J'essaie de diffuser un message du nœud racine à tous les autres nœuds à l'aide de MPI_Bcast. Cependant, chaque fois que j'exécute ce programme, il se bloque toujours au début. Quelqu'un sait-il ce qui ne va pas?
#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;
}
Il s'agit d'une source de confusion courante pour les nouveaux utilisateurs de MPI. Vous n'utilisez pas MPI_Recv()
pour recevoir les données envoyées par une diffusion; vous utilisez MPI_Bcast()
.
Par exemple, ce que vous voulez, c'est ceci:
#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;
}
Pour MPI communications collectives, tout le monde doit participer; tout le monde doit appeler le Bcast, ou l'Allreduce, ou quoi (C'est pourquoi la routine Bcast a un paramètre qui spécifie la "racine", ou qui fait l'envoi; si seulement l'expéditeur appelé bcast, vous n'en auriez pas besoin.) Tout le monde appelle la diffusion, y compris les récepteurs; les receveurs ne se contentent pas de poster une réception.
La raison en est que les opérations collectives peuvent impliquer tout le monde dans la communication, de sorte que vous déclariez ce que vous voulez faire (tout le monde obtient les données d'un processus) plutôt que comment cela se produit (par exemple, le processeur racine boucle sur tous les autres rangs et effectue un envoi), de sorte qu'il est possible d'optimiser les modèles de communication (par exemple, une communication hiérarchique basée sur un arbre qui prend log(P)
étapes plutôt que P
étapes pour les processus P).
MPI_Bcast
est une opération collective et doit être appelée par tous les processus pour se terminer.
Et il n'est pas nécessaire d'appeler MPI_Recv
lors de l'utilisation de MPI_Bcast
. Il y a un article qui peut vous être utile, cliquez ici