Использование MPI_Bcast для обмена сообщениями MPI

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

Ответ 1

Это общий источник путаницы для людей, не знакомых с 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 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).

Ответ 2

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

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