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.