int ompi_osc_ucx_get(void *origin_addr, int origin_count, struct ompi_datatype_t *origin_dt, int target, ptrdiff_t target_disp, int target_count, struct ompi_datatype_t *target_dt, struct ompi_win_t *win) { ompi_osc_ucx_module_t *module = (ompi_osc_ucx_module_t*) win->w_osc_module; ucp_ep_h ep = OSC_UCX_GET_EP(module->comm, target); uint64_t remote_addr = (module->win_info_array[target]).addr + target_disp * OSC_UCX_GET_DISP(module, target); ucp_rkey_h rkey; ptrdiff_t origin_lb, origin_extent, target_lb, target_extent; bool is_origin_contig = false, is_target_contig = false; ucs_status_t status; int ret = OMPI_SUCCESS; ret = check_sync_state(module, target, false); if (ret != OMPI_SUCCESS) { return ret; } if (module->flavor == MPI_WIN_FLAVOR_DYNAMIC) { status = get_dynamic_win_info(remote_addr, module, ep, target); if (status != UCS_OK) { return OMPI_ERROR; } } rkey = (module->win_info_array[target]).rkey; ompi_datatype_get_true_extent(origin_dt, &origin_lb, &origin_extent); ompi_datatype_get_true_extent(target_dt, &target_lb, &target_extent); is_origin_contig = ompi_datatype_is_contiguous_memory_layout(origin_dt, origin_count); is_target_contig = ompi_datatype_is_contiguous_memory_layout(target_dt, target_count); if (is_origin_contig && is_target_contig) { /* fast path */ size_t origin_len; ompi_datatype_type_size(origin_dt, &origin_len); origin_len *= origin_count; status = ucp_get_nbi(ep, (void *)((intptr_t)origin_addr + origin_lb), origin_len, remote_addr + target_lb, rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_get_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } return incr_and_check_ops_num(module, target, ep); } else { return ddt_put_get(module, origin_addr, origin_count, origin_dt, is_origin_contig, origin_lb, target, ep, remote_addr, rkey, target_count, target_dt, is_target_contig, target_lb, true); } }
static inline int get_dynamic_win_info(uint64_t remote_addr, ompi_osc_ucx_module_t *module, ucp_ep_h ep, int target) { ucp_rkey_h state_rkey = (module->state_info_array)[target].rkey; uint64_t remote_state_addr = (module->state_info_array)[target].addr + OSC_UCX_STATE_DYNAMIC_WIN_CNT_OFFSET; size_t len = sizeof(uint64_t) + sizeof(ompi_osc_dynamic_win_info_t) * OMPI_OSC_UCX_ATTACH_MAX; char *temp_buf = malloc(len); ompi_osc_dynamic_win_info_t *temp_dynamic_wins; int win_count, contain, insert = -1; ucs_status_t status; if ((module->win_info_array[target]).rkey_init == true) { ucp_rkey_destroy((module->win_info_array[target]).rkey); (module->win_info_array[target]).rkey_init == false; } status = ucp_get_nbi(ep, (void *)temp_buf, len, remote_state_addr, state_rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_get_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } status = ucp_ep_flush(ep); if (status != UCS_OK) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_ep_flush failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } memcpy(&win_count, temp_buf, sizeof(uint64_t)); assert(win_count > 0 && win_count <= OMPI_OSC_UCX_ATTACH_MAX); temp_dynamic_wins = (ompi_osc_dynamic_win_info_t *)(temp_buf + sizeof(uint64_t)); contain = ompi_osc_find_attached_region_position(temp_dynamic_wins, 0, win_count, remote_addr, 1, &insert); assert(contain >= 0 && contain < win_count); status = ucp_ep_rkey_unpack(ep, temp_dynamic_wins[contain].rkey_buffer, &((module->win_info_array[target]).rkey)); if (status != UCS_OK) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_ep_rkey_unpack failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } (module->win_info_array[target]).rkey_init = true; free(temp_buf); return status; }
int mca_spml_ucx_get_nb(void *src_addr, size_t size, void *dst_addr, int src, void **handle) { void *rva; ucs_status_t status; spml_ucx_mkey_t *ucx_mkey; ucx_mkey = mca_spml_ucx_get_mkey(src, src_addr, &rva); status = ucp_get_nbi(mca_spml_ucx.ucp_peers[src].ucp_conn, dst_addr, size, (uint64_t)rva, ucx_mkey->rkey); return ucx_status_to_oshmem(status); }
int mca_spml_ucx_get_nb(shmem_ctx_t ctx, void *src_addr, size_t size, void *dst_addr, int src, void **handle) { void *rva; ucs_status_t status; spml_ucx_mkey_t *ucx_mkey; mca_spml_ucx_ctx_t *ucx_ctx = (mca_spml_ucx_ctx_t *)ctx; ucx_mkey = mca_spml_ucx_get_mkey(ctx, src, src_addr, &rva, &mca_spml_ucx); status = ucp_get_nbi(ucx_ctx->ucp_peers[src].ucp_conn, dst_addr, size, (uint64_t)rva, ucx_mkey->rkey); return ucx_status_to_oshmem_nb(status); }
static inline int ddt_put_get(ompi_osc_ucx_module_t *module, const void *origin_addr, int origin_count, struct ompi_datatype_t *origin_dt, bool is_origin_contig, ptrdiff_t origin_lb, int target, ucp_ep_h ep, uint64_t remote_addr, ucp_rkey_h rkey, int target_count, struct ompi_datatype_t *target_dt, bool is_target_contig, ptrdiff_t target_lb, bool is_get) { ucx_iovec_t *origin_ucx_iov = NULL, *target_ucx_iov = NULL; uint32_t origin_ucx_iov_count = 0, target_ucx_iov_count = 0; uint32_t origin_ucx_iov_idx = 0, target_ucx_iov_idx = 0; ucs_status_t status; int ret = OMPI_SUCCESS; if (!is_origin_contig) { ret = create_iov_list(origin_addr, origin_count, origin_dt, &origin_ucx_iov, &origin_ucx_iov_count); if (ret != OMPI_SUCCESS) { return ret; } } if (!is_target_contig) { ret = create_iov_list(NULL, target_count, target_dt, &target_ucx_iov, &target_ucx_iov_count); if (ret != OMPI_SUCCESS) { return ret; } } if (!is_origin_contig && !is_target_contig) { size_t curr_len = 0; while (origin_ucx_iov_idx < origin_ucx_iov_count) { curr_len = MIN(origin_ucx_iov[origin_ucx_iov_idx].len, target_ucx_iov[target_ucx_iov_idx].len); if (!is_get) { status = ucp_put_nbi(ep, origin_ucx_iov[origin_ucx_iov_idx].addr, curr_len, remote_addr + (uint64_t)(target_ucx_iov[target_ucx_iov_idx].addr), rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_put_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } } else { status = ucp_get_nbi(ep, origin_ucx_iov[origin_ucx_iov_idx].addr, curr_len, remote_addr + (uint64_t)(target_ucx_iov[target_ucx_iov_idx].addr), rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_get_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } } ret = incr_and_check_ops_num(module, target, ep); if (ret != OMPI_SUCCESS) { return ret; } origin_ucx_iov[origin_ucx_iov_idx].addr = (void *)((intptr_t)origin_ucx_iov[origin_ucx_iov_idx].addr + curr_len); target_ucx_iov[target_ucx_iov_idx].addr = (void *)((intptr_t)target_ucx_iov[target_ucx_iov_idx].addr + curr_len); origin_ucx_iov[origin_ucx_iov_idx].len -= curr_len; if (origin_ucx_iov[origin_ucx_iov_idx].len == 0) { origin_ucx_iov_idx++; } target_ucx_iov[target_ucx_iov_idx].len -= curr_len; if (target_ucx_iov[target_ucx_iov_idx].len == 0) { target_ucx_iov_idx++; } } assert(origin_ucx_iov_idx == origin_ucx_iov_count && target_ucx_iov_idx == target_ucx_iov_count); } else if (!is_origin_contig) { size_t prev_len = 0; while (origin_ucx_iov_idx < origin_ucx_iov_count) { if (!is_get) { status = ucp_put_nbi(ep, origin_ucx_iov[origin_ucx_iov_idx].addr, origin_ucx_iov[origin_ucx_iov_idx].len, remote_addr + target_lb + prev_len, rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_put_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } } else { status = ucp_get_nbi(ep, origin_ucx_iov[origin_ucx_iov_idx].addr, origin_ucx_iov[origin_ucx_iov_idx].len, remote_addr + target_lb + prev_len, rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_get_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } } ret = incr_and_check_ops_num(module, target, ep); if (ret != OMPI_SUCCESS) { return ret; } prev_len += origin_ucx_iov[origin_ucx_iov_idx].len; origin_ucx_iov_idx++; } } else { size_t prev_len = 0; while (target_ucx_iov_idx < target_ucx_iov_count) { if (!is_get) { status = ucp_put_nbi(ep, (void *)((intptr_t)origin_addr + origin_lb + prev_len), target_ucx_iov[target_ucx_iov_idx].len, remote_addr + (uint64_t)(target_ucx_iov[target_ucx_iov_idx].addr), rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_put_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } } else { status = ucp_get_nbi(ep, (void *)((intptr_t)origin_addr + origin_lb + prev_len), target_ucx_iov[target_ucx_iov_idx].len, remote_addr + (uint64_t)(target_ucx_iov[target_ucx_iov_idx].addr), rkey); if (status != UCS_OK && status != UCS_INPROGRESS) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: ucp_get_nbi failed: %d\n", __FILE__, __LINE__, status); return OMPI_ERROR; } } ret = incr_and_check_ops_num(module, target, ep); if (ret != OMPI_SUCCESS) { return ret; } prev_len += target_ucx_iov[target_ucx_iov_idx].len; target_ucx_iov_idx++; } } if (origin_ucx_iov != NULL) { free(origin_ucx_iov); } if (target_ucx_iov != NULL) { free(target_ucx_iov); } return ret; }