2

MPI と Pthreads を使用して次のことを実装したいのですが、いくつかのエラーに直面しています。

各プロセッサには 2 つのスレッドがあります。各プロセッサの 1 つのスレッドは他のプロセッサにデータを送信し、他のスレッドは他のプロセッサからデータを受信します。私がそれを実装しているとき、「現在のバイト -40、合計バイト 0、リモート ID 5」のようないくつかのメッセージでセグメンテーション違反エラーが発生しています。

テスト目的で、プロセッサごとに 1 つのスレッドのみを使用し、データを送信または受信している場合、エラーは発生しません。

「一般に、複数のスレッドが MPI 呼び出しを行うと問題が発生する可能性があります。プログラムが失敗するか、予期しない動作をする可能性があります。スレッド内から MPI 呼び出しを行う必要がある場合は、1 つのスレッドでのみ行う必要があります。」という情報を見つけました。次のリンク: https://computing.llnl.gov/tutorials/pthreads/

プロセッサごとに 2 つのスレッドを使用し、1 つのスレッドが MPI_Send 関数を使用してデータを送信し、もう 1 つのスレッドが MPI_Recv 関数を受信して​​、ロック メカニズムを使用せずにデータを受信します。これを実装する方法、または複数のスレッドを使用してミューテックスやロックメカニズムを使用せずに MPI 関数を呼び出す方法を知っている人はいますか?

コードは次のとおりです。

int rank, size, msg_num;

// thread function for sending messages
void *Send_Func_For_Thread(void *arg)
{
    int send, procnum, x;
    send = rank;

    for(x=0; x < msg_num; x++)
    {
        procnum = rand()%size;
        if(procnum != rank)
            MPI_Send(&send, 1, MPI_INT, procnum, 0, MPI_COMM_WORLD);
    }

// sending special message to other processors with tag = 128 to signal the finishing of sending message

    for (x = 0; x < size; x++)
    {
        if(x != rank)
            MPI_Send(&send, 1, MPI_INT, x, 128, MPI_COMM_WORLD);    
    }

    pthread_exit((void *)NULL);
}


// thread function for receiving messages

void *Recv_Func_For_Thread(void *arg)
{
    MPI_Status status;
    int recv, counter = 0;

    while(counter != size - 1)
    {
        MPI_Recv(&recv, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        if(status.MPI_TAG == 128)
            counter++;
    }

    pthread_exit((void *)NULL);
}


int main(int argc, char **argv)
{
    void *stat;
    pthread_attr_t attr;
    pthread_t thread[2];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);   // rank -> rank of this processor
    MPI_Comm_size(MPI_COMM_WORLD, &size);   // size -> total number of processors

    srand((unsigned)time(NULL));

    msg_num = atoi(argv[1]);

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    // thread 0 will be sending   messages
    pthread_create(&thread[0], &attr, Send_Func_For_Thread, (void *)0);

    // thread 1 will be receiving messages
    pthread_create(&thread[1], &attr, Recv_Func_For_Thread, (void *)1);

    pthread_attr_destroy(&attr);

    pthread_join(thread[0], &stat);
    pthread_join(thread[1], &stat);

    cout << "Finished : Proc " << rank << "\n";

    MPI_Finalize();
    pthread_exit((void *)NULL);
    return 0;   
}

Compile:
========

module load mvapich2/gcc;        mpicxx -lpthread -o demo demo.cpp

Run:
====
mpiexec -comm mpich2-pmi demo 10000000

I ran this program with 3 processors and got segmentation fault.
4

2 に答える 2

2

(例を挙げていないので、以下は単なる憶測です。)

MPI_Init() の代わりに MPI_Init_thread() を使用して MPI を初期化する必要があります。あなたの説明が正しく理解できれば、「必須」引数の値は MPI_THREAD_MULTIPLE でなければなりません。MPI_Init_thread() が「提供された」引数で下位レベルのスレッド サポートを返す場合、MPI 実装が MPI_THREAD_MULTIPLE をサポートしていないことを意味します。その場合、何か他のことをしなければなりません。http://www.mpi-forum.org/docs/mpi-20-html/node165.htmを参照してください。

于 2013-05-21T07:26:32.000 に答える