PMPI_LOCAL int MPIR_Ibsend_cancel( void *extra, int complete ) { int mpi_errno = MPI_SUCCESS; ibsend_req_info *ibsend_info = (ibsend_req_info *)extra; MPI_Status status; MPIR_Request *req = ibsend_info->req; MPI_Request req_hdl = req->handle; /* FIXME: There should be no unreferenced args! */ /* Note that this value should always be 1 because Grequest_complete is called on this request when it is created */ MPL_UNREFERENCED_ARG(complete); /* Try to cancel the underlying request */ mpi_errno = MPIR_Cancel_impl(req); if (mpi_errno) MPIR_ERR_POP(mpi_errno); mpi_errno = MPIR_Wait_impl( &req_hdl, &status ); if (mpi_errno) MPIR_ERR_POP(mpi_errno); ibsend_info->cancelled = MPIR_STATUS_GET_CANCEL_BIT(status); /* If the cancelation is successful, free the memory in the attached buffer used by the request */ if (ibsend_info->cancelled) { mpi_errno = MPIR_Bsend_free_req_seg(ibsend_info->req); if (mpi_errno) MPIR_ERR_POP(mpi_errno); } fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIR_Bsend_detach( void *bufferp, int *size ) { if (BsendBuffer.pending) { /* FIXME: Process pending bsend requests in detach */ return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Bsend_detach", __LINE__, MPI_ERR_OTHER, "**bsendpending", 0 ); } if (BsendBuffer.active) { /* Loop through each active element and wait on it */ MPIR_Bsend_data_t *p = BsendBuffer.active; while (p) { MPI_Request r = p->request->handle; MPIR_Wait_impl( &r, MPI_STATUS_IGNORE ); p = p->next; } } /* Note that this works even when the buffer does not exist */ *(void **) bufferp = BsendBuffer.origbuffer; /* This cast to int will work because the user must use an int to describe the buffer size */ *size = (int)BsendBuffer.origbuffer_size; BsendBuffer.origbuffer = NULL; BsendBuffer.origbuffer_size = 0; BsendBuffer.buffer = 0; BsendBuffer.buffer_size = 0; BsendBuffer.avail = 0; BsendBuffer.active = 0; BsendBuffer.pending = 0; return MPI_SUCCESS; }
int MPIR_Gather_nb(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; MPI_Request req = MPI_REQUEST_NULL; MPIR_Request *req_ptr = NULL; /* just call the nonblocking version and wait on it */ mpi_errno = MPID_Igather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm_ptr, &req_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); if(req_ptr) req = req_ptr->handle; mpi_errno = MPIR_Wait_impl(&req, MPI_STATUS_IGNORE); if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
PMPI_LOCAL int MPIR_Ibsend_cancel( void *extra, int complete ) { int mpi_errno = MPI_SUCCESS; ibsend_req_info *ibsend_info = (ibsend_req_info *)extra; MPI_Status status; MPID_Request *req = ibsend_info->req; /* FIXME: There should be no unreferenced args! */ /* Note that this value should always be 1 because Grequest_complete is called on this request when it is created */ MPIU_UNREFERENCED_ARG(complete); /* Try to cancel the underlying request */ mpi_errno = MPIR_Cancel_impl(req); if (mpi_errno) MPIU_ERR_POP(mpi_errno); mpi_errno = MPIR_Wait_impl( &req->handle, &status ); if (mpi_errno) MPIU_ERR_POP(mpi_errno); MPIR_Test_cancelled_impl( &status, &ibsend_info->cancelled ); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIR_Finalize_async_thread(void) { int mpi_errno = MPI_SUCCESS; #if MPICH_THREAD_LEVEL == MPI_THREAD_MULTIPLE MPIR_Request *request_ptr = NULL; MPI_Request request; MPI_Status status; MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); mpi_errno = MPID_Isend(NULL, 0, MPI_CHAR, 0, WAKE_TAG, progress_comm_ptr, MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); MPIR_Assert(!mpi_errno); request = request_ptr->handle; mpi_errno = MPIR_Wait_impl(&request, &status); MPIR_Assert(!mpi_errno); /* XXX DJG why is this unlock/lock necessary? Should we just YIELD here or later? */ MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_Thread_mutex_lock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); while (!progress_thread_done) { MPID_Thread_cond_wait(&progress_cond, &progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); } MPID_Thread_mutex_unlock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); mpi_errno = MPIR_Comm_free_impl(progress_comm_ptr); MPIR_Assert(!mpi_errno); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_Thread_cond_destroy(&progress_cond, &mpi_errno); MPIR_Assert(!mpi_errno); MPID_Thread_mutex_destroy(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); #endif /* MPICH_THREAD_LEVEL == MPI_THREAD_MULTIPLE */ return mpi_errno; }
int MPIR_Neighbor_allgather_default(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPID_Comm *comm_ptr) { int mpi_errno = MPI_SUCCESS; MPI_Request req; /* just call the nonblocking version and wait on it */ mpi_errno = MPIR_Ineighbor_allgather_impl(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm_ptr, &req); if (mpi_errno) MPIU_ERR_POP(mpi_errno); mpi_errno = MPIR_Wait_impl(&req, MPI_STATUS_IGNORE); if (mpi_errno) MPIU_ERR_POP(mpi_errno); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIR_Neighbor_alltoallw_default(const void *sendbuf, const int sendcounts[], const MPI_Aint sdispls[], const MPI_Datatype sendtypes[], void *recvbuf, const int recvcounts[], const MPI_Aint rdispls[], const MPI_Datatype recvtypes[], MPIR_Comm *comm_ptr) { int mpi_errno = MPI_SUCCESS; MPI_Request req; /* just call the nonblocking version and wait on it */ mpi_errno = MPID_Ineighbor_alltoallw(sendbuf, sendcounts, sdispls, sendtypes, recvbuf, recvcounts, rdispls, recvtypes, comm_ptr, &req); if (mpi_errno) MPIR_ERR_POP(mpi_errno); mpi_errno = MPIR_Wait_impl(&req, MPI_STATUS_IGNORE); if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
static void progress_fn(void * data) { int mpi_errno = MPI_SUCCESS; MPIR_Request *request_ptr = NULL; MPI_Request request; MPI_Status status; /* Explicitly add CS_ENTER/EXIT since this thread is created from * within an internal function and will call NMPI functions * directly. */ MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); /* FIXME: We assume that waiting on some request forces progress * on all requests. With fine-grained threads, will this still * work as expected? We can imagine an approach where a request on * a non-conflicting communicator would not touch the remaining * requests to avoid locking issues. Once the fine-grained threads * code is fully functional, we need to revisit this and, if * appropriate, either change what we do in this thread, or delete * this comment. */ mpi_errno = MPID_Irecv(NULL, 0, MPI_CHAR, 0, WAKE_TAG, progress_comm_ptr, MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); MPIR_Assert(!mpi_errno); request = request_ptr->handle; mpi_errno = MPIR_Wait_impl(&request, &status); MPIR_Assert(!mpi_errno); /* Send a signal to the main thread saying we are done */ MPID_Thread_mutex_lock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); progress_thread_done = 1; MPID_Thread_mutex_unlock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); MPID_Thread_cond_signal(&progress_cond, &mpi_errno); MPIR_Assert(!mpi_errno); MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); return; }
int MPIR_Barrier_nb(MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; MPI_Request req = MPI_REQUEST_NULL; MPIR_Request *req_ptr = NULL; /* just call the nonblocking version and wait on it */ mpi_errno = MPID_Ibarrier(comm_ptr, &req_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); if(req_ptr) req = req_ptr->handle; mpi_errno = MPIR_Wait_impl(&req, MPI_STATUS_IGNORE); if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIR_Bcast_nb(void *buffer, int count, MPI_Datatype datatype, int root, MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; MPI_Request req = MPI_REQUEST_NULL; MPIR_Request * req_ptr = NULL; /* just call the nonblocking version and wait on it */ mpi_errno = MPID_Ibcast(buffer, count, datatype, root, comm_ptr, &req_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); if(req_ptr) req = req_ptr->handle; mpi_errno = MPIR_Wait_impl(&req, MPI_STATUS_IGNORE); if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }