web-dev-qa-db-ja.com

MPI通信にMPI_Bcastを使用する

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;
}
67
David

これは、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集合通信、everyoneは参加する必要があります;誰もがBcast、Allreduce、または何を持っているかを呼び出す必要があります。 Bcastルーチンには、「ルート」または送信者を指定するパラメーターがあります。送信者のみがbcastを呼び出した場合、これは必要ありません。受信者を含む誰もがブロードキャストを呼び出します。受信者は単に受信を投稿します。

その理由は、集合操作がコミュニケーションに全員を関与させることができるため、方法ではなく、発生したいこと(誰もが1つのプロセスのデータを取得すること)を述べることです (たとえば、ルートプロセッサは他のすべてのランクでループして送信します)。そのため、通信パターン(たとえば、PのPステップではなくlog(P)ステップを実行するツリーベースの階層通信)を最適化します。プロセス)。

126
Jonathan Dursi

MPI_Bcastは集合的な操作であり、完了するためにすべてのプロセスによって呼び出される必要があります。

また、MPI_Recvを使用するときにMPI_Bcastを呼び出す必要はありません。あなたに役立つかもしれない投稿があります ここをクリック

1
GoingMyWay