static int frag_send (ompi_osc_pt2pt_module_t *module, ompi_osc_pt2pt_frag_t *frag) { int count; count = (int)((uintptr_t) frag->top - (uintptr_t) frag->buffer); OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, "osc pt2pt: frag_send called to %d, frag = %p, count = %d", frag->target, (void *) frag, count)); OSC_PT2PT_HTON(frag->header, module, frag->target); return ompi_osc_pt2pt_isend_w_cb (frag->buffer, count, MPI_BYTE, frag->target, OSC_PT2PT_FRAG_TAG, module->comm, frag_send_cb, frag); }
static inline int ompi_osc_pt2pt_rget_internal (void *origin_addr, int origin_count, struct ompi_datatype_t *origin_dt, int target, OPAL_PTRDIFF_TYPE target_disp, int target_count, struct ompi_datatype_t *target_dt, struct ompi_win_t *win, bool release_req, struct ompi_request_t **request) { int ret, tag; ompi_osc_pt2pt_module_t *module = GET_MODULE(win); bool is_long_datatype = false; ompi_osc_pt2pt_frag_t *frag; ompi_osc_pt2pt_header_get_t *header; ompi_osc_pt2pt_sync_t *pt2pt_sync; size_t ddt_len, frag_len; char *ptr; const void *packed_ddt; ompi_osc_pt2pt_request_t *pt2pt_request; OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output, "get: 0x%lx, %d, %s, %d, %d, %d, %s, %s", (unsigned long) origin_addr, origin_count, origin_dt->name, target, (int) target_disp, target_count, target_dt->name, win->w_name)); pt2pt_sync = ompi_osc_pt2pt_module_sync_lookup (module, target, NULL); if (OPAL_UNLIKELY(NULL == pt2pt_sync)) { return OMPI_ERR_RMA_SYNC; } /* gets are always request based, so that we know where to land the data */ OMPI_OSC_PT2PT_REQUEST_ALLOC(win, pt2pt_request); pt2pt_request->internal = release_req; /* short-circuit case */ if (0 == origin_count || 0 == target_count) { ompi_osc_pt2pt_request_complete (pt2pt_request, MPI_SUCCESS); *request = &pt2pt_request->super; return OMPI_SUCCESS; } /* optimize self communication. TODO: optimize local communication */ if (ompi_comm_rank (module->comm) == target) { *request = &pt2pt_request->super; return ompi_osc_pt2pt_get_self (pt2pt_sync, origin_addr, origin_count, origin_dt, target_disp, target_count, target_dt, module, pt2pt_request); } pt2pt_request->type = OMPI_OSC_PT2PT_HDR_TYPE_GET; pt2pt_request->origin_addr = origin_addr; pt2pt_request->origin_count = origin_count; OMPI_DATATYPE_RETAIN(origin_dt); pt2pt_request->origin_dt = origin_dt; /* Compute datatype length. Note that the datatype description * must fit in a single frag */ ddt_len = ompi_datatype_pack_description_length(target_dt); frag_len = sizeof(ompi_osc_pt2pt_header_get_t) + ddt_len; ret = ompi_osc_pt2pt_frag_alloc(module, target, frag_len, &frag, &ptr, false, release_req); if (OMPI_SUCCESS != ret) { /* allocate space for the header plus space to store ddt_len */ frag_len = sizeof(ompi_osc_pt2pt_header_get_t) + 8; ret = ompi_osc_pt2pt_frag_alloc(module, target, frag_len, &frag, &ptr, false, release_req); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { return OMPI_ERR_OUT_OF_RESOURCE; } is_long_datatype = true; } tag = get_tag (module); /* for bookkeeping the get is "outgoing" */ ompi_osc_signal_outgoing (module, target, 1); if (!release_req) { /* wait for epoch to begin before starting rget operation */ ompi_osc_pt2pt_sync_wait_expected (pt2pt_sync); } header = (ompi_osc_pt2pt_header_get_t*) ptr; header->base.type = OMPI_OSC_PT2PT_HDR_TYPE_GET; header->base.flags = 0; header->len = frag_len; header->count = target_count; header->displacement = target_disp; header->tag = tag; OSC_PT2PT_HTON(header, module, target); ptr += sizeof(ompi_osc_pt2pt_header_get_t); do { ret = ompi_datatype_get_pack_description(target_dt, &packed_ddt); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { break; } if (is_long_datatype) { /* the datatype does not fit in an eager message. send it seperately */ header->base.flags |= OMPI_OSC_PT2PT_HDR_FLAG_LARGE_DATATYPE; OMPI_DATATYPE_RETAIN(target_dt); ret = ompi_osc_pt2pt_isend_w_cb ((void *) packed_ddt, ddt_len, MPI_BYTE, target, tag_to_target(tag), module->comm, ompi_osc_pt2pt_dt_send_complete, target_dt); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { break; } *((uint64_t *) ptr) = ddt_len; ptr += 8; } else { memcpy((unsigned char*) ptr, packed_ddt, ddt_len); ptr += ddt_len; } /* TODO -- store the request somewhere so we can cancel it on error */ pt2pt_request->outstanding_requests = 1; ret = ompi_osc_pt2pt_irecv_w_cb (origin_addr, origin_count, origin_dt, target, tag_to_origin(tag), module->comm, NULL, ompi_osc_pt2pt_req_comm_complete, pt2pt_request); } while (0); if (OMPI_SUCCESS == ret) { header->base.flags |= OMPI_OSC_PT2PT_HDR_FLAG_VALID; *request = &pt2pt_request->super; } return ompi_osc_pt2pt_frag_finish(module, frag); }