Использование MPI_Bcast для связи MPI - PullRequest
67 голосов
/ 23 октября 2011

Я пытаюсь передать сообщение от корневого узла всем остальным узлам, используя 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;
}

Ответы [ 2 ]

125 голосов
/ 23 октября 2011

Это распространенный источник путаницы для людей, плохо знакомых с 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 есть параметр, который задает «root» или того, кто выполняет отправку; если бы только отправитель назывался bcast, это вам не понадобилось бы.) Все вызывают трансляцию, включая получателей; Получатели не просто отправляют получение.

Причина этого заключается в том, что коллективные операции могут вовлекать всех в общение, поэтому вы указываете, что вы хотите, чтобы произошло (каждый получает данные одного процесса), а не как это происходит (например, корневой процессор зацикливается на всех других рангах и отправляет), так что есть возможности для оптимизации шаблонов связи (например, иерархическая связь на основе дерева, которая выполняет log(P) шагов вместо P шагов для процессов P).

1 голос
/ 19 августа 2016

MPI_Bcast является коллективной операцией, и для ее завершения она должна вызываться всеми процессами.

И при использовании MPI_Bcast нет необходимости вызывать MPI_Recv.Есть сообщение, которое может быть полезно для вас, нажмите здесь

...