最近日記かいてなかったなぁ, まぁネタがぜんぜんなかったからだけど
注: 特にネタ記事ではないです
某方面より, MPIの知られざる機能についてBlogに書けという圧力(大嘘)が来たので, MPI2にあるGeneralized Requestgrequestについて書いてみようかと, 執筆時点で仕様書の邦訳以外引っかからないし
とりあえず, APIの正確な解説が必要な人や, なにしろ関数プロトタイプすらここには書いてないしね本当に使ってみたい人はMPI Forumにある仕様書の該当部分を読むことをお勧めします, 以下はなんとなく解った気になるかもしれない程度のいい加減な解説です, ここがわかりづらいとかそういうのがあったらご指摘ください
- なにこれ?
あえて日本語訳すれば『一般化リクエスト』, 自前で実装したノンブロッキング処理をMPIのセマンティクス上で使うためのインターフェースです
普通のMPI_Requestは, 当然IsendやIrecvといったノンブロッキング通信処理に紐付いており, MPI_WaitAny()などでどれかが終わるまで待つみたいな使い方をするわけですが, この枠組みをもっと別のことにも使えるようにしたもの, 別のことって何? 自分で実装してね という枠組み
たとえば, 別スレッドで他所のサーバにデータを拾いに行ってもらうといった処理の終了報告をgrequestにやらせることで, MPIの通信と別スレッドの処理を同時に待てるようになるわけです
ほら, select()とかpoll()でサーバを書いてるときに, イベント報告用にpipe()使ってまでファイルディスクリプタに落とし込みたくなることあるでしょ? ない?
- どうやって使うの?
リクエストの終了ステータス(MPI_Status)を返すコールバック関数query_fnなどを実装して, MPI_Grequest_start()を呼ぶと, MPI_Requestができるので, それを使って待ったりする
Requestに対応する処理(これはユーザが実装する)が終わったら, MPI_Grequest_complete()を呼ぶ, そうするとそのリクエストに対応するMPI_{Wait,Test}{any,all,some}が呼ばれたときに, start時に設定したquery_fnが呼ばれて, そのリクエストの終了ステータスが返ってくる, これだけ
query_fnなどのコールバックがリクエストを追跡するために, grequestにはvoid *のデータを1つ紐付けておくことができ, コールバック関数に渡されるので, これで個々のリクエストを区別できる
- で, それって嬉しいの?
そんなの使う人しだいとしか言いようがないんだよなぁ
ちなみに石川研のYampiの実装には内部的に使われてたりします, とりあえずMPI_SuccessでGrequest_startの直後でGrequest_completeを呼んでおくとっとと終わりたいときとか