The functions MPI_WAIT and MPI_TEST are used to complete a nonblocking communication. The completion of a send operation indicates that the sender is now free to update the locations in the send buffer (the send operation itself leaves the content of the send buffer unchanged). It does not indicate that the message has been received, rather, it may have been buffered by the communication subsystem. However, if a synchronous mode send was used, the completion of the send operation indicates that a matching receive was initiated, and that the message will eventually be received by this matching receive.
The completion of a receive operation indicates that the receive buffer contains the received message, the receiver is now free to access it, and that the status object is set. It does not indicate that the matching send operation has completed (but indicates, of course, that the send was initiated).
We shall use the following terminology:
A null handle is a handle with
value
MPI_REQUEST_NULL.
A persistent
request and the handle to it are inactive
if the request is not associated with any ongoing
communication (see Section 3.9).
A handle is active if it is neither null nor inactive.
A empty status is a status which is set to
return tag = MPI_ANY_TAG,
source = MPI_ANY_SOURCE, and is also internally configured
so that calls to
MPI_GET_COUNT and MPI_GET_ELEMENTS return count = 0. (Enhancement/Correction in the MPI-1.2 Standard:
)
We set a status variable to empty when the value returned by it is not
significant. Status is set in this
way so as to prevent errors due to accesses of stale information.
int MPI_Wait(MPI_Request *request, MPI_Status *status)
MPI_WAIT(REQUEST, STATUS, IERROR)
INTEGER REQUEST, STATUS(MPI_STATUS_SIZE), IERROR
A call to MPI_WAIT returns when the operation identified by request is complete. If the communication object associated with this request was created by a nonblocking send or receive call, then the object is deallocated by the call to MPI_WAIT and the request handle is set to MPI_REQUEST_NULL. MPI_WAIT is a non-local operation.
The call returns, in status, information on the completed operation. The content of the status object for a receive operation can be accessed as described in section 3.2.5. The status object for a send operation may be queried by a call to MPI_TEST_CANCELLED (see Section 3.8).
One is allowed to call MPI_WAIT with a null or inactive request argument. In this case the operation returns immediately with empty status.
Enhancement/Correction in the MPI-1.2 Standard:
MPI_TEST(request, flag, status)
int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)
MPI_TEST(REQUEST, FLAG, STATUS, IERROR)
LOGICAL FLAG
INTEGER REQUEST, STATUS(MPI_STATUS_SIZE), IERROR
A call to MPI_TEST returns flag = true if the operation identified by request is complete. In such a case, the status object is set to contain information on the completed operation; if the communication object was created by a nonblocking send or receive, then it is deallocated and the request handle is set to MPI_REQUEST_NULL. The call returns flag = false, otherwise. In this case, the value of the status object is undefined. MPI_TEST is a local operation.
The return status object for a receive operation carries information that can be accessed as described in section 3.2.5. The status object for a send operation carries information that can be accessed by a call to MPI_TEST_CANCELLED (see Section 3.8).
One is allowed to call MPI_TEST with a null or inactive request argument. In such a case the operation returns with flag = true and empty status.
The functions MPI_WAIT and MPI_TEST can be used to complete both sends and receives.
CALL MPI_COMM_RANK(comm, rank, ierr) IF(rank.EQ.0) THEN CALL MPI_ISEND(a(1), 10, MPI_REAL, 1, tag, comm, request, ierr) **** do some computation to mask latency **** CALL MPI_WAIT(request, status, ierr) ELSE CALL MPI_IRECV(a(1), 15, MPI_REAL, 0, tag, comm, request, ierr) **** do some computation to mask latency **** CALL MPI_WAIT(request, status, ierr) END IF
A request object can be deallocated without waiting for the associated communication to complete, by using the following operation.
Enhancement/Correction in the MPI-1.2 Standard:
int MPI_Request_free(MPI_Request *request)
MPI_REQUEST_FREE(REQUEST, IERROR)
INTEGER REQUEST, IERROR
Mark the request object for deallocation and set request to MPI_REQUEST_NULL. An ongoing communication that is associated with the request will be allowed to complete. The request will be deallocated only after its completion.
CALL MPI_COMM_RANK(MPI_COMM_WORLD, rank) IF(rank.EQ.0) THEN DO i=1, n CALL MPI_ISEND(outval, 1, MPI_REAL, 1, 0, req, ierr) CALL MPI_REQUEST_FREE(req, ierr) CALL MPI_IRECV(inval, 1, MPI_REAL, 1, 0, req, ierr) CALL MPI_WAIT(req, status, ierr) END DO ELSE ! rank.EQ.1 CALL MPI_IRECV(inval, 1, MPI_REAL, 0, 0, req, ierr) CALL MPI_WAIT(req, status) DO I=1, n-1 CALL MPI_ISEND(outval, 1, MPI_REAL, 0, 0, req, ierr) CALL MPI_REQUEST_FREE(req, ierr) CALL MPI_IRECV(inval, 1, MPI_REAL, 0, 0, req, ierr) CALL MPI_WAIT(req, status, ierr) END DO CALL MPI_ISEND(outval, 1, MPI_REAL, 0, 0, req, ierr) CALL MPI_WAIT(req, status) END IF
MPI-Standard for MARMOT