# MPI data broadcast or not in C

I have two slightly different but getting the same results MPI code.

The first one is from an open-source package having several data exchange steps in between:

int main ( int argc, char **argv )
{
int i,j,nx=600,nz=300,NP, MYID;
int idum[2];
float v[420][720];

for (i=0;i<420;i++){
for (j=0;j<720;j++){
if(i<161) { v[i][j] = 2800.0; }
else { v[i][j] = 5200.0; }
}
}

MPI_Init ( &argc, &argv );
MPI_Comm_size ( MPI_COMM_WORLD, &NP );
MPI_Comm_rank ( MPI_COMM_WORLD, &MYID );

if(MYID==0){
idum[0] = nx;
idum[1] = nz;
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(&idum,5,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&v,420*720,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);

nx = idum[0];
nz = idum[1];

for (i=0;i<5;i++){
printf("id=%d,v[%d][350]=%f,\n",MYID,i*100+19,v[i*100+19][350]);
}
printf("nx=%d,nz=%d\n",nx,nz);
MPI_Finalize();
exit(0);
}


I run the code using mpirun with 4 cores. The results are:

id=0,v[19][350]=2800.000000,
id=0,v[119][350]=2800.000000,
id=0,v[219][350]=5200.000000,
id=0,v[319][350]=5200.000000,
id=0,v[419][350]=5200.000000,
nx=600,nz=300
id=0,v[19][350]=2800.000000,
id=0,v[119][350]=2800.000000,
id=0,v[219][350]=5200.000000,
id=0,v[319][350]=5200.000000,
id=0,v[419][350]=5200.000000,
nx=600,nz=300
id=0,v[19][350]=2800.000000,
id=0,v[119][350]=2800.000000,
id=0,v[219][350]=5200.000000,
id=0,v[319][350]=5200.000000,
id=0,v[419][350]=5200.000000,
nx=600,nz=300
id=0,v[19][350]=2800.000000,
id=0,v[119][350]=2800.000000,
id=0,v[219][350]=5200.000000,
id=0,v[319][350]=5200.000000,
id=0,v[419][350]=5200.000000,
nx=600,nz=300


But I think the data exchange part is a little "redundant?", so I simplify the above code as:

int main ( int argc, char **argv )
{
int i,j,nx=600, nz=300, NP=0, MYID;
float v[420][720];

for (i=0;i<420;i++){
for (j=0;j<720;j++){
if(i<161) { v[i][j] = 2800.0; }
else { v[i][j] = 5200.0; }
}
}

MPI_Init ( &argc, &argv );
MPI_Comm_size ( MPI_COMM_WORLD, &NP );
MPI_Comm_rank ( MPI_COMM_WORLD, &MYID );

for (i=0;i<5;i++){
printf("id=%d,v[%d][350]=%f,\n",MYID,i*100+19,v[i*100+19][350]);
}

printf("nx=%d,nz=%d\n",nx,nz);
MPI_Finalize();
exit(0);
}


I get the same results as the first code.

Which one of the two codes is correct? If both are correct, which one is better? Why do we need to have the data exchange lines in the first code, or don't have to?

A couple of things:

• It is certainly a bit strange to start the computations before MPI_INIT. Now, the fill of the array v is performed before the MPI execution environment is initialized. At least according to MPICH, one should do as little as possible before MPI_INIT and after MPI_FINILIZE, because the MPI standard does not specify what is actually allowed.
• I would assume, that the code was supposed to:
1. Initialize MPI
2. Fill the array v on the master node (ID=0)
3. Broadcast the info about the idum and v from ID=0 to other nodes in the communicator (MPI_COMM_WORLD).
4. Print out some elements of the array on all the nodes.

Now a lot of the things go wrong here (if at least some of the assumptions I make are correct)

• I doubt that this code is actually launched (properly) using MPI because according to your output, every processor outputs his ID=0.
• If the arrays v and idum is supposed to be filled on ALL processors (not only the master one), of course, those broadcasts are useless. But then the MPI parallelization is useless.
• Your "fixed version" of the code is not practically using MPI at all.

My suggestions:

1. Fix the initialization of the MPI and move it as close to the top of the main function as possible
2. Determine, where do you want to fill array v: on all the nodes or only on the master
3. Based on that, decide on the broadcasts if necessary.
4. Make sure you are running it using proper MPI command and your ids in the output are actually not all zeroes.