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.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.