1. ホーム
  2. c

[解決済み】MPI通信でMPI_Bcastを使用する場合

2022-02-09 12:37:35

質問

MPI_Bcastを使ってルートノードから他の全ノードへメッセージをブロードキャストしようとしています。しかし、このプログラムを実行するといつも最初のほうでハングしてしまいます。何が問題なのか、誰か知っていますか?

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
        int rank;
        int buf;
        MPI_Status status;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        if(rank == 0) {
                buf = 777;
                MPI_Bcast(&buf, 1, MPI_INT, 0, MPI_COMM_WORLD);
        }
        else {
                MPI_Recv(&buf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
                printf("rank %d receiving received %d\n", rank, buf);
        }

        MPI_Finalize();
        return 0;
}

解決するには?

これは、MPIを初めて使う人がよく混乱する原因です。 を使うわけではありません。 MPI_Recv() を使用して、ブロードキャストで送信されたデータを受信します。 MPI_Bcast().

例えば、あなたが欲しいのはこれです。

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
        int rank;
        int buf;
        const int root=0;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        if(rank == root) {
           buf = 777;
        }

        printf("[%d]: Before Bcast, buf is %d\n", rank, buf);

        /* everyone calls bcast, data is taken from root and ends up in everyone's buf */
        MPI_Bcast(&buf, 1, MPI_INT, root, MPI_COMM_WORLD);

        printf("[%d]: After Bcast, buf is %d\n", rank, buf);

        MPI_Finalize();
        return 0;
}

MPI集団通信の場合。 全員 BcastやAllreduceなどを呼び出す必要があります。 (Bcastルーチンに「ルート」つまり送信者を指定するパラメータがあるのはこのためです。送信者だけがbcastを呼べば、このパラメータは必要ありません)。 受信者も含めて全員がブロードキャストを呼び出します。受信者はただ受信を投稿するだけではありません。

この理由は、集団的操作は通信に参加する全員を巻き込むことができるので、起こりたいこと(全員が1つのプロセスのデータを取得する)を、むしろ どのように そのため、通信パターンを最適化する余地があります(例えば、ツリーベースの階層型通信で {コード ステップではなく {コード {コード Pプロセスのステップ)。