I am trying to test the effects of MPI_Send
without MPI_Recv
. I have the following program which I compile and run using openmpi-1.4.5 and mvapich2-1.9. I am aware that these implementations are for 2 different versions of the MPI standard, but I think MPI_Send
and MPI_Recv
are same across these standards:
#include <mpi.h>
#include <iostream>
#include <assert.h>
using namespace std;
MPI_Comm ping_world;
int mpi_size, mpi_rank;
void* ping(void* args)
{
int ctr = 0;
while(1)
{
char buff[6] = "PING";
++ctr;
for(int i=0; i<mpi_size; ++i)
{
cout << "[" << ctr << "] Rank " << mpi_rank << " sending " << buff << " to rank " << i << endl;
MPI_Send(buff, 6, MPI_CHAR, i, 0, ping_world);
}
}
}
int main(int argc, char *argv[])
{
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
assert(provided == MPI_THREAD_MULTIPLE);
MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);
{
MPI_Group orig_group;
MPI_Comm_group(MPI_COMM_WORLD, &orig_group);
int ranks[mpi_size];
for(int i=0; i<mpi_size; ++i)
ranks[i] = i;
MPI_Group new_group;
MPI_Group_incl(orig_group, mpi_size, ranks, &new_group);
MPI_Comm_create(MPI_COMM_WORLD, new_group, &ping_world);
}
pthread_t th_ping;
pthread_create(&th_ping, NULL, ping, (void *) NULL);
pthread_join(th_ping, NULL);
return 0;
}
With mvapich2, I always get the following output (nothing more than this). Basically, the program seems to have hanged after the 3 lines:
[1] Rank 0 sending PING to rank 0
[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1
With openmpi, I get the following output (unending):
[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1
[1] Rank 0 sending PING to rank 0
[1] Rank 0 sending PING to rank 1
[2] Rank 0 sending PING to rank 0
[2] Rank 0 sending PING to rank 1
[3] Rank 0 sending PING to rank 0
[3] Rank 0 sending PING to rank 1
[4] Rank 0 sending PING to rank 0
[4] Rank 0 sending PING to rank 1
[5] Rank 0 sending PING to rank 0
[2] Rank 1 sending PING to rank 0
[2] Rank 1 sending PING to rank 1
[3] Rank 1 sending PING to rank 0
[3] Rank 1 sending PING to rank 1
[4] Rank 1 sending PING to rank 0
[4] Rank 1 sending PING to rank 1
[5] Rank 1 sending PING to rank 0
[5] Rank 1 sending PING to rank 1
[6] Rank 1 sending PING to rank 0
Questions:
- Why is there such a difference?
- How do I achieve the behavior similar to openmpi (unending) using mvapich2?
MPI_Send can return when the buffer can be safely reused by the calling program. Nothing else is guaranteed, but there are many different implementation dependent behaviors. Different implementations can handle the buffering of messages differently. Eager protocols also allow for the transport of some short(er) messages to the receive rank without the need for a matching MPI_Recv to be posted.
If you need MPI to enforce the message being received before the blocking send returns, look at MPI_Ssend.