/*@ MPI_Cancel - Cancels a communication request Input Parameters: . request - communication request (handle) Notes: The primary expected use of 'MPI_Cancel' is in multi-buffering schemes, where speculative 'MPI_Irecvs' are made. When the computation completes, some of these receive requests may remain; using 'MPI_Cancel' allows the user to cancel these unsatisfied requests. Cancelling a send operation is much more difficult, in large part because the send will usually be at least partially complete (the information on the tag, size, and source are usually sent immediately to the destination). Users are advised that cancelling a send, while a local operation (as defined by the MPI standard), is likely to be expensive (usually generating one or more internal messages). .N ThreadSafe .N Fortran .N NULL .N Errors .N MPI_SUCCESS .N MPI_ERR_REQUEST .N MPI_ERR_ARG @*/ int MPI_Cancel(MPI_Request *request) { int mpi_errno = MPI_SUCCESS; MPID_Request * request_ptr; MPID_MPI_STATE_DECL(MPID_STATE_MPI_CANCEL); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPIU_THREAD_CS_ENTER(ALLFUNC,); MPID_MPI_PT2PT_FUNC_ENTER(MPID_STATE_MPI_CANCEL); /* Convert MPI object handles to object pointers */ MPID_Request_get_ptr( *request, request_ptr ); /* Validate parameters if error checking is enabled */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { /* Validate request_ptr */ MPID_Request_valid_ptr( request_ptr, mpi_errno ); if (mpi_errno) goto fn_fail; } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPIR_Cancel_impl(request_ptr); if (mpi_errno) goto fn_fail; /* ... end of body of routine ... */ fn_exit: MPID_MPI_PT2PT_FUNC_EXIT(MPID_STATE_MPI_CANCEL); MPIU_THREAD_CS_EXIT(ALLFUNC,); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_cancel", "**mpi_cancel %p", request); } # endif mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno); goto fn_exit; /* --END ERROR HANDLING-- */ }
/*@ MPI_Start - Initiates a communication with a persistent request handle Input Parameters: . request - communication request (handle) .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS .N MPI_ERR_REQUEST @*/ int MPI_Start(MPI_Request *request) { static const char FCNAME[] = "MPI_Start"; MPID_Request * request_ptr = NULL; int mpi_errno = MPI_SUCCESS; MPID_MPI_STATE_DECL(MPID_STATE_MPI_START); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPIU_THREAD_CS_ENTER(ALLFUNC,); MPID_MPI_PT2PT_FUNC_ENTER(MPID_STATE_MPI_START); /* Validate handle parameters needing to be converted */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPIR_ERRTEST_ARGNULL(request,"request",mpi_errno); MPIR_ERRTEST_REQUEST(*request, mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* Convert MPI request handle to a request object pointer */ MPID_Request_get_ptr( *request, request_ptr ); /* Validate object pointers if error checking is enabled */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPID_Request_valid_ptr( request_ptr, mpi_errno ); if (mpi_errno) goto fn_fail; MPIR_ERRTEST_PERSISTENT(request_ptr, mpi_errno); MPIR_ERRTEST_PERSISTENT_ACTIVE(request_ptr, mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPID_Startall(1, &request_ptr); if (mpi_errno != MPI_SUCCESS) goto fn_fail; /* ... end of body of routine ... */ fn_exit: MPID_MPI_PT2PT_FUNC_EXIT(MPID_STATE_MPI_START); MPIU_THREAD_CS_EXIT(ALLFUNC,); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_start", "**mpi_start %p", request); } # endif mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno); goto fn_exit; /* --END ERROR HANDLING-- */ }
/*@ MPI_Test - Tests for the completion of a request Input Parameters: . request - MPI request (handle) Output Parameters: + flag - true if operation completed (logical) - status - status object (Status). May be 'MPI_STATUS_IGNORE'. .N ThreadSafe .N waitstatus .N Fortran .N FortranStatus .N Errors .N MPI_SUCCESS .N MPI_ERR_REQUEST .N MPI_ERR_ARG @*/ int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status) { int mpi_errno = MPI_SUCCESS; MPID_Request *request_ptr = NULL; MPID_MPI_STATE_DECL(MPID_STATE_MPI_TEST); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPIU_THREAD_CS_ENTER(ALLFUNC,); MPID_MPI_PT2PT_FUNC_ENTER(MPID_STATE_MPI_TEST); /* Validate parameters, especially handles needing to be converted */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPIR_ERRTEST_ARGNULL(request, "request", mpi_errno); MPIR_ERRTEST_REQUEST_OR_NULL(*request, mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ MPID_Request_get_ptr( *request, request_ptr ); /* Validate parameters and objects (post conversion) */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { if (*request != MPI_REQUEST_NULL) { /* Validate request_ptr */ MPID_Request_valid_ptr( request_ptr, mpi_errno ); if (mpi_errno) goto fn_fail; } MPIR_ERRTEST_ARGNULL(flag, "flag", mpi_errno); /* NOTE: MPI_STATUS_IGNORE != NULL */ MPIR_ERRTEST_ARGNULL(status, "status", mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPIR_Test_impl(request, flag, status); if (mpi_errno) goto fn_fail; /* ... end of body of routine ... */ fn_exit: MPID_MPI_PT2PT_FUNC_EXIT(MPID_STATE_MPI_TEST); MPIU_THREAD_CS_EXIT(ALLFUNC,); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_test", "**mpi_test %p %p %p", request, flag, status); } # endif mpi_errno = MPIR_Err_return_comm(request_ptr ? request_ptr->comm : NULL, FCNAME, mpi_errno); goto fn_exit; /* --END ERROR HANDLING-- */ }
/*@ MPI_Grequest_complete - Notify MPI that a user-defined request is complete Input Parameter: . request - Generalized request to mark as complete .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS .seealso: MPI_Grequest_start @*/ int MPI_Grequest_complete( MPI_Request request ) { int mpi_errno = MPI_SUCCESS; MPID_Request *request_ptr; MPID_MPI_STATE_DECL(MPID_STATE_MPI_GREQUEST_COMPLETE); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPIU_THREAD_CS_ENTER(ALLFUNC,); MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GREQUEST_COMPLETE); /* Validate handle parameters needing to be converted */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPIR_ERRTEST_REQUEST(request, mpi_errno); if (mpi_errno) goto fn_fail; } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* Convert MPI object handles to object pointers */ MPID_Request_get_ptr( request, request_ptr ); /* Validate parameters if error checking is enabled */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPID_Request_valid_ptr(request_ptr,mpi_errno); if (request_ptr && request_ptr->kind != MPID_UREQUEST) { mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_ARG, "**notgenreq", 0 ); } if (mpi_errno) goto fn_fail; } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ MPIR_Grequest_complete_impl(request_ptr); /* ... end of body of routine ... */ #ifdef HAVE_ERROR_CHECKING fn_exit: #endif MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GREQUEST_COMPLETE); MPIU_THREAD_CS_EXIT(ALLFUNC,); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING fn_fail: { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_grequest_complete", "**mpi_grequest_complete %R", request); } mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno ); goto fn_exit; # endif /* --END ERROR HANDLING-- */ }
/*@ MPI_Imrecv - Nonblocking receive of message matched by MPI_Mprobe or MPI_Improbe. Input/Output Parameters: . message - message (handle) Input Parameters: + count - number of elements in the receive buffer (non-negative integer) - datatype - datatype of each receive buffer element (handle) Output Parameters: + buf - initial address of the receive buffer (choice) - request - communication request (handle) .N ThreadSafe .N Fortran .N Errors @*/ int MPI_Imrecv(void *buf, int count, MPI_Datatype datatype, MPI_Message *message, MPI_Request *request) { int mpi_errno = MPI_SUCCESS; MPID_Request *rreq = NULL; MPID_Request *msgp = NULL; MPID_MPI_STATE_DECL(MPID_STATE_MPI_IMRECV); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_IMRECV); /* Validate parameters, especially handles needing to be converted */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS { MPIR_ERRTEST_DATATYPE(datatype, "datatype", mpi_errno); /* TODO more checks may be appropriate */ } MPID_END_ERROR_CHECKS } # endif /* HAVE_ERROR_CHECKING */ /* Convert MPI object handles to object pointers */ MPID_Request_get_ptr(*message, msgp); /* Validate parameters and objects (post conversion) */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS { if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN) { MPID_Datatype *datatype_ptr = NULL; MPID_Datatype_get_ptr(datatype, datatype_ptr); MPID_Datatype_valid_ptr(datatype_ptr, mpi_errno); if (mpi_errno != MPI_SUCCESS) goto fn_fail; MPID_Datatype_committed_ptr(datatype_ptr, mpi_errno); if (mpi_errno != MPI_SUCCESS) goto fn_fail; } /* MPI_MESSAGE_NO_PROC should yield a "proc null" status */ if (*message != MPI_MESSAGE_NO_PROC) { MPID_Request_valid_ptr(msgp, mpi_errno); if (mpi_errno) MPIR_ERR_POP(mpi_errno); MPIR_ERR_CHKANDJUMP((msgp->kind != MPID_REQUEST_MPROBE), mpi_errno, MPI_ERR_ARG, "**reqnotmsg"); } MPIR_ERRTEST_ARGNULL(request, "request", mpi_errno); /* TODO more checks may be appropriate (counts, in_place, buffer aliasing, etc) */ } MPID_END_ERROR_CHECKS } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPID_Imrecv(buf, count, datatype, msgp, &rreq); if (mpi_errno) MPIR_ERR_POP(mpi_errno); MPIU_Assert(rreq != NULL); *request = rreq->handle; *message = MPI_MESSAGE_NULL; /* ... end of body of routine ... */ fn_exit: MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_IMRECV); MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_imrecv", "**mpi_imrecv %p %d %D %p %p", buf, count, datatype, message, request); } # endif mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno); goto fn_exit; /* --END ERROR HANDLING-- */ }