📄 ch3u_rma_ops.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#include "mpidi_ch3_impl.h"#include "mpidrma.h"#define MPIDI_PASSIVE_TARGET_DONE_TAG 348297#define MPIDI_PASSIVE_TARGET_RMA_TAG 563924#undef FUNCNAME#define FUNCNAME MPIDI_Win_create#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Win_create(void *base, MPI_Aint size, int disp_unit, MPID_Info *info, MPID_Comm *comm_ptr, MPID_Win **win_ptr, MPIDI_RMAFns *RMAFns){ int mpi_errno=MPI_SUCCESS, i, comm_size, rank; MPI_Aint *tmp_buf; MPIU_CHKPMEM_DECL(4); MPIU_CHKLMEM_DECL(1); MPIU_THREADPRIV_DECL; MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_CREATE); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_CREATE); /* FIXME: There should be no unreferenced args */ MPIU_UNREFERENCED_ARG(info); MPIU_UNREFERENCED_ARG(RMAFns); MPIU_THREADPRIV_GET; MPIR_Nest_incr(); comm_size = comm_ptr->local_size; rank = comm_ptr->rank; *win_ptr = (MPID_Win *)MPIU_Handle_obj_alloc( &MPID_Win_mem ); MPIU_ERR_CHKANDJUMP(!(*win_ptr),mpi_errno,MPI_ERR_OTHER,"**nomem"); (*win_ptr)->fence_cnt = 0; (*win_ptr)->base = base; (*win_ptr)->size = size; (*win_ptr)->disp_unit = disp_unit; (*win_ptr)->start_group_ptr = NULL; (*win_ptr)->start_assert = 0; (*win_ptr)->attributes = NULL; (*win_ptr)->rma_ops_list = NULL; (*win_ptr)->lock_granted = 0; (*win_ptr)->current_lock_type = MPID_LOCK_NONE; (*win_ptr)->shared_lock_ref_cnt = 0; (*win_ptr)->lock_queue = NULL; (*win_ptr)->my_counter = 0; (*win_ptr)->my_pt_rma_puts_accs = 0; mpi_errno = NMPI_Comm_dup(comm_ptr->handle, &((*win_ptr)->comm)); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } /* allocate memory for the base addresses, disp_units, and completion counters of all processes */ MPIU_CHKPMEM_MALLOC((*win_ptr)->base_addrs, void **, comm_size*sizeof(void *), mpi_errno, "(*win_ptr)->base_addrs"); MPIU_CHKPMEM_MALLOC((*win_ptr)->disp_units, int *, comm_size*sizeof(int), mpi_errno, "(*win_ptr)->disp_units"); MPIU_CHKPMEM_MALLOC((*win_ptr)->all_win_handles, MPI_Win *, comm_size*sizeof(MPI_Win), mpi_errno, "(*win_ptr)->all_win_handles"); MPIU_CHKPMEM_MALLOC((*win_ptr)->pt_rma_puts_accs, int *, comm_size*sizeof(int), mpi_errno, "(*win_ptr)->pt_rma_puts_accs"); for (i=0; i<comm_size; i++) (*win_ptr)->pt_rma_puts_accs[i] = 0; /* get the addresses of the windows, window objects, and completion counters of all processes. allocate temp. buffer for communication */ MPIU_CHKLMEM_MALLOC(tmp_buf, MPI_Aint *, 3*comm_size*sizeof(MPI_Aint), mpi_errno, "tmp_buf"); /* FIXME: This needs to be fixed for heterogeneous systems */ tmp_buf[3*rank] = MPIU_PtrToAint(base); tmp_buf[3*rank+1] = (MPI_Aint) disp_unit; tmp_buf[3*rank+2] = (MPI_Aint) (*win_ptr)->handle; mpi_errno = NMPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, tmp_buf, 3 * sizeof(MPI_Aint), MPI_BYTE, comm_ptr->handle); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } for (i=0; i<comm_size; i++) { (*win_ptr)->base_addrs[i] = MPIU_AintToPtr(tmp_buf[3*i]); (*win_ptr)->disp_units[i] = (int) tmp_buf[3*i+1]; (*win_ptr)->all_win_handles[i] = (MPI_Win) tmp_buf[3*i+2]; } fn_exit: MPIR_Nest_decr(); MPIU_CHKLMEM_FREEALL(); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_CREATE); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: MPIU_CHKPMEM_REAP(); goto fn_exit; /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_Win_free#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Win_free(MPID_Win **win_ptr){ int mpi_errno=MPI_SUCCESS, total_pt_rma_puts_accs, i, *recvcnts, comm_size; MPID_Comm *comm_ptr; MPIU_CHKLMEM_DECL(1); MPIU_THREADPRIV_DECL; MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_FREE); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_FREE); MPIU_THREADPRIV_GET; MPIR_Nest_incr(); /* set up the recvcnts array for the reduce scatter to check if all passive target rma operations are done */ MPID_Comm_get_ptr( (*win_ptr)->comm, comm_ptr ); comm_size = comm_ptr->local_size; MPIU_CHKLMEM_MALLOC(recvcnts, int *, comm_size*sizeof(int), mpi_errno, "recvcnts"); for (i=0; i<comm_size; i++) recvcnts[i] = 1; mpi_errno = NMPI_Reduce_scatter((*win_ptr)->pt_rma_puts_accs, &total_pt_rma_puts_accs, recvcnts, MPI_INT, MPI_SUM, (*win_ptr)->comm); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } if (total_pt_rma_puts_accs != (*win_ptr)->my_pt_rma_puts_accs) { MPID_Progress_state progress_state; /* poke the progress engine until the two are equal */ MPID_Progress_start(&progress_state); while (total_pt_rma_puts_accs != (*win_ptr)->my_pt_rma_puts_accs) { 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); } NMPI_Comm_free(&((*win_ptr)->comm)); MPIU_Free((*win_ptr)->base_addrs); MPIU_Free((*win_ptr)->disp_units); MPIU_Free((*win_ptr)->all_win_handles); MPIU_Free((*win_ptr)->pt_rma_puts_accs); /* check whether refcount needs to be decremented here as in group_free */ MPIU_Handle_obj_free( &MPID_Win_mem, *win_ptr ); fn_exit: MPIR_Nest_decr(); MPIU_CHKLMEM_FREEALL(); MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_FREE); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: goto fn_exit; /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_Put#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Put(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPID_Win *win_ptr){ int mpi_errno = MPI_SUCCESS; int dt_contig, rank, predefined; MPIDI_RMA_ops *curr_ptr, *prev_ptr, *new_ptr; MPID_Datatype *dtp; MPI_Aint dt_true_lb; MPIDI_msg_sz_t data_sz; MPIU_CHKPMEM_DECL(1); MPIU_THREADPRIV_DECL; MPIDI_STATE_DECL(MPID_STATE_MPIDI_PUT); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_PUT); MPIU_THREADPRIV_GET; MPIDI_Datatype_get_info(origin_count, origin_datatype, dt_contig, data_sz, dtp,dt_true_lb); if ((data_sz == 0) || (target_rank == MPI_PROC_NULL)) { goto fn_exit; } /* FIXME: It makes sense to save the rank (and size) of the communicator in the window structure to speed up these operations, or to save a pointer to the communicator structure, rather than just the handle */ MPIR_Nest_incr(); NMPI_Comm_rank(win_ptr->comm, &rank); MPIR_Nest_decr(); /* If the put is a local operation, do it here */ if (target_rank == rank) { mpi_errno = MPIR_Localcopy(origin_addr, origin_count, origin_datatype, (char *) win_ptr->base + win_ptr->disp_unit * target_disp, target_count, target_datatype); } else { /* queue it up */ curr_ptr = win_ptr->rma_ops_list; prev_ptr = curr_ptr; while (curr_ptr != NULL) { prev_ptr = curr_ptr; curr_ptr = curr_ptr->next; } /* FIXME: Where does this memory get freed? */ MPIU_CHKPMEM_MALLOC(new_ptr, MPIDI_RMA_ops *, sizeof(MPIDI_RMA_ops), mpi_errno, "RMA operation entry"); if (prev_ptr != NULL) prev_ptr->next = new_ptr; else win_ptr->rma_ops_list = new_ptr; new_ptr->next = NULL; new_ptr->type = MPIDI_RMA_PUT; new_ptr->origin_addr = origin_addr; new_ptr->origin_count = origin_count; new_ptr->origin_datatype = origin_datatype; new_ptr->target_rank = target_rank; new_ptr->target_disp = target_disp; new_ptr->target_count = target_count; new_ptr->target_datatype = target_datatype; /* if source or target datatypes are derived, increment their reference counts */ MPIDI_CH3I_DATATYPE_IS_PREDEFINED(origin_datatype, predefined); if (!predefined) { MPID_Datatype_get_ptr(origin_datatype, dtp); MPID_Datatype_add_ref(dtp); } MPIDI_CH3I_DATATYPE_IS_PREDEFINED(target_datatype, predefined); if (!predefined) { MPID_Datatype_get_ptr(target_datatype, dtp); MPID_Datatype_add_ref(dtp); } } fn_exit: MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_PUT); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: MPIU_CHKPMEM_REAP(); goto fn_exit; /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_Get#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Get(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPID_Win *win_ptr){ int mpi_errno = MPI_SUCCESS; MPIDI_msg_sz_t data_sz; int dt_contig, rank, predefined; MPI_Aint dt_true_lb; MPIDI_RMA_ops *curr_ptr, *prev_ptr, *new_ptr; MPID_Datatype *dtp; MPIU_CHKPMEM_DECL(1); MPIU_THREADPRIV_DECL; MPIDI_STATE_DECL(MPID_STATE_MPIDI_GET); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_GET); MPIU_THREADPRIV_GET; MPIDI_Datatype_get_info(origin_count, origin_datatype, dt_contig, data_sz, dtp, dt_true_lb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -