Point to Point Communication Routines: Non-blocking Message Passing Routines

The more commonly used MPI non-blocking message passing routines are described below.

MPI_Isend

Identifies an area in memory to serve as a send buffer. Processing continues immediately without waiting for the message to be copied out from the application buffer. A communication request handle is returned for handling the pending message status. The program should not modify the application buffer until subsequent calls to MPI_Wait or MPI_Test indicate that the non-blocking send has completed.

MPI_Isend (&buf,count,datatype,dest,tag,comm,&request) MPI_ISEND (buf,count,datatype,dest,tag,comm,request,ierr) 

MPI_Irecv

Identifies an area in memory to serve as a receive buffer. Processing continues immediately without actually waiting for the message to be received and copied into the the application buffer. A communication request handle is returned for handling the pending message status. The program must use calls to MPI_Wait or MPI_Test to determine when the non-blocking receive operation completes and the requested message is available in the application buffer.

MPI_Irecv (&buf,count,datatype,source,tag,comm,&request) MPI_IRECV (buf,count,datatype,source,tag,comm,request,ierr) 

MPI_Issend

Non-blocking synchronous send. Similar to MPI_Isend(), except MPI_Wait() or MPI_Test() indicates when the destination process has received the message.

MPI_Issend (&buf,count,datatype,dest,tag,comm,&request) MPI_ISSEND (buf,count,datatype,dest,tag,comm,request,ierr) 

MPI_Test

MPI_Testany

MPI_Testall

MPI_Testsome

MPI_Test checks the status of a specified non-blocking send or receive operation. The “flag” parameter is returned logical true (1) if the operation has completed, and logical false (0) if not. For multiple non-blocking operations, the programmer can specify any, all or some completions.

MPI_Test (&request,&flag,&status) MPI_Testany (count,&array_of_requests,&index,&flag,&status) MPI_Testall (count,&array_of_requests,&flag,&array_of_statuses) MPI_Testsome (incount,&array_of_requests,&outcount, . &array_of_offsets, &array_of_statuses) MPI_TEST (request,flag,status,ierr) MPI_TESTANY (count,array_of_requests,index,flag,status,ierr) MPI_TESTALL (count,array_of_requests,flag,array_of_statuses,ierr) MPI_TESTSOME (incount,array_of_requests,outcount, . array_of_offsets, array_of_statuses,ierr) 

MPI_Iprobe

Performs a non-blocking test for a message. The “wildcards” MPI_ANY_SOURCE and MPI_ANY_TAG may be used to test for a message from any source or with any tag. The integer “flag” parameter is returned logical true (1) if a message has arrived, and logical false (0) if not. For the C routine, the actual source and tag will be returned in the status structure as status.MPI_SOURCE and status.MPI_TAG. For the Fortran routine, they will be returned in the integer array status(MPI_SOURCE) and status(MPI_TAG).

MPI_Iprobe (source,tag,comm,&flag,&status) MPI_IPROBE (source,tag,comm,flag,status,ierr) 

Examples: Non-blocking Message Passing Routines

Nearest neighbor exchange in a ring topology

C Language - Non-blocking Message Passing Example

#include "mpi.h" #include main(int argc, char *argv[]) < int numtasks, rank, next, prev, buf[2], tag1=1, tag2=2; MPI_Request reqs[4]; // required variable for non-blocking calls MPI_Status stats[4]; // required variable for Waitall routine MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank); // determine left and right neighbors prev = rank-1; next = rank+1; if (rank == 0) prev = numtasks - 1; if (rank == (numtasks - 1)) next = 0; // post non-blocking receives and sends for neighbors MPI_Irecv(&buf[0], 1, MPI_INT, prev, tag1, MPI_COMM_WORLD, &reqs[0]); MPI_Irecv(&buf[1], 1, MPI_INT, next, tag2, MPI_COMM_WORLD, &reqs[1]); MPI_Isend(&rank, 1, MPI_INT, prev, tag2, MPI_COMM_WORLD, &reqs[2]); MPI_Isend(&rank, 1, MPI_INT, next, tag1, MPI_COMM_WORLD, &reqs[3]); // do some work while sends/receives progress in background // wait for all non-blocking operations to complete MPI_Waitall(4, reqs, stats); // continue - do more work MPI_Finalize(); >

Fortran - Non-blocking Message Passing Example

program ringtopo include 'mpif.h' integer numtasks, rank, next, prev, buf(2), tag1, tag2, ierr integer reqs(4) ! required variable for non-blocking calls integer stats(MPI_STATUS_SIZE,4) ! required variable for WAITALL routine tag1 = 1 tag2 = 2 call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr) ! determine left and right neighbors prev = rank - 1 next = rank + 1 if (rank .eq. 0) then prev = numtasks - 1 endif if (rank .eq. numtasks - 1) then next = 0 endif ! post non-blocking receives and sends for neighbors call MPI_IRECV(buf(1), 1, MPI_INTEGER, prev, tag1, MPI_COMM_WORLD, reqs(1), ierr) call MPI_IRECV(buf(2), 1, MPI_INTEGER, next, tag2, MPI_COMM_WORLD, reqs(2), ierr) call MPI_ISEND(rank, 1, MPI_INTEGER, prev, tag2, MPI_COMM_WORLD, reqs(3), ierr) call MPI_ISEND(rank, 1, MPI_INTEGER, next, tag1, MPI_COMM_WORLD, reqs(4), ierr) ! do some work while sends/receives progress in background ! wait for all non-blocking operations to complete call MPI_WAITALL(4, reqs, stats, ierr); ! continue - do more work call MPI_FINALIZE(ierr) end 
Lawrence Livermore National Laboratory | 7000 East Avenue • Livermore, CA 94550 | LLNL-WEB-458451

Operated by the Lawrence Livermore National Security, LLC for the Department of Energy's National Nuclear Security Administration Learn about the Department of Energy's Vulnerability Disclosure Program