前の記事についての補足&訂正です。
OpenMPI、probeでサイズわかんなかったっけ?ヘッダいらんと思うけど。OpenMPIはけっこうよくできてると思うけどなー。
— Eikyu Ito (@aq3948) November 12, 2015
MPIの仕様を確認しますと…。
http://www.mpi-forum.org/docs/
http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf 【PDFにつき閲覧注意】
Iprobe(probeの非同期版で内容的にはprobeと同じ)の説明には、次のようにあります。
If MPI_IPROBE returns flag = true, then the content of the status object can be subsequently
accessed as described in Section 3.2.5 to find the source, tag and length of the
probed message.
「MPI_IPROBEがflag = trueを返したなら、status objectの中身は、Section 3.2.5に記載されている、source(送信元rank)、tagとprobeされたメッセージの長さに、後でアクセスできる」とあります。
3.2.5 Return Status
In C, status is a structure that contains three fields named MPI_SOURCE, MPI_TAG,
and MPI_ERROR; the structure may contain additional fields. Thus,
status.MPI_SOURCE, status.MPI_TAG and status.MPI_ERROR contain the source, tag, and error code, respectively, of the received message.
と書いてあって、MPI_SOURCE(送信元のrank)、MPI_TAG(メッセージタグ)、MPI_ERRORは必須。追加フィールドに関しては規定なしのようです。何故にここにlengthに関する規定を含めておかないのか、本当、糞仕様だと私は思います。これを見て、私はlengthは取得できないのかと思いました。
では、さきほどのcan be subsequently accessedとは何だったのかということになりますが、よくよく調べてみると、MPI_Status構造体には内部ハンドルも含んでいるので、Iprobeで返ってきたstatus objectを用いてMPI_GET_COUNTを呼び出すと受信したエントリー数(MPI_SendでMPI_DatatypeとしてMPI_BYTEを指定していればバイト数)が返ってくるようなのでこれをもってメッセージのデータサイズは確定できるようです。
返ってくるのはint(符号つき32bit)なのでMPI_BYTEで送っている場合、2GBまでしか扱えないようで結局、大きなメッセージを送るならこの仕組みは使えない(or 小さなメッセージの送受信時だけ使える)ということになりそうですが、それはそれとして、「probe/Iprobe(のあとでMPI_GET_COUNT)でサイズは取得できる」は正しいようです。
伊藤さん、ご指摘、ありがとうございました。
以上、補足&訂正記事でした。
MPI仕様作ったときは2GB超送るなんて完全に想定外だったんだろうなぁ… まあラッパー作るのは簡単だろうし、そう致命的ではないのでは(あれ、エラー時の処理とかけっこうめんどいか?)
— Eikyu Ito (@aq3948) November 13, 2015