📄 ch3u_rma_sync.c
字号:
{ target_dt_derived = 1; MPID_Datatype_get_ptr(rma_op->target_datatype, target_dtp); } else { target_dt_derived = 0; } if (target_dt_derived) { /* derived datatype on target. fill derived datatype info */ dtype_info->is_contig = target_dtp->is_contig; dtype_info->n_contig_blocks = target_dtp->n_contig_blocks; dtype_info->size = target_dtp->size; dtype_info->extent = target_dtp->extent; dtype_info->dataloop_size = target_dtp->dataloop_size; dtype_info->dataloop_depth = target_dtp->dataloop_depth; dtype_info->eltype = target_dtp->eltype; dtype_info->dataloop = target_dtp->dataloop; dtype_info->ub = target_dtp->ub; dtype_info->lb = target_dtp->lb; dtype_info->true_ub = target_dtp->true_ub; dtype_info->true_lb = target_dtp->true_lb; dtype_info->has_sticky_ub = target_dtp->has_sticky_ub; dtype_info->has_sticky_lb = target_dtp->has_sticky_lb; MPIU_CHKPMEM_MALLOC(*dataloop, void *, target_dtp->dataloop_size, mpi_errno, "dataloop"); MPIDI_FUNC_ENTER(MPID_STATE_MEMCPY); memcpy(*dataloop, target_dtp->dataloop, target_dtp->dataloop_size); MPIDI_FUNC_EXIT(MPID_STATE_MEMCPY); if (rma_op->type == MPIDI_RMA_PUT) { put_pkt->dataloop_size = target_dtp->dataloop_size; } else { accum_pkt->dataloop_size = target_dtp->dataloop_size; } } MPID_Datatype_get_size_macro(rma_op->origin_datatype, origin_type_size); if (!origin_dt_derived) { /* basic datatype on origin */ if (!target_dt_derived) { /* basic datatype on target */ iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)rma_op->origin_addr; iov[1].MPID_IOV_LEN = rma_op->origin_count * origin_type_size; iovcnt = 2; } else { /* derived datatype on target */ iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)dtype_info; iov[1].MPID_IOV_LEN = sizeof(*dtype_info); iov[2].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)*dataloop; iov[2].MPID_IOV_LEN = target_dtp->dataloop_size; iov[3].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)rma_op->origin_addr; iov[3].MPID_IOV_LEN = rma_op->origin_count * origin_type_size; iovcnt = 4; } mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsgv(vc, iov, iovcnt, request)); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|rmamsg", 0); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_RMA_MSG); return mpi_errno; } /* --END ERROR HANDLING-- */ } else { /* derived datatype on origin */ if (!target_dt_derived) { /* basic datatype on target */ iovcnt = 1; } else { /* derived datatype on target */ iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)dtype_info; iov[1].MPID_IOV_LEN = sizeof(*dtype_info); iov[2].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)*dataloop; iov[2].MPID_IOV_LEN = target_dtp->dataloop_size; iovcnt = 3; } *request = MPID_Request_create(); if (*request == NULL) { /* --BEGIN ERROR HANDLING-- */ mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_RMA_MSG); return mpi_errno; /* --END ERROR HANDLING-- */ } MPIU_Object_set_ref(*request, 2); (*request)->kind = MPID_REQUEST_SEND; (*request)->dev.datatype_ptr = origin_dtp; /* this will cause the datatype to be freed when the request is freed. */ (*request)->dev.segment_ptr = MPID_Segment_alloc( ); /* if (!*request)->dev.segment_ptr) { MPIU_ERR_POP(); } */ MPID_Segment_init(rma_op->origin_addr, rma_op->origin_count, rma_op->origin_datatype, (*request)->dev.segment_ptr, 0); (*request)->dev.segment_first = 0; (*request)->dev.segment_size = rma_op->origin_count * origin_type_size; iov_n = MPID_IOV_LIMIT - iovcnt; /* On the initial load of a send iov req, set the OnFinal action (null for point-to-point) */ (*request)->dev.OnFinal = 0; mpi_errno = MPIDI_CH3U_Request_load_send_iov(*request, &iov[iovcnt], &iov_n); if (mpi_errno == MPI_SUCCESS) { iov_n += iovcnt; mpi_errno = MPIU_CALL(MPIDI_CH3,iSendv(vc, *request, iov, iov_n)); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { MPID_Datatype_release((*request)->dev.datatype_ptr); MPIU_Object_set_ref(*request, 0); MPIDI_CH3_Request_destroy(*request); *request = NULL; mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|rmamsg", 0); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_RMA_MSG); return mpi_errno; } /* --END ERROR HANDLING-- */ } else { /* --BEGIN ERROR HANDLING-- */ MPID_Datatype_release((*request)->dev.datatype_ptr); MPIU_Object_set_ref(*request, 0); MPIDI_CH3_Request_destroy(*request); *request = NULL; mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|loadsendiov", 0); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_RMA_MSG); return mpi_errno; /* --END ERROR HANDLING-- */ } } if (target_dt_derived) { MPID_Datatype_release(target_dtp); } fn_exit: MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_RMA_MSG); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: MPIU_CHKPMEM_REAP(); goto fn_exit; /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_CH3I_Recv_rma_msg#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static int MPIDI_CH3I_Recv_rma_msg(MPIDI_RMA_ops *rma_op, MPID_Win *win_ptr, MPI_Win source_win_handle, MPI_Win target_win_handle, MPIDI_RMA_dtype_info *dtype_info, void **dataloop, MPID_Request **request) { MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_get_t *get_pkt = &upkt.get; int mpi_errno, predefined; MPIDI_VC_t * vc; MPID_Comm *comm_ptr; MPID_Request *req = NULL; MPID_Datatype *dtp; MPID_IOV iov[MPID_IOV_LIMIT]; MPIU_CHKPMEM_DECL(1); MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_RECV_RMA_MSG); MPIDI_STATE_DECL(MPID_STATE_MEMCPY); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_RECV_RMA_MSG); /* create a request, store the origin buf, cnt, datatype in it, and pass a handle to it in the get packet. When the get response comes from the target, it will contain the request handle. */ req = MPID_Request_create(); if (req == NULL) { /* --BEGIN ERROR HANDLING-- */ mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_RECV_RMA_MSG); return mpi_errno; /* --END ERROR HANDLING-- */ } *request = req; MPIU_Object_set_ref(req, 2); req->dev.user_buf = rma_op->origin_addr; req->dev.user_count = rma_op->origin_count; req->dev.datatype = rma_op->origin_datatype; req->dev.target_win_handle = MPI_WIN_NULL; req->dev.source_win_handle = source_win_handle; MPIDI_CH3I_DATATYPE_IS_PREDEFINED(req->dev.datatype, predefined); if (!predefined) { MPID_Datatype_get_ptr(req->dev.datatype, dtp); req->dev.datatype_ptr = dtp; /* this will cause the datatype to be freed when the request is freed. */ } MPIDI_Pkt_init(get_pkt, MPIDI_CH3_PKT_GET); get_pkt->addr = (char *) win_ptr->base_addrs[rma_op->target_rank] + win_ptr->disp_units[rma_op->target_rank] * rma_op->target_disp; get_pkt->count = rma_op->target_count; get_pkt->datatype = rma_op->target_datatype; get_pkt->request_handle = req->handle; get_pkt->target_win_handle = target_win_handle; get_pkt->source_win_handle = source_win_handle;/* printf("send pkt: type %d, addr %d, count %d, base %d\n", rma_pkt->type, rma_pkt->addr, rma_pkt->count, win_ptr->base_addrs[rma_op->target_rank]); fflush(stdout);*/ MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); MPIDI_Comm_get_vc(comm_ptr, rma_op->target_rank, &vc); MPIDI_CH3I_DATATYPE_IS_PREDEFINED(rma_op->target_datatype, predefined); if (predefined) { /* basic datatype on target. simply send the get_pkt. */ mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, get_pkt, sizeof(*get_pkt), &req)); } else { /* derived datatype on target. fill derived datatype info and send it along with get_pkt. */ MPID_Datatype_get_ptr(rma_op->target_datatype, dtp); dtype_info->is_contig = dtp->is_contig; dtype_info->n_contig_blocks = dtp->n_contig_blocks; dtype_info->size = dtp->size; dtype_info->extent = dtp->extent; dtype_info->dataloop_size = dtp->dataloop_size; dtype_info->dataloop_depth = dtp->dataloop_depth; dtype_info->eltype = dtp->eltype; dtype_info->dataloop = dtp->dataloop; dtype_info->ub = dtp->ub; dtype_info->lb = dtp->lb; dtype_info->true_ub = dtp->true_ub; dtype_info->true_lb = dtp->true_lb; dtype_info->has_sticky_ub = dtp->has_sticky_ub; dtype_info->has_sticky_lb = dtp->has_sticky_lb; MPIU_CHKPMEM_MALLOC(*dataloop, void *, dtp->dataloop_size, mpi_errno, "dataloop"); MPIDI_FUNC_ENTER(MPID_STATE_MEMCPY); memcpy(*dataloop, dtp->dataloop, dtp->dataloop_size); MPIDI_FUNC_EXIT(MPID_STATE_MEMCPY); get_pkt->dataloop_size = dtp->dataloop_size; iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)get_pkt; iov[0].MPID_IOV_LEN = sizeof(*get_pkt); iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)dtype_info; iov[1].MPID_IOV_LEN = sizeof(*dtype_info); iov[2].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)*dataloop; iov[2].MPID_IOV_LEN = dtp->dataloop_size; mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsgv(vc, iov, 3, &req)); /* release the target datatype */ MPID_Datatype_release(dtp); } /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|rmamsg", 0); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_RECV_RMA_MSG); return mpi_errno; } /* --END ERROR HANDLING-- */ /* release the request returned by iStartMsg or iStartMsgv */ if (req != NULL) { MPID_Request_release(req); } fn_exit: MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_RECV_RMA_MSG); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: MPIU_CHKPMEM_REAP(); goto fn_exit; /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_Win_post#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Win_post(MPID_Group *group_ptr, int assert, MPID_Win *win_ptr){ int nest_level_inc = FALSE; int mpi_errno=MPI_SUCCESS; MPI_Group win_grp, post_grp; int i, post_grp_size, *ranks_in_post_grp, *ranks_in_win_grp, dst, rank; MPIU_CHKLMEM_DECL(2); MPIU_THREADPRIV_DECL; MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_POST); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_POST); MPIU_THREADPRIV_GET; /* Reset the fence counter so that in case the user has switched from fence to post-wait synchronization, he cannot use the previous fence to mark the beginning of a fence epoch. */ win_ptr->fence_cnt = 0; /* In case this process was previously the target of passive target rma * operations, we need to take care of the following... * Since we allow MPI_Win_unlock to return without a done ack from * the target in the case of multiple rma ops and exclusive lock, * we need to check whether there is a lock on the window, and if * there is a lock, poke the progress engine until the operations * have completed and the lock is therefore released. */ if (win_ptr->current_lock_type != MPID_LOCK_NONE) { MPID_Progress_state progress_state; /* poke the progress engine */ MPID_Progress_start(&progress_state); while (win_ptr->current_lock_type != MPID_LOCK_NONE) { mpi_errno = MPID_Progress_wait(&progress_state); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { MPID_Progress_end(&progress_state); mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", "**fail %s", "making progress on the rma messages failed"); goto fn_exit; } /* --END ERROR HANDLING-- */ } MPID_Progress_end(&progress_state); } post_grp_size = group_ptr->size; /* initialize the completion counter */ win_ptr->my_counter = post_grp_size; if ((assert & MPI_MODE_NOCHECK) == 0) { /* NOCHECK not specified. We need to notify the source processes that Post has been called. */ /* We need to translate the ranks of the processes in post_group to ranks in win_ptr->comm, so that we can do communication */ MPIU_CHKLMEM_MALLOC(ranks_in_post_grp, int *, post_grp_size * sizeof(int), mpi_errno, "ranks_in_post_grp"); MPIU_CHKLMEM_MALLOC(ranks_in_win_grp, int *, post_grp_size * sizeof(int), mpi_errno, "ranks_in_win_grp"); for (i=0; i<post_grp_size; i++) { ranks_in_post_grp[i] = i; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -