I have come across a scenario in which I need to allocate a static array of type MPI_Request for keeping track of asynchronous send and receive MPI operations. I have total of 8 Isend and Irecv operations - where 4 of which are Isend and the remaining is Irecv. However, I do not call these 8 functions all at once. Depending on the incoming data, these functions are called in pairs, which means I may call pair of 1 send/receive or 2 send/receive or 3 send/receive or all at once. The fact that they are going to be called in pairs is certain but how many of them will be called is not certain. Below is a pseudo-code:
MPI_Request reqs[8];
MPI_Status stats[8];
if (Rank A exists){
//The process have to send data to A and receive data from A
MPI_Isend(A, ..., &reqs[0]);
MPI_Irecv(A, ..., &reqs[1]);
}
if(Rank B exists){
//The process have to send data to B and receive data from B
MPI_Isend(B, ..., &reqs[2]);
MPI_Irecv(B, ..., &reqs[3]);
}
if(Rank C exists){
//The process have to send data to C and receive data from C
MPI_Isend(C, ..., &reqs[4]);
MPI_Irecv(C, ..., &reqs[5]);
}
if(Rank D exists){
//The process have to send data to D and receive data from D
MPI_Isend(D, ..., &reqs[6]);
MPI_Irecv(D, ..., &reqs[7]);
}
//Wait for asynchronous operations to complete
MPI_Waitall(8, reqs, stats);
Now, I am not sure what the behavior of the program will be. There are total of 8 distinct asynchronous send and receive function calls and there is one slot for each function in MPI_reqs[8]
for each call but not all of the functions will always be used. When some of them are not called, some slots in MPI_reqs[8]
will be uninitialized. However, I need MPI_Waitall(8, reqs, stats)
to return regardless of whether all slots in MPI_reqs[8]
are initialized or not.
Could someone explain how the program might behave in this particular scenario?
You could set / initialize those missing requests with MPI_REQUEST_NULL
. That said, why not just
int count = 0;
...
Isend(A, &reqs[count++]);
...
MPI_Waitall(count, reqs, stats);
Of course, leaving the value uninitialized and feeding it to some function that reads from it is not a good idea.