0

使っていると思いますMPI_Sendrecv

MPI_Sendrecv(&ballPos, 2, MPI_INT, FIELD, NEW_BALL_POS_TAG, &ballPos, 2, MPI_INT, winner, NEW_BALL_POS_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

しかし、私はルートだけに気づきました(受信側は実行を続けますか?)。Sendrecvcoutの前後に次のものが生成されます。

0 b4 sendrecv
2 b4 sendrecv
4 b4 sendrecv
1 b4 sendrecv
3 b4 sendrecv
5 b4 sendrecv
0 after sendrecv

sendrecvの前はすべてのプロセスで問題ありませんが、その後はrootのみがブロックを解除します。

完全なソース:147行目を参照

アップデート

結果は次のようになります

if (rank == winner) {
    ballPos[0] = rand() % 128;
    ballPos[1] = rand() % 64;
    cout << "new ball pos: " << ballPos[0] << " " << ballPos[1] << endl;
    MPI_Send(&ballPos, 2, MPI_INT, FIELD, NEW_BALL_POS_TAG, MPI_COMM_WORLD);
} else if (rank == FIELD) {
    MPI_Recv(&ballPos, 2, MPI_INT, winner, NEW_BALL_POS_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
4

1 に答える 1

1

投稿された送信の数は、投稿された受信の数と同じである必要があります。あなたの場合、すべてのランクがランクに送信され、ランクFIELDから受信されます。これにはwinner、およびが含まFIELDwinnerます。

Rank       Sends to  Receives from
----------------------------------
0 (FIELD)  FIELD     winner
1          FIELD     winner
2          FIELD     winner
...        ...       ...
winner     FIELD     winner
...        ...       ...
numprocs-1 FIELD     winner

(そのようなテーブルは時々非常に役立つかもしれません)

したがって、メッセージFIELDを受信する必要がありnumprocsますが、実行はMPI_Sendrecv1回だけであるため、numprocs-1への呼び出しはMPI_Sendrecv送信を完了できません。同じことが。にも当てはまりwinnerます。メッセージを送信する必要がありnumprocsますが、実行はMPI_Sendrecv1回だけであるため、送信されるメッセージは1つだけであり、numprocs-1への呼び出しMPI_Sendrecvは受信を完了できません。

別のエラーもあります。MPI標準では、送信バッファーと受信バッファーが互いに素である(つまり、オーバーラップしてはならない)必要がありますが、これはコードには当てはまりません。送信バッファと受信バッファは重複しているだけでなく、同じバッファです。同じバッファでスワップを実行する場合は、MPIがMPI_Sendrecv_replace操作を提供します。

この声明で何を達成しようとしているのかはわかりませんがMPI_Sendrecv、声明の中に入れる必要があるのではないかと強く思いますif

于 2012-11-09T11:24:19.220 に答える