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

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

Решение

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

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

И звонить не нужно MPI_Recv когда используешь MPI_Bcast, Существует еще один пост может помочь вам, нажмите здесь

Другие вопросы по тегам