"MPI_Bcast"er at runtime
How do I do an MPI_Bcast in the case where the broadcaster is decided at runtime? How do I specify the root node in this case?
I'm trying to search for a distinct number in an array. If a node finds the number, then it should b开发者_JAVA百科roadcast its location to all other nodes. However, as I don't know the finder beforehand, what should the "root" value be in:
int MPI_Bcast ( void *buffer, int count, MPI_Datatype datatype,
int root, MPI_Comm comm );
Everyone has to agree on "root" before going into the collective, so there has to be some collaboration before hand. Here's one straightforward approach - everyone sends a flag indicating whether or not they have the relevant data, and then everyone can agree who to receive from. This allows you to handle the cases of when there's multiple possible senders or none.
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size, ierr;
int bcaster;
int bcasterflag, *allflags;
int consensus;
int globaldata, mydata;
ierr = MPI_Init(&argc, &argv);
ierr|= MPI_Comm_size(MPI_COMM_WORLD,&size);
ierr|= MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if (argc != 2) {
if (rank == 0) fprintf(stderr,"Usage: %s rank-to-broadcast\n",argv[0]);
MPI_Abort(MPI_COMM_WORLD,1);
}
bcaster = atoi(argv[1]);
if (bcaster < 0 ) bcaster = 0;
if (bcaster >= size) bcaster = size-1;
/* pretend the processes didn't all know the above and had to
* rely solely on local info to decide the broadcaster
*/
bcasterflag = 0; /* not the broadcaster yet */
mydata = rank*rank; /* the local data */
if (mydata == bcaster*bcaster) {
bcasterflag = 1;
globaldata = mydata;
}
/* collect these local decisions */
allflags = (int *)malloc(size * sizeof(int));
ierr = MPI_Allgather(&bcasterflag, 1, MPI_INT,
allflags, 1, MPI_INT, MPI_COMM_WORLD);
consensus = -1;
for (int i=0; i<size; i++)
if (allflags[i] != 0) consensus = i;
if (consensus == -1) {
if (rank == 0) {
fprintf(stderr,"Error: no one found to do the broadcast.\n");
}
} else {
ierr = MPI_Bcast(&globaldata, 1, MPI_INT, consensus, MPI_COMM_WORLD);
}
printf("%d: Received data %d from %d\n",
rank, globaldata, consensus);
return 0;
}
精彩评论