Throughout the MPI standard the term locations is used and not the term variables in order to prevent such confusion. The MPI library does not care where the memory comes from as long outstanding MPI operations are operating on disjoint sets of memory locations. Different memory locations could be different variables or different elements of a big array. In fact, the whole process memory could be thought as one big anonymous array of bytes.
In many cases, it is possible to achieve the same memory layout given different set of variable declarations. For example, with most x86/x64 C/C++ compilers the following two sets of local variable declarations will result in the same stack layout:
int a, b; int d[3];
int c;
| .... | | .... | |
+--------------+ +--------------+ |
| a | | d[2] | |
+--------------+ +--------------+ | lower addresses
| b | | d[1] | |
+--------------+ +--------------+ |
| c | | d[0] | \|/
+--------------+ +--------------+ V
In that case:
int a, b;
int c;
MPI_Irecv(&a, 1, MPI_INT, ..., &req[0]);
MPI_Irecv(&c, 1, MPI_INT, ..., &req[1]);
MPI_Waitall(2, &req, MPI_STATUSES_IGNORE);
is equivalent to:
int d[3];
MPI_Irecv(&d[2], 1, MPI_INT, ..., &req[0]);
MPI_Irecv(&d[0], 1, MPI_INT, ..., &req[1]);
MPI_Waitall(2, &req, MPI_STATUSES_IGNORE);
In the second case, though d[0] and d[2] belong to the same variable, &d[0] and &d[2] specify different and - in combination with ..., 1, MPI_INT, ... - disjoint memory locations.
In any case, make sure that you are not simultaneously reading from and writing into the same memory location.
A somehow more complex version of the example given by Wesley Bland follows. It overlaps send and receive operations by using MPI_Waitsome instead:
MPI_Request rreqs[size], sreqs[size];
for (i = 0; i < size; i++)
MPI_Irecv(&data[i*100], 100, MPI_INT, i, 0, comm, &rreqs[i]);
while (1)
{
int done_idx[size], numdone;
MPI_Waitsome(size, rreqs, &numdone, done_idx, MPI_STATUSES_IGNORE);
if (numdone == MPI_UNDEFINED)
break;
for (i = 0; i < numdone; i++)
{
int id = done_idx[i];
process(&data[id*100], 100);
MPI_Isend(&data[id*100], 100, MPI_INT, id, 0, comm, &sreqs[id]);
}
}
MPI_Waitall(size, sreqs, MPI_STATUSES_IGNORE);
In that particular case, using size separate arrays could result in somehow more readable code.
senddata[]andrecvdata[]do not overlap, the code is perfectly fine. - Hristo Iliev