I want to use MPI_Iprobe to test whether a message with a given tag is already pending.
However, the behaviour of MPI_Iprobe isn't quite as I was expecting. In the example below, I send messages from multiple tasks to a single task (rank 0). Then on rank 0, I wait several seconds to allow plenty of time for the MPI_Isends to complete. Then when I run MPI_Iprobe it returns with flag false. If I repeat after a (blocking) MPI_Probe, then it returns true.
#include "mpi.h"
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int rank;
int numprocs;
int tag;
int receive_tag;
int flag=0;
int number;
int recv_number=0;
MPI_Request request;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
// rank 0 receives messages, all others send messages
if (rank > 0 ) {
number = rank;
tag = rank;
MPI_Isend(&number, 1, MPI_INT, 0, tag, MPI_COMM_WORLD,&request); // send to rank 0
printf("Sending tag : %d \n",tag);
}
else if (rank == 0) {
sleep(5); // [seconds] allow plenty of time for all sends from other tasks to complete
receive_tag = 3; // just try and receive a single message from task 1
MPI_Iprobe(MPI_ANY_SOURCE,receive_tag,MPI_COMM_WORLD,&flag,&status);
printf("After MPI_Iprobe, flag = %d \n",flag);
MPI_Probe(MPI_ANY_SOURCE,receive_tag,MPI_COMM_WORLD,&status);
printf("After MPI_Probe, found message with tag : %d \n",receive_tag);
MPI_Iprobe(MPI_ANY_SOURCE,receive_tag,MPI_COMM_WORLD,&flag,&status);
printf("After second MPI_Iprobe, flag = %d \n",flag);
// receive all the messages
for (int i=1;i<numprocs;i++){
MPI_Recv(&recv_number, 1, MPI_INT, MPI_ANY_SOURCE, i, MPI_COMM_WORLD,&status);
printf("Received : %d \n",recv_number);
}
}
MPI_Finalize();
}
Gives this output:
Sending tag : 4
Sending tag : 3
Sending tag : 2
Sending tag : 5
Sending tag : 1
After MPI_Iprobe, flag = 0
After MPI_Probe, found message with tag : 3
After second MPI_Iprobe, flag = 1
Received : 1
Received : 2
Received : 3
Received : 4
Received : 5
Why does mpi_iprobe return 'false' the first time?
Any help would be much appreciated!
EDIT: after the answer by Hristo Iliev I now have the following code:
#include "mpi.h"
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int rank;
int numprocs;
int tag;
int receive_tag;
int flag=0;
int number;
int recv_number=0;
MPI_Request request;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
// rank 0 receives messages, all others send messages
if (rank > 0 ) {
number = rank;
tag = rank;
MPI_Isend(&number, 1, MPI_INT, 0, tag, MPI_COMM_WORLD,&request); // send to rank 0
printf("Sending tag : %d \n",tag);
// do stuff
MPI_Wait(&request,&status);
printf("Sent tag : %d \n",tag);
}
else if (rank == 0) {
sleep(5); // [seconds] allow plenty of time for all sends from other tasks to complete
receive_tag = 3; // just try and receive a single message from task 1
MPI_Iprobe(MPI_ANY_SOURCE,receive_tag,MPI_COMM_WORLD,&flag,&status);
printf("After MPI_Iprobe, flag = %d \n",flag);
MPI_Probe(MPI_ANY_SOURCE,receive_tag,MPI_COMM_WORLD,&status);
printf("After MPI_Probe, found message with tag : %d \n",receive_tag);
MPI_Iprobe(MPI_ANY_SOURCE,receive_tag,MPI_COMM_WORLD,&flag,&status);
printf("After second MPI_Iprobe, flag = %d \n",flag);
// receive all the other messages
for (int i=1;i<numprocs;i++){
MPI_Recv(&recv_number, 1, MPI_INT, MPI_ANY_SOURCE, i, MPI_COMM_WORLD,&status);
}
}
MPI_Finalize();
}
Which gives the following output:
Sending tag : 5
Sending tag : 2
Sending tag : 1
Sending tag : 4
Sending tag : 3
Sent tag : 2
Sent tag : 1
Sent tag : 5
Sent tag : 4
Sent tag : 3
After MPI_Iprobe, flag = 0
After MPI_Probe, found message with tag : 3
After second MPI_Iprobe, flag = 1