The nonblocking operations must share a data structure with the MPI implementation; this is the part of the MPI_Request that the device needs. Since the part of the implementation above the ADI that uses the requests needs to access very few of the fields in the request, the ADI defines the requests as structures of type MPIR_RHANDLE (receive), MPIR_SHANDLE (send), MPIR_PRHANDLE (persistent receive), and MPIR_PSHANDLE (persistent send). The file mpid/ch2/req.h shows one possible definition. An ADI may define its own request structures as long as the shared fields are maintained. These shared fields include
Unlike the first generation ADI, this ADI is responsible for more of the
``bookeeping'' details; this requires that the ADI know more about MPI
objects. For example, the following code is legal:
MPI_Type_struct( ..., &newtype );
MPI_Type_commit( &newtype );
MPI_Send_init( ..., newtype, ..., &request );
MPI_Type_free( &newtype );
MPI_Start( &request );
....
Note the the user-defined datatype newtype was freed even before the
communication was started. The MPICH implementation maintains reference
counts on all objects that may be used in this way (including datatypes,
communicators, groups, and error handlers); the ADI must update these
reference counts as needed, and must be prepared to delete an object if it
decrements a reference count. This is most likely to be encounted when
implementing receives where the message is not yet available.