4

n個のプロセスがあり、それぞれがintなどのローカルデータを所有しているとします。

ここで、 MPI_Allreduce()関数を再実装します。つまり、これらすべてのintのグローバル合計を計算し、結果の合計をプロセスにブロードキャストします。

私は以下のコードのようにそれをやろうとしました:

  int temp;
  int my_sum = temp = my_data;
  for (int i = 1; i < size; ++i) {
    int partner = (my_rank + 1) % size;
    MPI_Sendrecv_replace(&temp, 1, MPI_INT, 
                         partner, 0, 
                         my_rank, 0, 
                         MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    my_sum += temp;
  }

プロセスがリングファヒオンで通信するようにしますが、それはブロックしています。なんで?正しく動作するようにコードを変更するにはどうすればよいですか?

注:問題の代替(より良い)解決策を提案しないでください(明らかに、そのうちの1つはMPI_Allreduce()関数を使用することです)。私の目標は、このコードスニペットが期待どおりに機能しない理由を理解することです。

4

1 に答える 1

7

誰もが自分自身から受信しようとしていますが、送信していpartnerます。partner送信されているメッセージを受信することはなくmy_rank、ここでそれ自体からメッセージを受信することもないため、ハングが発生します。

にデータを送信しようとしている場合は、自分から受信しparterていることを確認する必要がありpartnerます。つまり、全員がから受信している必要があります(myrank - 1 + size) % size

int spartner = (my_rank + 1) % size;
int rpartner = (my_rank - 1 + size) % size;
MPI_Sendrecv_replace(&temp, 1, MPI_INT,
                     spartner, i,
                     rpartner, i,
                     MPI_COMM_WORLD, MPI_STATUS_IGNORE);

このように、ランク3(たとえば)は4に送信し、ランク4は各反復でランク3から受信するため、sendrecvは完了します。(私はまた、ループを介して各反復に独自のタグを与える自由を取りました。これはここでは実際には必要ありませんが、他の不一致メッセージタイプエラーがある場合にバグを見つけるのに役立つことがよくあります。)

于 2012-08-29T00:06:09.523 に答える