Open MPIユーザーリストで返信しましたが、他の誰かが役立つと思った場合に備えて、ここにも投稿します。Jeff Squyresは、Open MPIメーリングリストであなたの質問にすでに回答しているか、少なくとも考えられる問題について示唆していると思います。MPIメッセージは、送信された順序で受信されますが、特定の(タグ、コミュニケーター)タプル内でのみ受信されます。これは基本的に次のことを意味します。
- 同じコミュニケーター内で、メッセージが異なるタグを持っている場合、メッセージを順不同で受信する可能性があります。
- 同じタグを持つメッセージは、異なるコンテキスト(コミュニケーター)で通信された場合、順序が狂って受信される可能性があります。
ただし、ここに問題があります。送信操作がまだ投稿されていない場合、メッセージを受信することはできません。2つの連続した送信操作がある場合は、最初の操作が永久にブロックされないようにする必要があります。標準のMPI送信操作MPI_Send
はさまざまな方法で実装できますが(標準では正確な方法は示されていません)、ほとんどのMPI実装では、非常に小さいメッセージの場合はバッファー送信のように、大きいメッセージの場合は同期送信のように動作します。送信者プロセスで次の2つの呼び出しがある場合:
MPI_Send(largedata, largecount, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(smalldata, smallcount, MPI_INT, dest, tag2, MPI_COMM_WORLD);
最初のものMPI_Send
は実際には同期的なものとして動作する可能性があります。つまり、一致する受信操作が受信者側にポストされない限り、戻りません。受信者コードが次のとおりであるとします。
MPI_Probe(src, tag2, MPI_COMM_WORLD, &status);
MPI_Recv(largedata, largecount, MPI_INT, src, tag1, MPI_COMM_WORLD, &status);
これMPI_Probe
は、ブロッキング呼び出しであるため、デッドロックになる可能性があります。つまり、一致する送信が投稿されるまで返されません。つまり、2番目の送信MPI_Send
を実行する必要があります。これは、最初の送信が戻った後にのみ発生しますがMPI_Recv
、受信機が実行されます...私はあなたがアイデアを得ると思います
デッドロックを防ぐために、非ブロッキング送信を使用するように送信者のコードを変更できます。
MPI_Request req;
MPI_Isend(largedata, largecount, MPI_INT, dest, tag1, MPI_COMM_WORLD, &req);
MPI_Send(smalldata, smallcount, MPI_INT, dest, tag2, MPI_COMM_WORLD);
MPI_Wait(&req, MPI_STATUS_IGNORE);
非ブロッキング操作を使用すると、送信呼び出しはすぐに戻り、操作はバックグラウンドで続行されるため、2番目の送信はその直後に実行されます。これで、2つの保留中のメッセージがあり、それらは異なるタグを持っているため、任意の順序で受信できます。