68 votos

Usando MPI_Bcast para la comunicación MPI

Estoy tratando de transmitir un mensaje del nodo root a todos los demás nodos usando MPI_Bcast. Sin embargo, cada vez que ejecuto este programa siempre se cuelga al principio. ¿Alguien sabe lo que está mal con él?

#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;
}

129voto

Jonathan Dursi Puntos 25143

Esta es una fuente común de confusión para las personas nuevas en el IPM. No se usa MPI_Recv() para recibir los datos enviados por una emisión; se utiliza MPI_Bcast() .

Eg, lo que quieres es esto:

#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;
}

Para las comunicaciones colectivas del MPI, todos tiene que participar; todo el mundo tiene que llamar al Bcast, o al Allreduce, o lo que sea. (Por eso la rutina Bcast tiene un parámetro que especifica la "root", o quién está haciendo el envío; si sólo el remitente llamara a Bcast, no necesitarías esto). Todo el mundo llama a la emisión, incluidos los receptores; los receptores no sólo envían una recepción.

La razón de esto es que las operaciones colectivas pueden involucrar a todo el mundo en la comunicación, de modo que se declara lo que se quiere que ocurra (todo el mundo obtiene los datos de uno de los procesos) en lugar de cómo sucede (por ejemplo, el procesador root hace un bucle sobre todos los demás rangos y hace un envío), de modo que hay margen para optimizar los patrones de comunicación (por ejemplo, una comunicación jerárquica basada en árboles que toma log(P) pasos en lugar de P pasos para los procesos P).

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X