MPI_Isend

いちごパック > MPIの解説 > MPI_Isend

インターフェース

#include <mpi.h>
int MPI_Isend(const void* pdata, int count, MPI_Datatype datatype,
              int dest, int tag, MPI_Comm comm, MPI_Request* prequest);
指定したランク番号を持つプロセスに、 データ識別用の数値としてtagを持つデータを非同期で受け取るようMPIにリクエストします。 prequestを識別データとしてMPI_Wait()やMPI_Waitall()で待機するまで、 pdataの内容を変更したり、データを破棄したりしてはいけません。 引数として与えるcountは、datatype型を持つデータの要素数です(バイト数ではありません)。
成功した場合の戻り値はMPI_SUCCESSです。失敗した場合はそれ以外のエラー値が返されます。
引数内容
pdataデータの先頭へのポインタです。
countデータの要素数です。
datatypeデータの型です。MPI_INTやMPI_DOUBLEなど定義済みの型、またはユーザ定義型が指定できます。
dest送り先プロセスのランク番号です。
tagデータを受け取りプロセスで識別するための数値です。
comm送受信を行うプロセスの所属プロセスグループを指定します。MPI_COMM_WORLDを指定するとすべてのプロセスが所属するプロセスグループになります。
prequestこの非同期通信の識別データです。

サンプルプログラム

ランク番号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)
{
    MPI_Request req;
    MPI_Status status;
    int32_t ichigodata = process_rank + 15;
    int ret;

    ret = MPI_Isend(&ichigodata, 1, MPI_INT32_T,
        RANK_MASTER, TAG_ICHIGO, MPI_COMM_WORLD, &req);
    if (ret != MPI_SUCCESS) {
        MPI_Abort(MPI_COMM_WORLD, ABORT_ICHIGO);
    }

    // ...

    ret = MPI_Wait(&req, &status);
    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 2 recv 17
ichigosample: rank 1 recv 16
ichigosample: data 10
ichigosample: data 16
ichigosample: data 17
ichigosample: data 18

関連ページ

  • MPIの解説 目次
  • MPI_Datatype定数