インターフェース
#include <mpi.h>
int MPI_Recv(void* pbuf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Status* pstatus)
指定したランク番号を持つプロセスから、データ識別用の数値としてtagを持つデータを受け取ります。
受信プロセスは、データの受信が完了するまで待機します(データを受信しないとハングアップします)。
引数として与えるcountは、datatype型を持つデータの要素数です(バイト数ではありません)。
成功した場合の戻り値はMPI_SUCCESSです。失敗した場合はそれ以外のエラー値が返されます。
引数 | 内容 |
pbuf | 受信バッファの先頭へのポインタです。 |
count | データの要素数です。 |
datatype | データの型です。MPI_INTやMPI_DOUBLEなど定義済みの型、またはユーザ定義型が指定できます。 |
source | 送信元プロセスのランク番号です。MPI_ANY_SOURCEを指定すると任意のランク番号を持つプロセスからデータを受信します。 |
tag | 送信プロセスで指定したデータ識別用のIDです。このIDを持つデータだけが受信の対象になります。 |
comm | 送受信を行うプロセスの所属プロセスグループを指定します。MPI_COMM_WORLDを指定するとすべてのプロセスが所属するプロセスグループになります。 |
pstatus | 受信データの追加情報です。送信元プロセスのランク番号などが格納されています。 |
サンプルプログラム
ランク番号0を持つプロセスにそれ以外のプロセスが(ランク番号+15)を送信し、
ランク番号0を持つプロセスはそれらを受け取って表示するサンプルソースコードを示します。
#include <mpi.h>
#include <stdint.h>
#include <iostream>
#include <vector>
#define RANK_MASTER 0
#define ABORT_INIT 1
#define ABORT_ICHIGO 15
#define TAG_ICHIGO 15
void process_master(int num_processes)
{
int32_t ichigodata;
std::vector<int32_t> ichigobuf;
int ichigocount;
int source_rank;
MPI_Status status;
int ret;
bool ichigoerror = false;
ichigobuf.resize(num_processes);
ichigobuf[RANK_MASTER] = 10;
for ( ichigocount = 0; ichigocount < num_processes-1;
ichigocount++ ) {
ret = MPI_Recv(
&ichigodata, 1, MPI_INT32_T,
MPI_ANY_SOURCE, TAG_ICHIGO, MPI_COMM_WORLD, &status);
if (ret == MPI_SUCCESS) {
source_rank = status.MPI_SOURCE;
ichigobuf[source_rank] = ichigodata;
std::cout << "ichigosample: rank "
<< source_rank << " recv "
<< ichigodata << std::endl;
} else {
// error
ichigoerror = true;
break;
}
}
if ( !ichigoerror ) {
for ( ichigocount = 0; ichigocount < num_processes;
ichigocount++ ) {
std::cout << "ichigosample: data "
<< ichigobuf[ichigocount] << std::endl;
}
} else {
std::cout << "ichigosample: error" << std::endl;
MPI_Abort(MPI_COMM_WORLD, ABORT_ICHIGO);
}
}
void process_others(int num_processes, int process_rank)
{
int32_t ichigodata = process_rank + 15;
int ret;
ret = MPI_Send(&ichigodata, 1, MPI_INT32_T,
RANK_MASTER, TAG_ICHIGO, MPI_COMM_WORLD);
if (ret != MPI_SUCCESS) {
MPI_Abort(MPI_COMM_WORLD, ABORT_ICHIGO);
}
}
int main( int argc, char** argv )
{
int num_processes = 1;
int process_rank = 0;
int ret;
ret = MPI_Init(&argc, &argv);
if (ret == MPI_SUCCESS)
ret = MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
if (ret == MPI_SUCCESS)
ret = MPI_Comm_rank(MPI_COMM_WORLD, &process_rank);
if (ret != MPI_SUCCESS) {
// error
MPI_Abort(MPI_COMM_WORLD, ABORT_INIT);
}
if (process_rank == RANK_MASTER) {
process_master(num_processes);
} else {
process_others(num_processes, process_rank);
}
MPI_Finalize();
return 0;
}
4つのプロセスで動作させたときの出力結果の1例は次の通りです。
ichigosample: rank 3 recv 18
ichigosample: rank 1 recv 16
ichigosample: rank 2 recv 17
ichigosample: data 10
ichigosample: data 16
ichigosample: data 17
ichigosample: data 18
関連ページ
MPIの解説 目次
MPI_Datatype定数