MPI_Isend と MPI_Irecv による相互通信 ===================================== .. literalinclude:: mpi_sample9.cpp :language: c++ :linenos: :download:`Download the source code` 複数のプロセスの間で相互にデータを送り合いたい場合がありますが、 そのような場合に同期型の MPI_Send, MPI_Recv を使うと問題となる 場合があります。MPI_Send は、相手プロセスが MPI_Recv を発行する まで終わりません。ブロックする、という言い方をします。 互いにデータを送りたいプロセスがみなこぞって、まず先に、 自分が送り出したいデータを MPI_Send で送ろうとすると、 誰も MPI_Recv を呼び出さないので MPI_Send が先に進まず、 全てのプロセスがブロックしてしまいます。 そのような場合には、ノンブロッキングの MPI_Isend, MPI_Irecv を使うと 問題を回避できます。MPI_Isend は、通信相手が MPI_Irecv を発行していな くてもとりあえず関数としては終わって帰ってきます。つまり、ブロックしません。 帰ってきた後で、MPI_Irecvを発行することができます。 一通りのMPI_IsendとMPI_Irecvを発行し終えた後でMPI_Waitallを呼ぶと、 そこで全てのMPI_IsendとMPI_Irecvが完了するまで待ちます。ここはブロックします。 一回一回のMPI_Isend, MPI_Irecv の呼び出しの度に、宅配便の控え伝票の ようなデータである MPI_Request という型の値が渡されますので、この値を 必ず保持しておいて、MPI_Waitallに渡すようにします。 このサンプルでは2つのプロセスの間で相互にデータを送り合います。 3つ以上のプロセスに一般化した例は次のサンプルにあります。 openmpi上での実行例を示します。:: $ mpic++ -o mpi_sample9 mpi_sample9.cpp $ mpiexec -n 2 mpi_sample9 rank: 0, send_data: [ 0 1 2 3 4 5 6 7 8 9 ] rank: 1, send_data: [ 10 11 12 13 14 15 16 17 18 19 ] rank: 1, recv_data: [ 0 1 2 3 4 5 6 7 8 9 ] rank: 0, recv_data: [ 10 11 12 13 14 15 16 17 18 19 ]