int ompi_osc_portals4_free(struct ompi_win_t *win) { ompi_osc_portals4_module_t *module = (ompi_osc_portals4_module_t*) win->w_osc_module; int ret = OMPI_SUCCESS; /* synchronize */ module->comm->c_coll.coll_barrier(module->comm, module->comm->c_coll.coll_barrier_module); /* cleanup */ PtlMEUnlink(module->data_me_h); PtlMDRelease(module->md_h); PtlMDRelease(module->req_md_h); PtlCTFree(module->ct_h); if (NULL != module->disp_units) free(module->disp_units); ompi_comm_free(&module->comm); if (NULL != module->free_after) free(module->free_after); if (!opal_list_is_empty(&module->outstanding_locks)) { ret = OMPI_ERR_RMA_SYNC; } OBJ_DESTRUCT(&module->outstanding_locks); free(module); return ret; }
void mca_btl_portals4_free_module(mca_btl_portals4_module_t *portals4_btl) { int ret; OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "mca_btl_portals4_free_module portals_outstanding_ops=%d\n", portals4_btl->portals_outstanding_ops)); /* sanity check */ assert(portals4_btl->portals_outstanding_ops >= 0); /* finalize all communication */ while (portals4_btl->portals_outstanding_ops > 0) { OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "mca_btl_portals4_free_module portals_outstanding_ops: %d", portals4_btl->portals_outstanding_ops)); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Call to mca_btl_portals4_component_progress (3)\n")); mca_btl_portals4_component_progress(); } if (!PtlHandleIsEqual(portals4_btl->send_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(portals4_btl->send_md_h); portals4_btl->send_md_h = PTL_INVALID_HANDLE; } if (!PtlHandleIsEqual(portals4_btl->zero_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(portals4_btl->zero_md_h); portals4_btl->zero_md_h = PTL_INVALID_HANDLE; } if (!PtlHandleIsEqual(portals4_btl->long_overflow_me_h, PTL_INVALID_HANDLE)) { PtlMEUnlink(portals4_btl->long_overflow_me_h); portals4_btl->long_overflow_me_h = PTL_INVALID_HANDLE; } if ((ptl_pt_index_t) ~0UL != mca_btl_portals4_module.recv_idx) { PtlPTFree(portals4_btl->portals_ni_h, portals4_btl->recv_idx); portals4_btl->recv_idx= (ptl_pt_index_t) ~0UL; } if (PTL_EQ_NONE != portals4_btl->recv_eq_h) { ret = PtlEQFree(portals4_btl->recv_eq_h); if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error freeing EQ recv: %d", ret)); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlEQFree: recv_eq_h=%d portals4_btl=%p", portals4_btl->recv_eq_h, (void*)portals4_btl)); portals4_btl->recv_eq_h = PTL_EQ_NONE; } if (!PtlHandleIsEqual(portals4_btl->portals_ni_h, PTL_INVALID_HANDLE)) { ret = PtlNIFini(portals4_btl->portals_ni_h); if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error returned by PtlNIFini: %d\n", ret)); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlNIFini: portals_ni_h=%d portals4_btl=%p", portals4_btl->portals_ni_h, (void*)portals4_btl)); portals4_btl->portals_ni_h = PTL_INVALID_HANDLE; } ret = mca_btl_portals4_recv_disable(portals4_btl); if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error freeing recv list: %d", ret)); }
static int handler_recv_complete(const ptl_event_t *e) { int mpi_errno = MPI_SUCCESS; MPID_Request *const rreq = e->user_ptr; int ret; int i; MPIDI_STATE_DECL(MPID_STATE_HANDLER_RECV_COMPLETE); MPIDI_FUNC_ENTER(MPID_STATE_HANDLER_RECV_COMPLETE); MPIU_Assert(e->type == PTL_EVENT_REPLY || e->type == PTL_EVENT_PUT || e->type == PTL_EVENT_PUT_OVERFLOW); if (REQ_PTL(rreq)->md != PTL_INVALID_HANDLE) { ret = PtlMDRelease(REQ_PTL(rreq)->md); MPIR_ERR_CHKANDJUMP1(ret, mpi_errno, MPI_ERR_OTHER, "**ptlmdrelease", "**ptlmdrelease %s", MPID_nem_ptl_strerror(ret)); } for (i = 0; i < MPID_NEM_PTL_NUM_CHUNK_BUFFERS; ++i) if (REQ_PTL(rreq)->chunk_buffer[i]) MPIU_Free(REQ_PTL(rreq)->chunk_buffer[i]); mpi_errno = MPID_Request_complete(rreq); if (mpi_errno) { MPIR_ERR_POP(mpi_errno); } fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_HANDLER_RECV_COMPLETE); return mpi_errno; fn_fail: goto fn_exit; }
static void mca_btl_portals4_frag_eager_destructor(mca_btl_portals4_frag_t* frag) { if (PTL_INVALID_HANDLE == frag->me_h) { PtlMDRelease(frag->me_h); frag->me_h = PTL_INVALID_HANDLE; } }
static int read_msg(void *start, ptl_size_t length, ptl_process_t target, ptl_match_bits_t match_bits, ptl_size_t remote_offset, ompi_mtl_portals4_recv_request_t *request) { ptl_md_t md; int ret; /* FIX ME: This needs to be on the send eq... */ md.start = start; md.length = length; md.options = 0; md.eq_handle = ompi_mtl_portals4.send_eq_h; md.ct_handle = PTL_CT_NONE; ret = PtlMDBind(ompi_mtl_portals4.ni_h, &md, &request->md_h); if (OPAL_UNLIKELY(PTL_OK != ret)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlMDBind failed: %d", __FILE__, __LINE__, ret); return OMPI_ERR_OUT_OF_RESOURCE; } #if OMPI_MTL_PORTALS4_FLOW_CONTROL while (OPAL_UNLIKELY(OPAL_THREAD_ADD32(&ompi_mtl_portals4.flowctl.send_slots, -1) < 0)) { OPAL_THREAD_ADD32(&ompi_mtl_portals4.flowctl.send_slots, 1); ompi_mtl_portals4_progress(); } #endif ret = PtlGet(request->md_h, 0, md.length, target, ompi_mtl_portals4.read_idx, match_bits, remote_offset, request); if (OPAL_UNLIKELY(PTL_OK != ret)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlGet failed: %d", __FILE__, __LINE__, ret); PtlMDRelease(request->md_h); return OMPI_ERR_OUT_OF_RESOURCE; } return OMPI_SUCCESS; }
int ompi_mtl_portals4_finalize(struct mca_mtl_base_module_t *mtl) { opal_progress_unregister(ompi_mtl_portals4_progress); while (0 != ompi_mtl_portals4_progress()) { } #if OMPI_MTL_PORTALS4_FLOW_CONTROL ompi_mtl_portals4_flowctl_fini(); #endif ompi_mtl_portals4_recv_short_fini(); PtlMEUnlink(ompi_mtl_portals4.long_overflow_me_h); PtlMDRelease(ompi_mtl_portals4.zero_md_h); #if OPAL_PORTALS4_MAX_MD_SIZE < OPAL_PORTALS4_MAX_VA_SIZE { int i; int num_mds = ompi_mtl_portals4_get_num_mds(); for (i = 0 ; i < num_mds ; ++i) { PtlMDRelease(ompi_mtl_portals4.send_md_hs[i]); } free(ompi_mtl_portals4.send_md_hs); } #else PtlMDRelease(ompi_mtl_portals4.send_md_h); #endif PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.read_idx); PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_idx); PtlEQFree(ompi_mtl_portals4.send_eq_h); PtlEQFree(ompi_mtl_portals4.recv_eq_h); PtlNIFini(ompi_mtl_portals4.ni_h); PtlFini(); return OMPI_SUCCESS; }
int ompi_mtl_portals4_finalize(struct mca_mtl_base_module_t *mtl) { opal_progress_unregister(ompi_mtl_portals4_progress); while (0 != ompi_mtl_portals4_progress()) { } #if OMPI_MTL_PORTALS4_FLOW_CONTROL ompi_mtl_portals4_flowctl_fini(); #endif ompi_mtl_portals4_recv_short_fini(); PtlMEUnlink(ompi_mtl_portals4.long_overflow_me_h); PtlMDRelease(ompi_mtl_portals4.zero_md_h); PtlMDRelease(ompi_mtl_portals4.send_md_h); PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.read_idx); PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_idx); PtlEQFree(ompi_mtl_portals4.send_eq_h); PtlEQFree(ompi_mtl_portals4.recv_eq_h); PtlNIFini(ompi_mtl_portals4.ni_h); PtlFini(); return OMPI_SUCCESS; }
/* ** Buffers in args.r_buff and args.s_buff have been allocated and aligned. ** We setup an MD over s_buff and an LE over r_buff. This gets called ** outside the timing loop, but we still try to be a little efficient here. ** We only free and re-allocate an MD/LE if the buffer address or ** length has changed. */ void AfterAlignmentInit(ArgStruct *p) { int rc; /* Create a persistent ME to send from */ if (PtlHandleIsEqual(md_handle, PTL_INVALID_HANDLE)) { /* First time here, setup an MD to send benchmark data */ libtest_CreateMDCT(ni_logical, p->s_buff, p->bufflen, &md_handle, &send_ct_handle); md_size= p->bufflen; md_buf= p->s_buff; } else if ((md_size != p->bufflen) || (md_buf != p->s_buff)) { /* Release the existing MD and create a new one */ rc= PtlMDRelease(md_handle); LIBTEST_CHECK(rc, "PtlMDRelease(md_handle) in AfterAlignmentInit"); libtest_CreateMDCT(ni_logical, p->s_buff, p->bufflen, &md_handle, &send_ct_handle); md_size= p->bufflen; md_buf= p->s_buff; } else { /* Just keep the MD we already have */ } /* Create a persistent LE to receive into */ if (PtlHandleIsEqual(le_handle, PTL_INVALID_HANDLE)) { libtest_CreateLECT(ni_logical, PTL_XMIT_INDEX, p->r_buff, p->bufflen, &le_handle, &recv_ct_handle); le_size= p->bufflen; le_buf= p->r_buff; } else if ((le_size != p->bufflen) || (le_buf != p->r_buff)) { rc= PtlLEUnlink(le_handle); LIBTEST_CHECK(rc, "PtlLEUnlink(le_handle) in CleanUp"); libtest_CreateLECT(ni_logical, PTL_XMIT_INDEX, p->r_buff, p->bufflen, &le_handle, &recv_ct_handle); le_size= p->bufflen; le_buf= p->r_buff; } else { /* Just keep the LE we already have */ } } /* end of AfterAlignmentInit() */
static int handler_send(const ptl_event_t *e) { int mpi_errno = MPI_SUCCESS; MPID_Request *const sreq = e->user_ptr; int i, ret; MPIDI_STATE_DECL(MPID_STATE_HANDLER_SEND); MPIDI_FUNC_ENTER(MPID_STATE_HANDLER_SEND); MPIU_Assert(e->type == PTL_EVENT_SEND || e->type == PTL_EVENT_GET); /* if we are done, release all netmod resources */ if (MPID_cc_get(sreq->cc) == 1) { if (REQ_PTL(sreq)->md != PTL_INVALID_HANDLE) { ret = PtlMDRelease(REQ_PTL(sreq)->md); MPIR_ERR_CHKANDJUMP1(ret, mpi_errno, MPI_ERR_OTHER, "**ptlmdrelease", "**ptlmdrelease %s", MPID_nem_ptl_strerror(ret)); } for (i = 0; i < MPID_NEM_PTL_NUM_CHUNK_BUFFERS; ++i) if (REQ_PTL(sreq)->chunk_buffer[i]) MPIU_Free(REQ_PTL(sreq)->chunk_buffer[i]); if (REQ_PTL(sreq)->get_me_p) MPIU_Free(REQ_PTL(sreq)->get_me_p); } mpi_errno = MPID_Request_complete(sreq); if (mpi_errno != MPI_SUCCESS) { MPIR_ERR_POP(mpi_errno); } fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_HANDLER_SEND); return mpi_errno; fn_fail: goto fn_exit; }
int main(int argc, char *argv[]) { ptl_handle_ni_t ni_logical; ptl_pt_index_t logical_pt_index; ptl_process_t myself; struct timeval start, stop; int potato = 0; ENTRY_T potato_catcher; HANDLE_T potato_catcher_handle; ptl_md_t potato_launcher; ptl_handle_md_t potato_launcher_handle; int num_procs; CHECK_RETURNVAL(PtlInit()); CHECK_RETURNVAL(libtest_init()); num_procs = libtest_get_size(); if (NULL != getenv("MAKELEVEL") && num_procs > 2) { return 77; } CHECK_RETURNVAL(PtlNIInit (PTL_IFACE_DEFAULT, NI_TYPE | PTL_NI_LOGICAL, PTL_PID_ANY, NULL, NULL, &ni_logical)); CHECK_RETURNVAL(PtlSetMap(ni_logical, num_procs, libtest_get_mapping(ni_logical))); CHECK_RETURNVAL(PtlGetId(ni_logical, &myself)); CHECK_RETURNVAL(PtlPTAlloc (ni_logical, 0, PTL_EQ_NONE, PTL_PT_ANY, &logical_pt_index)); assert(logical_pt_index == 0); /* Now do the initial setup on ni_logical */ potato_catcher.start = &potato; potato_catcher.length = sizeof(potato); potato_catcher.uid = PTL_UID_ANY; potato_catcher.options = OPTIONS; #if INTERFACE == 1 potato_catcher.match_id.rank = PTL_RANK_ANY; potato_catcher.match_bits = 1; potato_catcher.ignore_bits = ~potato_catcher.match_bits; #endif CHECK_RETURNVAL(PtlCTAlloc(ni_logical, &potato_catcher.ct_handle)); CHECK_RETURNVAL(APPEND (ni_logical, logical_pt_index, &potato_catcher, PTL_PRIORITY_LIST, NULL, &potato_catcher_handle)); /* Now do a barrier (on ni_physical) to make sure that everyone has their * logical interface set up */ libtest_barrier(); /* now I can communicate between ranks with ni_logical */ /* set up the potato launcher */ potato_launcher.start = &potato; potato_launcher.length = sizeof(potato); potato_launcher.options = PTL_MD_EVENT_CT_ACK | PTL_MD_EVENT_CT_SEND; potato_launcher.eq_handle = PTL_EQ_NONE; // i.e. don't queue send events CHECK_RETURNVAL(PtlCTAlloc(ni_logical, &potato_launcher.ct_handle)); CHECK_RETURNVAL(PtlMDBind (ni_logical, &potato_launcher, &potato_launcher_handle)); /* rank 0 starts the potato going */ if (myself.rank == 0) { ptl_process_t nextrank; nextrank.rank = myself.rank + 1; nextrank.rank *= (nextrank.rank <= num_procs - 1); gettimeofday(&start, NULL); CHECK_RETURNVAL(PtlPut(potato_launcher_handle, 0, potato_launcher.length, (LOOPS == 1) ? PTL_OC_ACK_REQ : PTL_NO_ACK_REQ, nextrank, logical_pt_index, 1, 0, NULL, 1)); } { /* the potato-passing loop */ size_t waitfor; ptl_ct_event_t ctc; ptl_process_t nextrank; nextrank.rank = myself.rank + 1; nextrank.rank *= (nextrank.rank <= num_procs - 1); for (waitfor = 1; waitfor <= LOOPS; ++waitfor) { CHECK_RETURNVAL(PtlCTWait(potato_catcher.ct_handle, waitfor, &ctc)); // wait for potato assert(ctc.failure == 0); assert(ctc.success == waitfor); /* I have the potato! */ ++potato; if (potato < LOOPS * (num_procs)) { // otherwise, the recipient may have exited /* Bomb's away! */ if (myself.rank == 0) { CHECK_RETURNVAL(PtlPut(potato_launcher_handle, 0, potato_launcher.length, (waitfor == (LOOPS - 1)) ? PTL_OC_ACK_REQ : PTL_NO_ACK_REQ, nextrank, logical_pt_index, 3, 0, NULL, 2)); } else { CHECK_RETURNVAL(PtlPut(potato_launcher_handle, 0, potato_launcher.length, (waitfor == LOOPS) ? PTL_OC_ACK_REQ : PTL_NO_ACK_REQ, nextrank, logical_pt_index, 3, 0, NULL, 2)); } } } // make sure that last send completed before exiting CHECK_RETURNVAL(PtlCTWait(potato_launcher.ct_handle, LOOPS+1, &ctc)); assert(ctc.failure == 0); } if (myself.rank == 0) { double accumulate = 0.0; gettimeofday(&stop, NULL); accumulate = (stop.tv_sec + stop.tv_usec * 1e-6) - (start.tv_sec + start.tv_usec * 1e-6); /* calculate the average time waiting */ printf("Total time: %g secs\n", accumulate); accumulate /= LOOPS; printf("Average time around the loop: %g microseconds\n", accumulate * 1e6); accumulate /= num_procs; printf("Average catch-to-toss latency: %g microseconds\n", accumulate * 1e6); } /* cleanup */ CHECK_RETURNVAL(PtlMDRelease(potato_launcher_handle)); CHECK_RETURNVAL(PtlCTFree(potato_launcher.ct_handle)); CHECK_RETURNVAL(UNLINK(potato_catcher_handle)); CHECK_RETURNVAL(PtlCTFree(potato_catcher.ct_handle)); /* major cleanup */ CHECK_RETURNVAL(PtlPTFree(ni_logical, logical_pt_index)); CHECK_RETURNVAL(PtlNIFini(ni_logical)); CHECK_RETURNVAL(libtest_fini()); PtlFini(); return 0; }
static int portals4_close(void) { int ret; OBJ_DESTRUCT(&mca_coll_portals4_component.requests); if (!PtlHandleIsEqual(mca_coll_portals4_component.zero_md_h, PTL_INVALID_HANDLE)) { ret = PtlMDRelease(mca_coll_portals4_component.zero_md_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlMDRelease failed: %d\n", __FILE__, __LINE__, ret); } } mca_coll_portals4_component.zero_md_h = PTL_INVALID_HANDLE; if (!PtlHandleIsEqual(mca_coll_portals4_component.data_md_h, PTL_INVALID_HANDLE)) { ret = PtlMDRelease(mca_coll_portals4_component.data_md_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlMDRelease failed: %d\n", __FILE__, __LINE__, ret); } } mca_coll_portals4_component.data_md_h = PTL_INVALID_HANDLE; if (!PtlHandleIsEqual(mca_coll_portals4_component.finish_me_h, PTL_INVALID_HANDLE)) { ret = PtlMEUnlink(mca_coll_portals4_component.finish_me_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlMEUnlink failed: %d\n", __FILE__, __LINE__, ret); } } if (!PtlHandleIsEqual(mca_coll_portals4_component.unex_me_h, PTL_INVALID_HANDLE)) { ret = PtlMEUnlink(mca_coll_portals4_component.unex_me_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlMEUnlink failed: %d\n", __FILE__, __LINE__, ret); } } if (mca_coll_portals4_component.finish_pt_idx >= 0) { ret = PtlPTFree(mca_coll_portals4_component.ni_h, mca_coll_portals4_component.finish_pt_idx); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlPTFree failed: %d\n", __FILE__, __LINE__, ret); } } if (mca_coll_portals4_component.pt_idx >= 0) { ret = PtlPTFree(mca_coll_portals4_component.ni_h, mca_coll_portals4_component.pt_idx); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlPTFree failed: %d\n", __FILE__, __LINE__, ret); } } if (!PtlHandleIsEqual(mca_coll_portals4_component.eq_h, PTL_INVALID_HANDLE)) { ret = PtlEQFree(mca_coll_portals4_component.eq_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlEQFree failed: %d\n", __FILE__, __LINE__, ret); } } if (!PtlHandleIsEqual(mca_coll_portals4_component.ni_h, PTL_INVALID_HANDLE)) { ret = PtlNIFini(mca_coll_portals4_component.ni_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlNIFini failed: %d\n", __FILE__, __LINE__, ret); } PtlFini(); } opal_progress_unregister(portals4_progress); return OMPI_SUCCESS; }
int main(int argc, char *argv[]) { ptl_handle_ni_t ni_handle; ptl_process_t *procs; int rank; ptl_pt_index_t pt_index, signal_pt_index; HANDLE_T signal_e_handle; HANDLE_T signal_e2_handle; int num_procs; ptl_handle_eq_t eq_handle; ptl_handle_ct_t ct_handle; ptl_handle_md_t md_handle; ptl_ni_limits_t limits_reqd, limits_actual; ENTRY_T value_e; limits_reqd.max_entries = 1024; limits_reqd.max_unexpected_headers = ITERS*2; limits_reqd.max_mds = 1024; limits_reqd.max_eqs = 1024; limits_reqd.max_cts = 1024; limits_reqd.max_pt_index = 64; limits_reqd.max_iovecs = 1024; limits_reqd.max_list_size = 1024; limits_reqd.max_triggered_ops = 1024; limits_reqd.max_msg_size = 1048576; limits_reqd.max_atomic_size = 1048576; limits_reqd.max_fetch_atomic_size = 1048576; limits_reqd.max_waw_ordered_size = 1048576; limits_reqd.max_war_ordered_size = 1048576; limits_reqd.max_volatile_size = 1048576; limits_reqd.features = 0; CHECK_RETURNVAL(PtlInit()); CHECK_RETURNVAL(libtest_init()); rank = libtest_get_rank(); num_procs = libtest_get_size(); if (num_procs < 2) { fprintf(stderr, "test_flowctl_noeq requires at least two processes\n"); return 77; } int iters; if (num_procs < ITERS) iters = ITERS*2+1; else iters = ITERS; CHECK_RETURNVAL(PtlNIInit(PTL_IFACE_DEFAULT, NI_TYPE | PTL_NI_LOGICAL, PTL_PID_ANY, &limits_reqd, &limits_actual, &ni_handle)); procs = libtest_get_mapping(ni_handle); CHECK_RETURNVAL(PtlSetMap(ni_handle, num_procs, procs)); if (0 == rank) { /* create data PT space */ CHECK_RETURNVAL(PtlEQAlloc(ni_handle, (num_procs - 1) * iters + 64, &eq_handle)); CHECK_RETURNVAL(PtlPTAlloc(ni_handle, PTL_PT_FLOWCTRL, eq_handle, 5, &pt_index)); /* create signal ME */ CHECK_RETURNVAL(PtlCTAlloc(ni_handle, &ct_handle)); CHECK_RETURNVAL(PtlPTAlloc(ni_handle, 1, eq_handle, 6, &signal_pt_index)); value_e.start = NULL; value_e.length = 0; value_e.ct_handle = ct_handle; value_e.uid = PTL_UID_ANY; value_e.options = OPTIONS | PTL_LE_EVENT_CT_COMM; #if INTERFACE == 1 value_e.match_id.rank = PTL_RANK_ANY; value_e.match_bits = 0; value_e.ignore_bits = 0; #endif CHECK_RETURNVAL(APPEND(ni_handle, 5, &value_e, PTL_OVERFLOW_LIST, NULL, &signal_e_handle)); } else { ptl_md_t md; /* 16 extra just in case... */ CHECK_RETURNVAL(PtlEQAlloc(ni_handle, iters*2 + 16, &eq_handle)); md.start = NULL; md.length = 0; md.options = 0; md.eq_handle = eq_handle; md.ct_handle = PTL_CT_NONE; CHECK_RETURNVAL(PtlMDBind(ni_handle, &md, &md_handle)); } fprintf(stderr,"at barrier \n"); libtest_barrier(); if (0 == rank) { ptl_ct_event_t ct; ptl_event_t ev; int ret, count = 0, saw_flowctl = 0; fprintf(stderr,"begin ctwait \n"); /* wait for signal counts */ CHECK_RETURNVAL(PtlCTWait(ct_handle, iters / 2 , &ct)); if (ct.success != iters / 2 || ct.failure != 0) { return 1; } fprintf(stderr,"done CT wait \n"); /* wait for event entries */ while (1) { ret = PtlEQGet(eq_handle, &ev); if (PTL_OK == ret) { count++; fprintf(stderr, "found EQ value \n"); } else if (ret == PTL_EQ_EMPTY) { continue; } else { fprintf(stderr, "0: Unexpected return code from EQGet: %d\n", ret); return 1; } if (ev.type == PTL_EVENT_PT_DISABLED) { saw_flowctl++; break; } } fprintf(stderr, "0: Saw %d flowctl\n", saw_flowctl); if (saw_flowctl == 0) { return 1; } /* Now clear out all of the unexpected messages so we can clean up everything */ CHECK_RETURNVAL(APPEND(ni_handle, 5, &value_e, PTL_PRIORITY_LIST, NULL, &signal_e2_handle)); ret = PTL_OK; while (ret != PTL_EQ_EMPTY) ret = PtlEQGet(eq_handle, &ev); } else { ptl_process_t target; ptl_event_t ev; int ret, count = 0, fails = 0; int i; target.rank = 0; printf("beginning puts \n"); for (i = 0 ; i < iters ; ++i) { CHECK_RETURNVAL(PtlPut(md_handle, 0, 0, PTL_ACK_REQ, target, 5, 0, 0, NULL, 0)); usleep(100); } while (count < iters) { ret = PtlEQGet(eq_handle, &ev); if (PTL_EQ_EMPTY == ret) { continue; } else if (PTL_OK != ret) { fprintf(stderr, "%d: PtlEQGet returned %d\n", rank, ret); return 1; } if (ev.ni_fail_type == PTL_NI_OK) { if (ev.type == PTL_EVENT_SEND) { continue; } else if (ev.type == PTL_EVENT_ACK) { count++; } else { fprintf(stderr, "%d: Unexpected event type %d\n", rank, ev.type); } } else if (ev.ni_fail_type == PTL_NI_PT_DISABLED) { count++; fails++; } else if (ev.ni_fail_type == PTL_EQ_EMPTY) { continue; } else if (ev.ni_fail_type == PTL_EQ_DROPPED) { continue; } else { fprintf(stderr, "%d: Unexpected fail type: %d\n", rank, ev.ni_fail_type); return 1; } } fprintf(stderr, "%d: Saw %d of %d ACKs as fails\n", rank, fails, count); } fprintf(stderr,"at final barrier \n"); libtest_barrier(); if (0 == rank) { CHECK_RETURNVAL(UNLINK(signal_e_handle)); CHECK_RETURNVAL(UNLINK(signal_e2_handle)); CHECK_RETURNVAL(PtlPTFree(ni_handle, signal_pt_index)); CHECK_RETURNVAL(PtlCTFree(ct_handle)); CHECK_RETURNVAL(PtlPTFree(ni_handle, pt_index)); CHECK_RETURNVAL(PtlEQFree(eq_handle)); } else { CHECK_RETURNVAL(PtlMDRelease(md_handle)); CHECK_RETURNVAL(PtlEQFree(eq_handle)); } fprintf(stderr,"final cleanup \n"); CHECK_RETURNVAL(PtlNIFini(ni_handle)); CHECK_RETURNVAL(libtest_fini()); PtlFini(); return 0; }
int mca_btl_portals4_component_progress(void) { mca_btl_portals4_module_t *portals4_btl; int num_progressed = 0; int ret, btl_ownership; mca_btl_portals4_frag_t *frag = NULL; mca_btl_base_tag_t tag; static ptl_event_t ev; unsigned int which; mca_btl_active_message_callback_t* reg; mca_btl_base_segment_t seg[2]; mca_btl_base_descriptor_t btl_base_descriptor; while (true) { ret = PtlEQPoll(mca_btl_portals4_component.eqs_h, mca_btl_portals4_component.num_btls, 0, &ev, &which); if (PTL_OK == ret) { OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlEQPoll Event received: %d (fail=%d) on NI %d\n", ev.type, ev.ni_fail_type, which)); num_progressed++; portals4_btl = mca_btl_portals4_component.btls[which]; switch (ev.type) { case PTL_EVENT_SEND: /* generated on source (origin) when put stops sending */ frag = ev.user_ptr; if (NULL == frag) { opal_output(opal_btl_base_framework.framework_output, "btl/portals4: PTL_EVENT_SEND event with NULL user_ptr"); break; } btl_ownership = (frag->base.des_flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP); if (!mca_btl_portals4_component.portals_need_ack) { /* my part's done, in portals we trust! */ if( MCA_BTL_DES_SEND_ALWAYS_CALLBACK & frag->base.des_flags ){ OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_SEND: Direct call to des_cbfunc: %lx\n", (uint64_t)frag->base.des_cbfunc)); frag->base.des_cbfunc(&portals4_btl->super, frag->endpoint, &frag->base, OPAL_SUCCESS); } if (btl_ownership) { mca_btl_portals4_free(&portals4_btl->super, &frag->base); } if (0 != frag->size) { OPAL_THREAD_ADD32(&portals4_btl->portals_outstanding_ops, -1); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_SEND: Decrementing portals_outstanding_ops=%d (1)\n", portals4_btl->portals_outstanding_ops)); } } goto done; break; case PTL_EVENT_ACK: /* Ack that a put as completed on other side. We just call the callback function */ frag = ev.user_ptr; if (NULL == frag) { opal_output(opal_btl_base_framework.framework_output, "btl/portals4: PTL_EVENT_ACK event with NULL user_ptr"); break; } OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_ACK received rlength=%ld mlength=%ld des_flags=%d\n", ev.rlength, ev.mlength, frag->base.des_flags)); btl_ownership = (frag->base.des_flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP); /* other side received the message. should have received entire thing */ /* let the PML know we're done */ if (MCA_BTL_DES_SEND_ALWAYS_CALLBACK & frag->base.des_flags ) { OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_ACK: Call to des_cbfunc %lx\n", (uint64_t)frag->base.des_cbfunc)); frag->base.des_cbfunc(&portals4_btl->super, frag->endpoint, &frag->base, OPAL_SUCCESS); } if (btl_ownership) { mca_btl_portals4_free(&portals4_btl->super, &frag->base); } if (0 != frag->size) { OPAL_THREAD_ADD32(&portals4_btl->portals_outstanding_ops, -1); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_ACK: Decrementing portals_outstanding_ops=%d (2)\n", portals4_btl->portals_outstanding_ops)); } goto done; break; case PTL_EVENT_PUT: /* Generated on destination (target) when a put into memory ends */ tag = (unsigned char) (ev.hdr_data); btl_base_descriptor.des_segments = seg; btl_base_descriptor.des_segment_count = 1; seg[0].seg_addr.pval = ev.start; seg[0].seg_len = ev.mlength; reg = mca_btl_base_active_message_trigger + tag; OPAL_OUTPUT_VERBOSE((50, opal_btl_base_framework.framework_output, "PTL_EVENT_PUT: tag=%x base_descriptor=%p cbfunc: %lx\n", tag, (void*)&btl_base_descriptor, (uint64_t)reg->cbfunc)); reg->cbfunc(&portals4_btl->super, tag, &btl_base_descriptor, reg->cbdata); goto done; break; case PTL_EVENT_PUT_OVERFLOW: /* */ OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_OVERFLOW received\n")); goto done; break; case PTL_EVENT_LINK: /* */ frag = ev.user_ptr; if (NULL == frag) { opal_output(opal_btl_base_framework.framework_output, "btl/portals4: PTL_EVENT_LINK event with NULL user_ptr"); break; } goto done; break; case PTL_EVENT_AUTO_UNLINK: /* */ /* The Priority List is used, so PTL_EVENT_AUTO_FREE will never be received. So, we have to reactivate the block here */ mca_btl_portals4_activate_block(ev.user_ptr); goto done; break; case PTL_EVENT_AUTO_FREE: /* */ goto done; break; case PTL_EVENT_GET: /* Generated on source (target) when a get from memory ends */ /* */ OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_GET received at target rlength=%ld mlength=%ld\n", ev.rlength, ev.mlength)); goto done; break; case PTL_EVENT_REPLY: /* */ frag = ev.user_ptr; if (PTL_NI_PERM_VIOLATION == ev.ni_fail_type) { opal_output_verbose(1, opal_btl_base_framework.framework_output, "Warning : PTL_EVENT_REPLY with PTL_NI_PERM_VIOLATION received, try to re-issue a PtlGet"); /* The distant PtlMEAppend is not finished (distant PTL_EVENT_LINK not received) */ /* Re-issue the PtlGet (see btl_portals4_rdma.c) */ ret = PtlGet(frag->md_h, 0, frag->length, frag->peer_proc, portals4_btl->recv_idx, frag->match_bits, /* match bits */ 0, frag); if (OPAL_UNLIKELY(PTL_OK != ret)) { opal_output_verbose(1, opal_btl_base_framework.framework_output, "%s:%d: Re-issued PtlGet failed: %d", __FILE__, __LINE__, ret); PtlMDRelease(frag->md_h); frag->md_h = PTL_INVALID_HANDLE; return OPAL_ERROR; } OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Re-issued PtlGet length=%ld recv_idx=%d rank=%x pid=%x nid=%x match_bits=%lx\n", frag->length, portals4_btl->recv_idx, frag->peer_proc.rank, frag->peer_proc.phys.pid, frag->peer_proc.phys.nid, frag->match_bits)); } else { OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_REPLY: Call to rdma_cbfunc=%lx\n", (uint64_t)frag->rdma_cb.func)); frag->rdma_cb.func(&portals4_btl->super, frag->endpoint, ev.start, frag->rdma_cb.local_handle, frag->rdma_cb.context, frag->rdma_cb.data, OPAL_SUCCESS); PtlMDRelease(frag->md_h); frag->md_h = PTL_INVALID_HANDLE; OPAL_BTL_PORTALS4_FRAG_RETURN_USER(&portals4_btl->super, frag); OPAL_THREAD_ADD32(&portals4_btl->portals_outstanding_ops, -1); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PTL_EVENT_REPLY: Decrementing portals_outstanding_ops=%d\n", portals4_btl->portals_outstanding_ops)); goto done; } break; default: /* */ goto done; break; } } else if (PTL_EQ_EMPTY == ret) { /* there's nothing in the queue. This is actually the common case, so the easiest way to make the compiler emit something that doesn't completely blow here is to just go back to a good old goto */ goto done; break; } else if (PTL_EQ_DROPPED == ret) { opal_output(opal_btl_base_framework.framework_output, "Flow control situation without recovery (EQ_DROPPED)"); break; } else { opal_output(opal_btl_base_framework.framework_output, "Error returned from PtlEQPoll: %d", ret); break; } } done: return num_progressed; }
int main(int argc, char *argv[]) { ptl_handle_ni_t ni_h; ptl_pt_index_t pt_index; uint64_t *buf; ENTRY_T entry; HANDLE_T entry_h; ptl_md_t md; ptl_handle_md_t md_h; int rank; int num_procs; int ret; ptl_process_t *procs; ptl_handle_eq_t eq_h; ptl_event_t ev; ptl_hdr_data_t rcvd = 0; ptl_hdr_data_t goal = 0; ptl_hdr_data_t hdr_data = 1; ptl_size_t offset = sizeof(uint64_t); uint32_t distance; int sends = 0; CHECK_RETURNVAL(PtlInit()); CHECK_RETURNVAL(libtest_init()); rank = libtest_get_rank(); num_procs = libtest_get_size(); /* This test only succeeds if we have more than one rank */ if (num_procs < 2) return 77; CHECK_RETURNVAL(PtlNIInit(PTL_IFACE_DEFAULT, NI_TYPE | PTL_NI_LOGICAL, PTL_PID_ANY, NULL, NULL, &ni_h)); procs = libtest_get_mapping(ni_h); CHECK_RETURNVAL(PtlSetMap(ni_h, num_procs, procs)); CHECK_RETURNVAL(PtlEQAlloc(ni_h, 1024, &eq_h)); CHECK_RETURNVAL(PtlPTAlloc(ni_h, 0, eq_h, 0, &pt_index)); assert(pt_index == 0); buf = malloc(sizeof(uint64_t) * num_procs); assert(NULL != buf); md.start = buf; md.length = sizeof(uint64_t) * num_procs; md.options = PTL_MD_UNORDERED; md.eq_handle = eq_h; md.ct_handle = PTL_CT_NONE; CHECK_RETURNVAL(PtlMDBind(ni_h, &md, &md_h)); entry.start = buf; entry.length = sizeof(uint64_t) * num_procs; entry.ct_handle = PTL_CT_NONE; entry.uid = PTL_UID_ANY; entry.options = OPTIONS; #if MATCHING == 1 entry.match_id.rank = PTL_RANK_ANY; entry.match_bits = 0; entry.ignore_bits = 0; entry.min_free = 0; #endif CHECK_RETURNVAL(APPEND(ni_h, pt_index, &entry, PTL_PRIORITY_LIST, NULL, &entry_h)); /* ensure ME is linked before the barrier */ CHECK_RETURNVAL(PtlEQWait(eq_h, &ev)); assert( ev.type == PTL_EVENT_LINK ); libtest_barrier(); /* Bruck's Concatenation Algorithm */ memcpy(buf, &rank, sizeof(uint64_t)); for (distance = 1; distance < num_procs; distance *= 2) { ptl_size_t to_xfer; int peer; ptl_process_t proc; if (rank >= distance) { peer = rank - distance; } else { peer = rank + (num_procs - distance); } to_xfer = sizeof(uint64_t) * MIN(distance, num_procs - distance); proc.rank = peer; CHECK_RETURNVAL(PtlPut(md_h, 0, to_xfer, PTL_NO_ACK_REQ, proc, 0, 0, offset, NULL, hdr_data)); sends += 1; /* wait for completion of the proper receive, and keep count of uncompleted sends. "rcvd" is an accumulator to deal with out-of-order receives, which are IDed by the hdr_data */ goal |= hdr_data; while ((rcvd & goal) != goal) { ret = PtlEQWait(eq_h, &ev); switch (ret) { case PTL_OK: if (ev.type == PTL_EVENT_SEND) { sends -= 1; } else { rcvd |= ev.hdr_data; assert(ev.type == PTL_EVENT_PUT); assert(ev.rlength == ev.mlength); assert((ev.rlength == to_xfer) || (ev.hdr_data != hdr_data)); } break; default: fprintf(stderr, "PtlEQWait failure: %d\n", ret); abort(); } } hdr_data <<= 1; offset += to_xfer; } /* wait for any SEND_END events not yet seen */ while (sends) { ret = PtlEQWait(eq_h, &ev); switch (ret) { case PTL_OK: assert( ev.type == PTL_EVENT_SEND ); sends -= 1; break; default: fprintf(stderr, "PtlEQWait failure: %d\n", ret); abort(); } } CHECK_RETURNVAL(UNLINK(entry_h)); CHECK_RETURNVAL(PtlMDRelease(md_h)); free(buf); libtest_barrier(); /* cleanup */ CHECK_RETURNVAL(PtlPTFree(ni_h, pt_index)); CHECK_RETURNVAL(PtlEQFree(eq_h)); CHECK_RETURNVAL(PtlNIFini(ni_h)); CHECK_RETURNVAL(libtest_fini()); PtlFini(); return 0; }
void CleanUp(ArgStruct *p) { int rc; /* Free all CTs */ rc= PtlCTFree(send_ct_handle); LIBTEST_CHECK(rc, "PtlCTFree(send_ct_handle) in CleanUp"); rc= PtlCTFree(send_int_ct_handle); LIBTEST_CHECK(rc, "PtlCTFree(send_int_ct_handle) in CleanUp"); rc= PtlCTFree(send_double_ct_handle); LIBTEST_CHECK(rc, "PtlCTFree(send_double_ct_handle) in CleanUp"); rc= PtlCTFree(recv_ct_handle); LIBTEST_CHECK(rc, "PtlCTFree(recv_ct_handle) in CleanUp"); rc= PtlCTFree(recv_int_ct_handle); LIBTEST_CHECK(rc, "PtlCTFree(recv_int_ct_handle) in CleanUp"); rc= PtlCTFree(recv_double_ct_handle); LIBTEST_CHECK(rc, "PtlCTFree(recv_double_ct_handle) in CleanUp"); /* Free all MDs */ rc= PtlMDRelease(md_handle); LIBTEST_CHECK(rc, "PtlMDRelease(md_handle) in CleanUp"); rc= PtlMDRelease(send_int_md_handle); LIBTEST_CHECK(rc, "PtlMDRelease (send_int_md_handle) in CleanUp"); rc= PtlMDRelease(send_double_md_handle); LIBTEST_CHECK(rc, "PtlMDRelease (send_double_md_handle) in CleanUp"); /* Free all LEs */ rc= PtlLEUnlink(le_handle); LIBTEST_CHECK(rc, "PtlLEUnlink(le_handle) in CleanUp"); rc= PtlLEUnlink(recv_int_le_handle); LIBTEST_CHECK(rc, "PtlLEUnlink(recv_int_le_handle) in CleanUp"); rc= PtlLEUnlink(recv_double_le_handle); LIBTEST_CHECK(rc, "PtlLEUnlink(recv_double_le_handle) in CleanUp"); /* Free the Portal table entries we used */ rc= PtlPTFree(ni_logical, PTL_XMIT_INDEX); LIBTEST_CHECK(rc, "PtlPTFree(PTL_XMIT_INDEX) in CleanUp"); rc= PtlPTFree(ni_logical, PTL_SEND_INT_INDEX); LIBTEST_CHECK(rc, "PtlPTFree(PTL_SEND_INT_INDEX) in CleanUp"); rc= PtlPTFree(ni_logical, PTL_SEND_DOUBLE_INDEX); LIBTEST_CHECK(rc, "PtlPTFree(PTL_SEND_DOUBLE_INDEX) in CleanUp"); /* Almost done */ PtlNIFini(ni_logical); PtlFini(); } /* end of CleanUp() */
/* called when a receive should be progressed */ static int ompi_mtl_portals4_recv_progress(ptl_event_t *ev, ompi_mtl_portals4_base_request_t* ptl_base_request) { int ret; ompi_mtl_portals4_recv_request_t* ptl_request = (ompi_mtl_portals4_recv_request_t*) ptl_base_request; size_t msg_length = 0; /* as soon as we've seen any event associated with a request, it's started */ ptl_request->req_started = true; switch (ev->type) { case PTL_EVENT_PUT: OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) got put event", ptl_request->opcount, ev->hdr_data)); if (ev->ni_fail_type != PTL_NI_OK) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PTL_EVENT_PUT with ni_fail_type: %d", __FILE__, __LINE__, ev->ni_fail_type); goto callback_error; } ptl_request->me_h = PTL_INVALID_HANDLE; msg_length = MTL_PORTALS4_GET_LENGTH(ev->hdr_data); ptl_request->super.super.ompi_req->req_status.MPI_SOURCE = MTL_PORTALS4_GET_SOURCE(ev->match_bits); ptl_request->super.super.ompi_req->req_status.MPI_TAG = MTL_PORTALS4_GET_TAG(ev->match_bits); if (OPAL_UNLIKELY(msg_length > ptl_request->delivery_len)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "truncate expected: %ld %ld", msg_length, ptl_request->delivery_len); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = MPI_ERR_TRUNCATE; } #if OPAL_ENABLE_DEBUG ptl_request->hdr_data = ev->hdr_data; #endif if (!MTL_PORTALS4_IS_SHORT_MSG(ev->match_bits) && ompi_mtl_portals4.protocol == rndv) { /* If it's not a short message and we're doing rndv, we only have the first part of the message. Issue the get to pull the second part of the message. */ ret = read_msg((char*) ptl_request->delivery_ptr + ompi_mtl_portals4.eager_limit, ((msg_length > ptl_request->delivery_len) ? ptl_request->delivery_len : msg_length) - ompi_mtl_portals4.eager_limit, ev->initiator, ev->hdr_data, ompi_mtl_portals4.eager_limit, ptl_request); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); goto callback_error; } } else { /* If we're either using the eager protocol or were a short message, all data has been received, so complete the message. */ ret = ompi_mtl_datatype_unpack(ptl_request->convertor, ev->start, ev->mlength); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: ompi_mtl_datatype_unpack failed: %d", __FILE__, __LINE__, ret); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = ret; } ptl_request->super.super.ompi_req->req_status._ucount = ev->mlength; OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) completed, expected", ptl_request->opcount, ptl_request->hdr_data)); ptl_request->super.super.completion_callback(&ptl_request->super.super); } break; case PTL_EVENT_REPLY: OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) got reply event", ptl_request->opcount, ptl_request->hdr_data)); if (OPAL_UNLIKELY(ev->ni_fail_type != PTL_NI_OK)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PTL_EVENT_REPLY with ni_fail_type: %d", __FILE__, __LINE__, ev->ni_fail_type); PtlMDRelease(ptl_request->md_h); goto callback_error; } /* set the received length in the status, now that we know excatly how much data was sent. */ ptl_request->super.super.ompi_req->req_status._ucount = ev->mlength; if (ompi_mtl_portals4.protocol == rndv) { ptl_request->super.super.ompi_req->req_status._ucount += ompi_mtl_portals4.eager_limit; } #if OMPI_MTL_PORTALS4_FLOW_CONTROL OPAL_THREAD_ADD32(&ompi_mtl_portals4.flowctl.send_slots, 1); #endif /* make sure the data is in the right place. Use _ucount for the total length because it will be set correctly for all three protocols. mlength is only correct for eager, and delivery_len is the length of the buffer, not the length of the send. */ ret = ompi_mtl_datatype_unpack(ptl_request->convertor, ptl_request->delivery_ptr, ptl_request->super.super.ompi_req->req_status._ucount); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: ompi_mtl_datatype_unpack failed: %d", __FILE__, __LINE__, ret); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = ret; } PtlMDRelease(ptl_request->md_h); OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) completed, reply", ptl_request->opcount, ptl_request->hdr_data)); ptl_request->super.super.completion_callback(&ptl_request->super.super); break; case PTL_EVENT_PUT_OVERFLOW: OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) got put_overflow event", ptl_request->opcount, ev->hdr_data)); if (OPAL_UNLIKELY(ev->ni_fail_type != PTL_NI_OK)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PTL_EVENT_PUT_OVERFLOW with ni_fail_type: %d", __FILE__, __LINE__, ev->ni_fail_type); goto callback_error; } ptl_request->me_h = PTL_INVALID_HANDLE; msg_length = MTL_PORTALS4_GET_LENGTH(ev->hdr_data); ptl_request->super.super.ompi_req->req_status.MPI_SOURCE = MTL_PORTALS4_GET_SOURCE(ev->match_bits); ptl_request->super.super.ompi_req->req_status.MPI_TAG = MTL_PORTALS4_GET_TAG(ev->match_bits); if (OPAL_UNLIKELY(msg_length > ptl_request->delivery_len)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "truncate unexpected: %ld %ld %d", msg_length, ptl_request->delivery_len, MTL_PORTALS4_IS_SHORT_MSG(ev->match_bits)); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = MPI_ERR_TRUNCATE; } #if OPAL_ENABLE_DEBUG ptl_request->hdr_data = ev->hdr_data; #endif /* overflow case. Short messages have the buffer stashed somewhere. Long messages left in buffer at the source */ if (MTL_PORTALS4_IS_SHORT_MSG(ev->match_bits)) { ptl_request->super.super.ompi_req->req_status._ucount = ev->mlength; if (ev->mlength > 0) { struct iovec iov; uint32_t iov_count = 1; size_t max_data; iov.iov_base = (char*) ev->start; iov.iov_len = ev->mlength; max_data = iov.iov_len; ret = opal_convertor_unpack(ptl_request->convertor, &iov, &iov_count, &max_data ); if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); if (OPAL_UNLIKELY(ret < 0)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: opal_convertor_unpack failed: %d", __FILE__, __LINE__, ret); goto callback_error; } } /* if it's a sync, send the ack */ if (MTL_PORTALS4_IS_SYNC_MSG(ev->hdr_data)) { OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) sending sync ack", ptl_request->opcount, ptl_request->hdr_data)); ret = PtlPut(ompi_mtl_portals4.zero_md_h, 0, 0, PTL_NO_ACK_REQ, ev->initiator, ompi_mtl_portals4.read_idx, ev->hdr_data, 0, NULL, 0); if (OPAL_UNLIKELY(PTL_OK != ret)) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlPut failed: %d", __FILE__, __LINE__, ret); goto callback_error; } } OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output, "Recv %lu (0x%lx) completed, unexpected short (0x%lx)", ptl_request->opcount, ptl_request->hdr_data, (long) ev->start)); ptl_request->super.super.completion_callback(&ptl_request->super.super); } else { if (ev->mlength > 0) { /* if rndv or triggered, copy the eager part to the right place */ memcpy(ptl_request->delivery_ptr, ev->start, ev->mlength); } ret = read_msg((char*) ptl_request->delivery_ptr + ev->mlength, ((msg_length > ptl_request->delivery_len) ? ptl_request->delivery_len : msg_length) - ev->mlength, ev->initiator, ev->hdr_data, ev->mlength, ptl_request); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); goto callback_error; } } break; case PTL_EVENT_LINK: break; default: opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "Unhandled receive callback with event type %d", ev->type); return OMPI_ERROR; } return OMPI_SUCCESS; callback_error: ptl_request->super.super.ompi_req->req_status.MPI_ERROR = ompi_mtl_portals4_get_error(ret); ptl_request->super.super.completion_callback(&ptl_request->super.super); return OMPI_SUCCESS; }
int mca_btl_portals4_get(struct mca_btl_base_module_t* btl_base, struct mca_btl_base_endpoint_t* btl_peer, void *local_address, uint64_t remote_address, struct mca_btl_base_registration_handle_t *local_handle, struct mca_btl_base_registration_handle_t *remote_handle, size_t size, int flags, int order, mca_btl_base_rdma_completion_fn_t cbfunc, void *cbcontext, void *cbdata) { mca_btl_portals4_module_t *portals4_btl = (mca_btl_portals4_module_t *) btl_base; mca_btl_portals4_frag_t *frag = NULL; ptl_md_t md; int ret; /* reserve space in the event queue for rdma operations immediately */ while (OPAL_THREAD_ADD32(&portals4_btl->portals_outstanding_ops, 1) > portals4_btl->portals_max_outstanding_ops) { OPAL_THREAD_ADD32(&portals4_btl->portals_outstanding_ops, -1); OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Call to mca_btl_portals4_component_progress (1)\n")); mca_btl_portals4_component_progress(); } OPAL_BTL_PORTALS4_FRAG_ALLOC_USER(portals4_btl, frag); if (NULL == frag){ OPAL_THREAD_ADD32(&portals4_btl->portals_outstanding_ops, -1); return OPAL_ERROR; } OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "mca_btl_portals4_get: Incrementing portals_outstanding_ops=%d frag=%p", portals4_btl->portals_outstanding_ops, (void *)frag)); frag->rdma_cb.func = cbfunc; frag->rdma_cb.context = cbcontext; frag->rdma_cb.data = cbdata; frag->rdma_cb.local_handle = local_handle; frag->endpoint = btl_peer; frag->hdr.tag = MCA_BTL_TAG_MAX; /* Bind the memory */ md.start = (void *)local_address; md.length = size; md.options = 0; md.eq_handle = portals4_btl->recv_eq_h; md.ct_handle = PTL_CT_NONE; ret = PtlMDBind(portals4_btl->portals_ni_h, &md, &frag->md_h); if (OPAL_UNLIKELY(PTL_OK != ret)) { opal_output_verbose(1, opal_btl_base_framework.framework_output, "%s:%d: PtlMDBind failed: %d", __FILE__, __LINE__, ret); return OPAL_ERROR; } frag->match_bits = remote_handle->key; frag->length = md.length; frag->peer_proc = btl_peer->ptl_proc; OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlGet start=%p length=%ld nid=%x pid=%x match_bits=%lx\n", md.start, md.length, btl_peer->ptl_proc.phys.nid, btl_peer->ptl_proc.phys.pid, frag->match_bits)); ret = PtlGet(frag->md_h, 0, md.length, btl_peer->ptl_proc, portals4_btl->recv_idx, frag->match_bits, /* match bits */ 0, frag); if (OPAL_UNLIKELY(PTL_OK != ret)) { opal_output_verbose(1, opal_btl_base_framework.framework_output, "%s:%d: PtlGet failed: %d", __FILE__, __LINE__, ret); PtlMDRelease(frag->md_h); frag->md_h = PTL_INVALID_HANDLE; return OPAL_ERROR; } OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "SUCCESS: PtlGet start=%p length=%ld nid=%x pid=%x match_bits=%lx\n", md.start, md.length, btl_peer->ptl_proc.phys.nid, btl_peer->ptl_proc.phys.pid, frag->match_bits)); return OPAL_SUCCESS; }
int main(int argc, char *argv[]) { ptl_handle_ni_t ni_handle; ptl_process_t *procs; int rank; ptl_pt_index_t pt_index, signal_pt_index; HANDLE_T value_e_handle, signal_e_handle; int num_procs; ptl_handle_eq_t eq_handle; ptl_handle_ct_t ct_handle; ptl_handle_md_t md_handle; CHECK_RETURNVAL(PtlInit()); CHECK_RETURNVAL(libtest_init()); rank = libtest_get_rank(); num_procs = libtest_get_size(); if (num_procs < 2) { fprintf(stderr, "test_flowctl_noeq requires at least two processes\n"); return 77; } CHECK_RETURNVAL(PtlNIInit(PTL_IFACE_DEFAULT, NI_TYPE | PTL_NI_LOGICAL, PTL_PID_ANY, NULL, NULL, &ni_handle)); procs = libtest_get_mapping(ni_handle); CHECK_RETURNVAL(PtlSetMap(ni_handle, num_procs, procs)); if (0 == rank) { ENTRY_T value_e; /* create data ME */ CHECK_RETURNVAL(PtlEQAlloc(ni_handle, (num_procs - 1) * ITERS / 2, &eq_handle)); CHECK_RETURNVAL(PtlPTAlloc(ni_handle, PTL_PT_FLOWCTRL, eq_handle, 5, &pt_index)); value_e.start = NULL; value_e.length = 0; value_e.ct_handle = PTL_CT_NONE; value_e.uid = PTL_UID_ANY; value_e.options = OPTIONS; #if INTERFACE == 1 value_e.match_id.rank = PTL_RANK_ANY; value_e.match_bits = 0; value_e.ignore_bits = 0; #endif CHECK_RETURNVAL(APPEND(ni_handle, 5, &value_e, PTL_PRIORITY_LIST, NULL, &value_e_handle)); /* create signal ME */ CHECK_RETURNVAL(PtlCTAlloc(ni_handle, &ct_handle)); CHECK_RETURNVAL(PtlPTAlloc(ni_handle, 0, PTL_EQ_NONE, 6, &signal_pt_index)); value_e.start = NULL; value_e.length = 0; value_e.ct_handle = ct_handle; value_e.uid = PTL_UID_ANY; value_e.options = OPTIONS | PTL_LE_EVENT_SUCCESS_DISABLE | PTL_LE_EVENT_CT_COMM; #if INTERFACE == 1 value_e.match_id.rank = PTL_RANK_ANY; value_e.match_bits = 0; value_e.ignore_bits = 0; #endif CHECK_RETURNVAL(APPEND(ni_handle, 6, &value_e, PTL_PRIORITY_LIST, NULL, &signal_e_handle)); } else { ptl_md_t md; /* 16 extra just in case... */ CHECK_RETURNVAL(PtlEQAlloc(ni_handle, ITERS * 2 + 16, &eq_handle)); md.start = NULL; md.length = 0; md.options = 0; md.eq_handle = eq_handle; md.ct_handle = PTL_CT_NONE; CHECK_RETURNVAL(PtlMDBind(ni_handle, &md, &md_handle)); } libtest_barrier(); if (0 == rank) { ptl_ct_event_t ct; ptl_event_t ev; int ret, count = 0, saw_dropped = 0, saw_flowctl = 0; /* wait for signal counts */ CHECK_RETURNVAL(PtlCTWait(ct_handle, num_procs - 1, &ct)); if (ct.success != num_procs - 1 || ct.failure != 0) { return 1; } /* wait for event entries */ while (count < ITERS * (num_procs - 1)) { ret = PtlEQWait(eq_handle, &ev); if (PTL_OK == ret) { ; } else if (PTL_EQ_DROPPED == ret) { saw_dropped++; if (ev.type == PTL_EVENT_PT_DISABLED){ saw_flowctl++; CHECK_RETURNVAL(PtlPTEnable(ni_handle, pt_index)); } break; } else { fprintf(stderr, "0: Unexpected return code from EQWait: %d\n", ret); return 1; } if (ev.type == PTL_EVENT_PT_DISABLED) { CHECK_RETURNVAL(PtlPTEnable(ni_handle, pt_index)); saw_flowctl++; } else { count++; } } fprintf(stderr, "0: Saw %d dropped, %d flowctl\n", saw_dropped, saw_flowctl); if (saw_flowctl == 0) { return 1; } } else { ptl_process_t target; ptl_event_t ev; int ret, count = 0, fails = 0; int i; int *fail_seen; fail_seen = malloc(sizeof(int) * ITERS); if (NULL == fail_seen) { fprintf(stderr, "%d: malloc failed\n", rank); return 1; } memset(fail_seen, 0, sizeof(int) * ITERS); target.rank = 0; for (i = 0 ; i < ITERS ; ++i) { CHECK_RETURNVAL(PtlPut(md_handle, 0, 0, PTL_ACK_REQ, target, 5, 0, 0, (void*)(size_t)i, 0)); usleep(100); } while (count < ITERS) { ret = PtlEQGet(eq_handle, &ev); if (PTL_EQ_EMPTY == ret) { continue; } else if (PTL_OK != ret) { fprintf(stderr, "%d: PtlEQGet returned %d\n", rank, ret); return 1; } if (ev.ni_fail_type == PTL_NI_OK) { if (ev.type == PTL_EVENT_SEND) { continue; } else if (ev.type == PTL_EVENT_ACK) { count++; } else { fprintf(stderr, "%d: Unexpected event type %d\n", rank, ev.type); } } else if (ev.ni_fail_type == PTL_NI_PT_DISABLED) { int iter = (size_t) ev.user_ptr; if (fail_seen[iter]++ > 0) { fprintf(stderr, "%d: Double report of PT_DISABLED for " "iteration %d\n", rank, iter); return 1; } count++; fails++; } else { fprintf(stderr, "%d: Unexpected fail type: %d\n", rank, ev.ni_fail_type); return 1; } } fprintf(stderr, "%d: Saw %d of %d events as fails\n", rank, fails, count); CHECK_RETURNVAL(PtlPut(md_handle, 0, 0, PTL_NO_ACK_REQ, target, 6, 0, 0, NULL, 0)); /* wait for the send event on the last put */ CHECK_RETURNVAL(PtlEQWait(eq_handle, &ev)); while (fails > 0) { CHECK_RETURNVAL(PtlPut(md_handle, 0, 0, PTL_ACK_REQ, target, 5, 0, 0, NULL, 0)); while (1) { ret = PtlEQWait(eq_handle, &ev); if (PTL_OK != ret) { fprintf(stderr, "%d: PtlEQWait returned %d\n", rank, ret); return 1; } if (ev.ni_fail_type == PTL_NI_OK) { if (ev.type == PTL_EVENT_SEND) { continue; } else if (ev.type == PTL_EVENT_ACK) { fails--; break; } else { fprintf(stderr, "%d: Unexpected event type %d\n", rank, ev.type); } } else if (ev.ni_fail_type == PTL_NI_PT_DISABLED) { break; } else { fprintf(stderr, "%d: Unexpected fail type: %d\n", rank, ev.ni_fail_type); return 1; } } } } libtest_barrier(); if (0 == rank) { CHECK_RETURNVAL(UNLINK(signal_e_handle)); CHECK_RETURNVAL(PtlPTFree(ni_handle, signal_pt_index)); CHECK_RETURNVAL(PtlCTFree(ct_handle)); CHECK_RETURNVAL(UNLINK(value_e_handle)); CHECK_RETURNVAL(PtlPTFree(ni_handle, pt_index)); CHECK_RETURNVAL(PtlEQFree(eq_handle)); } else { CHECK_RETURNVAL(PtlMDRelease(md_handle)); CHECK_RETURNVAL(PtlEQFree(eq_handle)); } CHECK_RETURNVAL(PtlNIFini(ni_handle)); CHECK_RETURNVAL(libtest_fini()); PtlFini(); return 0; }
static void cleanup_handles(void) { if (!PtlHandleIsEqual(shmem_transport_portals4_get_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(shmem_transport_portals4_get_md_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_put_event_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(shmem_transport_portals4_put_event_md_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_put_volatile_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(shmem_transport_portals4_put_volatile_md_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_put_cntr_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(shmem_transport_portals4_put_cntr_md_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_get_ct_h, PTL_INVALID_HANDLE)) { PtlCTFree(shmem_transport_portals4_get_ct_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_put_ct_h, PTL_INVALID_HANDLE)) { PtlCTFree(shmem_transport_portals4_put_ct_h); } #ifdef ENABLE_REMOTE_VIRTUAL_ADDRESSING if (!PtlHandleIsEqual(shmem_transport_portals4_le_h, PTL_INVALID_HANDLE)) { PtlLEUnlink(shmem_transport_portals4_le_h); } #else if (!PtlHandleIsEqual(shmem_transport_portals4_heap_le_h, PTL_INVALID_HANDLE)) { PtlLEUnlink(shmem_transport_portals4_heap_le_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_data_le_h, PTL_INVALID_HANDLE)) { PtlLEUnlink(shmem_transport_portals4_data_le_h); } #endif #ifndef ENABLE_HARD_POLLING if (!PtlHandleIsEqual(shmem_transport_portals4_target_ct_h, PTL_INVALID_HANDLE)) { PtlCTFree(shmem_transport_portals4_target_ct_h); } #endif #ifdef ENABLE_REMOTE_VIRTUAL_ADDRESSING if (PTL_PT_ANY != all_pt) { PtlPTFree(shmem_transport_portals4_ni_h, all_pt); } #else if (PTL_PT_ANY != heap_pt) { PtlPTFree(shmem_transport_portals4_ni_h, heap_pt); } if (PTL_PT_ANY != data_pt) { PtlPTFree(shmem_transport_portals4_ni_h, data_pt); } #endif if (!PtlHandleIsEqual(shmem_transport_portals4_eq_h, PTL_INVALID_HANDLE)) { PtlEQFree(shmem_transport_portals4_eq_h); } if (!PtlHandleIsEqual(shmem_transport_portals4_ni_h, PTL_INVALID_HANDLE)) { PtlNIFini(shmem_transport_portals4_ni_h); } if (NULL != shmem_transport_portals4_bounce_buffers) { shmem_free_list_destroy(shmem_transport_portals4_bounce_buffers); } if (NULL != shmem_transport_portals4_long_frags) { shmem_free_list_destroy(shmem_transport_portals4_long_frags); } }
void test_prepostME(int cache_size, int *cache_buf, ptl_handle_ni_t ni, int npeers, int nmsgs, int nbytes, int niters) { int i, j, k; double tmp, total = 0; ptl_handle_md_t send_md_handle; ptl_md_t send_md; ptl_process_t dest; ptl_size_t offset; ptl_pt_index_t index; ptl_handle_eq_t recv_eq_handle; ptl_handle_me_t me_handles[npeers * nmsgs]; ptl_event_t event; ptl_assert(PtlEQAlloc(ni, nmsgs * npeers + 1, &send_md.eq_handle), PTL_OK); send_md.start = send_buf; send_md.length = SEND_BUF_SIZE; send_md.options = PTL_MD_UNORDERED; send_md.ct_handle = PTL_CT_NONE; ptl_assert(PtlMDBind(ni, &send_md, &send_md_handle), PTL_OK); ptl_assert(PtlEQAlloc(ni, nmsgs * npeers + 1, &recv_eq_handle), PTL_OK); ptl_assert(PtlPTAlloc(ni, 0, recv_eq_handle, TestSameDirectionIndex, &index), PTL_OK); ptl_assert(TestSameDirectionIndex, index); tmp = timer(); for (j = 0; j < npeers; ++j) { for (k = 0; k < nmsgs; ++k) { ptl_process_t src; src.rank = recv_peers[j]; postME(ni, index, recv_buf + (nbytes * (k + j * nmsgs)), nbytes, src, magic_tag, &me_handles[k + j * nmsgs]); } } total += (timer() - tmp); for (i = 0; i < niters - 1; ++i) { cache_invalidate(cache_size, cache_buf); libtest_Barrier(); tmp = timer(); for (j = 0; j < npeers; ++j) { for (k = 0; k < nmsgs; ++k) { offset = (nbytes * (k + j * nmsgs)); dest.rank = send_peers[npeers - j - 1], ptl_assert(libtest_Put_offset(send_md_handle, offset, nbytes, dest, index, magic_tag, offset), PTL_OK); } } /* wait for sends */ for (j = 0; j < npeers * nmsgs; ++j) { ptl_assert(PtlEQWait(send_md.eq_handle, &event), PTL_OK); ptl_assert(event.type, PTL_EVENT_SEND); } /* wait for receives */ for (j = 0; j < npeers * nmsgs; j++) { PtlEQWait(recv_eq_handle, &event); } for (j = 0; j < npeers; ++j) { for (k = 0; k < nmsgs; ++k) { ptl_process_t src; src.rank = recv_peers[j]; postME(ni, index, recv_buf + (nbytes * (k + j * nmsgs)), nbytes, src, magic_tag, &me_handles[k + j * nmsgs]); } } total += (timer() - tmp); } libtest_Barrier(); tmp = timer(); for (j = 0; j < npeers; ++j) { for (k = 0; k < nmsgs; ++k) { offset = (nbytes * (k + j * nmsgs)); dest.rank = send_peers[npeers - j - 1], ptl_assert(libtest_Put_offset(send_md_handle, offset, nbytes, dest, index, magic_tag, offset), PTL_OK); } } /* wait for sends */ for (j = 0; j < npeers * nmsgs; ++j) { ptl_assert(PtlEQWait(send_md.eq_handle, &event), PTL_OK); ptl_assert(event.type, PTL_EVENT_SEND); } /* wait for receives */ for (j = 0; j < npeers * nmsgs; j++) { PtlEQWait(recv_eq_handle, &event); } total += (timer() - tmp); ptl_assert(PtlEQFree(send_md.eq_handle), PTL_OK); ptl_assert(PtlMDRelease(send_md_handle), PTL_OK); ptl_assert(PtlEQFree(recv_eq_handle), PTL_OK); ptl_assert(PtlPTFree(ni, index), PTL_OK); tmp = libtest_AllreduceDouble(total, PTL_SUM); display_result("pre-post", (niters * npeers * nmsgs * 2) / (tmp / world_size)); }
static int component_select(struct ompi_win_t *win, void **base, size_t size, int disp_unit, struct ompi_communicator_t *comm, struct ompi_info_t *info, int flavor, int *model) { ompi_osc_portals4_module_t *module = NULL; int ret = OMPI_ERROR; int tmp; ptl_md_t md; ptl_me_t me; char *name; if (MPI_WIN_FLAVOR_SHARED == flavor) return OMPI_ERR_NOT_SUPPORTED; /* create module structure */ module = (ompi_osc_portals4_module_t*) calloc(1, sizeof(ompi_osc_portals4_module_t)); if (NULL == module) return OMPI_ERR_TEMP_OUT_OF_RESOURCE; /* fill in the function pointer part */ memcpy(module, &ompi_osc_portals4_module_template, sizeof(ompi_osc_base_module_t)); /* fill in our part */ if (MPI_WIN_FLAVOR_ALLOCATE == flavor) { module->free_after = *base = malloc(size); if (NULL == *base) goto error; } else { module->free_after = NULL; } ret = ompi_comm_dup(comm, &module->comm); if (OMPI_SUCCESS != ret) goto error; opal_output_verbose(1, ompi_osc_base_framework.framework_output, "portals4 component creating window with id %d", ompi_comm_get_cid(module->comm)); asprintf(&name, "portals4 window %d", ompi_comm_get_cid(module->comm)); ompi_win_set_name(win, name); free(name); /* share everyone's displacement units. Only do an allgather if strictly necessary, since it requires O(p) state. */ tmp = disp_unit; ret = module->comm->c_coll.coll_bcast(&tmp, 1, MPI_INT, 0, module->comm, module->comm->c_coll.coll_bcast_module); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: MPI_Bcast failed: %d\n", __FILE__, __LINE__, ret); goto error; } tmp = (tmp == disp_unit) ? 1 : 0; ret = module->comm->c_coll.coll_allreduce(MPI_IN_PLACE, &tmp, 1, MPI_INT, MPI_LAND, module->comm, module->comm->c_coll.coll_allreduce_module); if (OMPI_SUCCESS != ret) goto error; if (tmp == 1) { module->disp_unit = disp_unit; module->disp_units = NULL; } else { module->disp_unit = -1; module->disp_units = malloc(sizeof(int) * ompi_comm_size(module->comm)); ret = module->comm->c_coll.coll_allgather(&disp_unit, 1, MPI_INT, module->disp_units, 1, MPI_INT, module->comm, module->comm->c_coll.coll_allgather_module); if (OMPI_SUCCESS != ret) goto error; } module->ni_h = mca_osc_portals4_component.matching_ni_h; module->pt_idx = mca_osc_portals4_component.matching_pt_idx; ret = PtlCTAlloc(module->ni_h, &(module->ct_h)); if (PTL_OK != ret) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: PtlCTAlloc failed: %d\n", __FILE__, __LINE__, ret); goto error; } md.start = 0; md.length = PTL_SIZE_MAX; md.options = PTL_MD_EVENT_SUCCESS_DISABLE | PTL_MD_EVENT_CT_REPLY | PTL_MD_EVENT_CT_ACK; md.eq_handle = mca_osc_portals4_component.matching_eq_h; md.ct_handle = module->ct_h; ret = PtlMDBind(module->ni_h, &md, &module->md_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: PtlMDBind failed: %d\n", __FILE__, __LINE__, ret); goto error; } md.start = 0; md.length = PTL_SIZE_MAX; md.options = PTL_MD_EVENT_CT_REPLY | PTL_MD_EVENT_CT_ACK; md.eq_handle = mca_osc_portals4_component.matching_eq_h; md.ct_handle = module->ct_h; ret = PtlMDBind(module->ni_h, &md, &module->req_md_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: PtlMDBind failed: %d\n", __FILE__, __LINE__, ret); goto error; } if (MPI_WIN_FLAVOR_DYNAMIC == flavor) { me.start = 0; me.length = PTL_SIZE_MAX; } else { me.start = *base; me.length = size; } me.ct_handle = PTL_CT_NONE; me.uid = PTL_UID_ANY; me.options = PTL_ME_OP_PUT | PTL_ME_OP_GET | PTL_ME_NO_TRUNCATE | PTL_ME_EVENT_SUCCESS_DISABLE; me.match_id.phys.nid = PTL_NID_ANY; me.match_id.phys.pid = PTL_PID_ANY; me.match_bits = module->comm->c_contextid; me.ignore_bits = 0; ret = PtlMEAppend(module->ni_h, module->pt_idx, &me, PTL_PRIORITY_LIST, NULL, &module->data_me_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: PtlMEAppend failed: %d\n", __FILE__, __LINE__, ret); goto error; } me.start = &module->state; me.length = sizeof(module->state); me.ct_handle = PTL_CT_NONE; me.uid = PTL_UID_ANY; me.options = PTL_ME_OP_PUT | PTL_ME_OP_GET | PTL_ME_NO_TRUNCATE | PTL_ME_EVENT_SUCCESS_DISABLE; me.match_id.phys.nid = PTL_NID_ANY; me.match_id.phys.pid = PTL_PID_ANY; me.match_bits = module->comm->c_contextid | OSC_PORTALS4_MB_CONTROL; me.ignore_bits = 0; ret = PtlMEAppend(module->ni_h, module->pt_idx, &me, PTL_PRIORITY_LIST, NULL, &module->control_me_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "%s:%d: PtlMEAppend failed: %d\n", __FILE__, __LINE__, ret); goto error; } module->opcount = 0; module->match_bits = module->comm->c_contextid; module->atomic_max = (check_config_value_equal("accumulate_ordering", info, "none")) ? mca_osc_portals4_component.matching_atomic_max : MIN(mca_osc_portals4_component.matching_atomic_max, mca_osc_portals4_component.matching_atomic_ordered_size); module->fetch_atomic_max = (check_config_value_equal("accumulate_ordering", info, "none")) ? mca_osc_portals4_component.matching_fetch_atomic_max : MIN(mca_osc_portals4_component.matching_fetch_atomic_max, mca_osc_portals4_component.matching_atomic_ordered_size); module->zero = 0; module->one = 1; module->start_group = NULL; module->post_group = NULL; module->state.post_count = 0; module->state.complete_count = 0; if (check_config_value_bool("no_locks", info)) { module->state.lock = LOCK_ILLEGAL; } else { module->state.lock = LOCK_UNLOCKED; } OBJ_CONSTRUCT(&module->outstanding_locks, opal_list_t); module->passive_target_access_epoch = false; #if OPAL_ASSEMBLY_ARCH == OPAL_AMD64 || OPAL_ASSEMBLY_ARCH == OPAL_IA32 *model = MPI_WIN_UNIFIED; #else *model = MPI_WIN_SEPARATE; #endif win->w_osc_module = &module->super; PtlAtomicSync(); /* Make sure that everyone's ready to receive. */ module->comm->c_coll.coll_barrier(module->comm, module->comm->c_coll.coll_barrier_module); return OMPI_SUCCESS; error: /* BWB: FIX ME: This is all wrong... */ if (0 != module->ct_h) PtlCTFree(module->ct_h); if (0 != module->data_me_h) PtlMEUnlink(module->data_me_h); if (0 != module->req_md_h) PtlMDRelease(module->req_md_h); if (0 != module->md_h) PtlMDRelease(module->md_h); if (NULL != module->comm) ompi_comm_free(&module->comm); if (NULL != module) free(module); return ret; }
/* called when a receive should be progressed */ int ompi_mtl_portals4_recv_progress(ptl_event_t *ev, ompi_mtl_portals4_base_request_t* ptl_base_request) { int ret; ompi_mtl_portals4_recv_request_t* ptl_request = (ompi_mtl_portals4_recv_request_t*) ptl_base_request; size_t msg_length = 0; switch (ev->type) { case PTL_EVENT_PUT: OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) got put event", ptl_request->opcount, ev->hdr_data)); if (ev->ni_fail_type != PTL_NI_OK) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PTL_EVENT_PUT with ni_fail_type: %d", __FILE__, __LINE__, ev->ni_fail_type); goto callback_error; } msg_length = MTL_PORTALS4_GET_LENGTH(ev->hdr_data); ptl_request->super.super.ompi_req->req_status.MPI_SOURCE = MTL_PORTALS4_GET_SOURCE(ev->match_bits); ptl_request->super.super.ompi_req->req_status.MPI_TAG = MTL_PORTALS4_GET_TAG(ev->match_bits); if (msg_length > ptl_request->delivery_len) { opal_output_verbose(1, ompi_mtl_base_output, "truncate expected: %ld %ld", msg_length, ptl_request->delivery_len); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = MPI_ERR_TRUNCATE; } #if OPAL_ENABLE_DEBUG ptl_request->hdr_data = ev->hdr_data; #endif if (!MTL_PORTALS4_IS_SHORT_MSG(ev->match_bits) && ompi_mtl_portals4.protocol == rndv) { ptl_md_t md; md.start = (char*) ptl_request->delivery_ptr + ompi_mtl_portals4.eager_limit; md.length = ((msg_length > ptl_request->delivery_len) ? ptl_request->delivery_len : msg_length) - ompi_mtl_portals4.eager_limit; md.options = 0; md.eq_handle = ompi_mtl_portals4.eq_h; md.ct_handle = PTL_CT_NONE; ret = PtlMDBind(ompi_mtl_portals4.ni_h, &md, &ptl_request->md_h); if (PTL_OK != ret) { if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PtlMDBind failed: %d", __FILE__, __LINE__, ret); goto callback_error; } ret = PtlGet(ptl_request->md_h, 0, md.length, ev->initiator, ompi_mtl_portals4.read_idx, ev->hdr_data, ompi_mtl_portals4.eager_limit, ptl_request); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PtlGet failed: %d", __FILE__, __LINE__, ret); PtlMDRelease(ptl_request->md_h); if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); goto callback_error; } } else { /* make sure the data is in the right place */ ret = ompi_mtl_datatype_unpack(ptl_request->convertor, ev->start, ev->mlength); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: ompi_mtl_datatype_unpack failed: %d", __FILE__, __LINE__, ret); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = ret; } ptl_request->super.super.ompi_req->req_status._ucount = ev->mlength; OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) completed, expected", ptl_request->opcount, ptl_request->hdr_data)); ptl_request->super.super.completion_callback(&ptl_request->super.super); } break; case PTL_EVENT_REPLY: OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) got reply event", ptl_request->opcount, ptl_request->hdr_data)); if (ev->ni_fail_type != PTL_NI_OK) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PTL_EVENT_REPLY with ni_fail_type: %d", __FILE__, __LINE__, ev->ni_fail_type); PtlMDRelease(ptl_request->md_h); goto callback_error; } /* set the status - most of this filled in right after issuing the PtlGet */ ptl_request->super.super.ompi_req->req_status._ucount = ev->mlength; if (ompi_mtl_portals4.protocol == rndv) { ptl_request->super.super.ompi_req->req_status._ucount += ompi_mtl_portals4.eager_limit; } /* make sure the data is in the right place. Use _ucount for the total length because it will be set correctly for all three protocols. mlength is only correct for eager, and delivery_len is the length of the buffer, not the length of the send. */ ret = ompi_mtl_datatype_unpack(ptl_request->convertor, ptl_request->delivery_ptr, ptl_request->super.super.ompi_req->req_status._ucount); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: ompi_mtl_datatype_unpack failed: %d", __FILE__, __LINE__, ret); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = ret; } PtlMDRelease(ptl_request->md_h); OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) completed, reply", ptl_request->opcount, ptl_request->hdr_data)); ptl_request->super.super.completion_callback(&ptl_request->super.super); break; case PTL_EVENT_PUT_OVERFLOW: OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) got put_overflow event", ptl_request->opcount, ev->hdr_data)); if (ev->ni_fail_type != PTL_NI_OK) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PTL_EVENT_PUT_OVERFLOW with ni_fail_type: %d", __FILE__, __LINE__, ev->ni_fail_type); goto callback_error; } msg_length = MTL_PORTALS4_GET_LENGTH(ev->hdr_data); ptl_request->super.super.ompi_req->req_status.MPI_SOURCE = MTL_PORTALS4_GET_SOURCE(ev->match_bits); ptl_request->super.super.ompi_req->req_status.MPI_TAG = MTL_PORTALS4_GET_TAG(ev->match_bits); if (msg_length > ptl_request->delivery_len) { opal_output_verbose(1, ompi_mtl_base_output, "truncate unexpected: %ld %ld %d", msg_length, ptl_request->delivery_len, MTL_PORTALS4_IS_SHORT_MSG(ev->match_bits)); ptl_request->super.super.ompi_req->req_status.MPI_ERROR = MPI_ERR_TRUNCATE; } #if OPAL_ENABLE_DEBUG ptl_request->hdr_data = ev->hdr_data; #endif /* overflow case. Short messages have the buffer stashed somewhere. Long messages left in buffer at the source */ if (MTL_PORTALS4_IS_SHORT_MSG(ev->match_bits)) { ptl_request->super.super.ompi_req->req_status._ucount = ev->mlength; if (ev->mlength > 0) { struct iovec iov; uint32_t iov_count = 1; size_t max_data; iov.iov_base = (char*) ev->start; iov.iov_len = ev->mlength; max_data = iov.iov_len; ret = opal_convertor_unpack(ptl_request->convertor, &iov, &iov_count, &max_data ); if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); if (ret < 0) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: opal_convertor_unpack failed: %d", __FILE__, __LINE__, ret); goto callback_error; } } /* if it's a sync, send the ack */ if (MTL_PORTALS4_IS_SYNC_MSG(ev->hdr_data)) { OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) sending sync ack", ptl_request->opcount, ptl_request->hdr_data)); ret = PtlPut(ompi_mtl_portals4.zero_md_h, 0, 0, PTL_NO_ACK_REQ, ev->initiator, ompi_mtl_portals4.read_idx, ev->hdr_data, 0, NULL, 0); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PtlPut failed: %d", __FILE__, __LINE__, ret); goto callback_error; } } OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) completed, unexpected short (0x%lx)", ptl_request->opcount, ptl_request->hdr_data, (long) ev->start)); ptl_request->super.super.completion_callback(&ptl_request->super.super); } else { ptl_md_t md; if (ev->mlength > 0) { /* if rndv or triggered, copy the eager part to the right place */ memcpy(ptl_request->delivery_ptr, ev->start, ev->mlength); } md.start = (char*) ptl_request->delivery_ptr + ev->mlength; md.length = ((msg_length > ptl_request->delivery_len) ? ptl_request->delivery_len : msg_length) - ev->mlength; md.options = 0; md.eq_handle = ompi_mtl_portals4.eq_h; md.ct_handle = PTL_CT_NONE; ret = PtlMDBind(ompi_mtl_portals4.ni_h, &md, &ptl_request->md_h); if (PTL_OK != ret) { if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PtlMDBind failed: %d", __FILE__, __LINE__, ret); goto callback_error; } OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "Recv %d (0x%lx) getting long data", ptl_request->opcount, ptl_request->hdr_data)); ret = PtlGet(ptl_request->md_h, 0, md.length, ev->initiator, ompi_mtl_portals4.read_idx, ev->hdr_data, ev->mlength, ptl_request); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_output, "%s:%d: PtlGet failed: %d", __FILE__, __LINE__, ret); if (NULL != ptl_request->buffer_ptr) free(ptl_request->buffer_ptr); PtlMDRelease(ptl_request->md_h); goto callback_error; } } break; default: opal_output_verbose(1, ompi_mtl_base_output, "Unhandled receive callback with event type %d", ev->type); return OMPI_ERROR; } return OMPI_SUCCESS; callback_error: ptl_request->super.super.ompi_req->req_status.MPI_ERROR = ompi_mtl_portals4_get_error(ret); ptl_request->super.super.completion_callback(&ptl_request->super.super); return OMPI_SUCCESS; }
static int portals4_init_interface(void) { unsigned int ret; ptl_md_t md; ptl_me_t me; /* create event queues */ ret = PtlEQAlloc(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.send_queue_size, &ompi_mtl_portals4.send_eq_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlEQAlloc failed: %d\n", __FILE__, __LINE__, ret); goto error; } ret = PtlEQAlloc(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_queue_size, &ompi_mtl_portals4.recv_eq_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlEQAlloc failed: %d\n", __FILE__, __LINE__, ret); goto error; } /* Create send and long message (read) portal table entries */ ret = PtlPTAlloc(ompi_mtl_portals4.ni_h, PTL_PT_ONLY_USE_ONCE | PTL_PT_ONLY_TRUNCATE | PTL_PT_FLOWCTRL, ompi_mtl_portals4.recv_eq_h, REQ_RECV_TABLE_ID, &ompi_mtl_portals4.recv_idx); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlPTAlloc failed: %d\n", __FILE__, __LINE__, ret); goto error; } if (ompi_mtl_portals4.recv_idx != REQ_RECV_TABLE_ID) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlPTAlloc did not allocate the requested PT: %d\n", __FILE__, __LINE__, ompi_mtl_portals4.recv_idx); goto error; } ret = PtlPTAlloc(ompi_mtl_portals4.ni_h, PTL_PT_ONLY_USE_ONCE | PTL_PT_ONLY_TRUNCATE, ompi_mtl_portals4.send_eq_h, REQ_READ_TABLE_ID, &ompi_mtl_portals4.read_idx); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlPTAlloc failed: %d\n", __FILE__, __LINE__, ret); goto error; } if (ompi_mtl_portals4.read_idx != REQ_READ_TABLE_ID) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlPTAlloc did not allocate the requested PT: %d\n", __FILE__, __LINE__, ompi_mtl_portals4.read_idx); goto error; } /* bind zero-length md for sending acks */ md.start = NULL; md.length = 0; md.options = 0; md.eq_handle = PTL_EQ_NONE; md.ct_handle = PTL_CT_NONE; ret = PtlMDBind(ompi_mtl_portals4.ni_h, &md, &ompi_mtl_portals4.zero_md_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlMDBind failed: %d\n", __FILE__, __LINE__, ret); goto error; } /* Bind MD across all memory */ md.start = 0; md.length = PTL_SIZE_MAX; md.options = 0; md.eq_handle = ompi_mtl_portals4.send_eq_h; md.ct_handle = PTL_CT_NONE; ret = PtlMDBind(ompi_mtl_portals4.ni_h, &md, &ompi_mtl_portals4.send_md_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlMDBind failed: %d\n", __FILE__, __LINE__, ret); goto error; } /* Handle long overflows */ me.start = NULL; me.length = 0; me.ct_handle = PTL_CT_NONE; me.min_free = 0; me.uid = ompi_mtl_portals4.uid; me.options = PTL_ME_OP_PUT | PTL_ME_EVENT_LINK_DISABLE | PTL_ME_EVENT_COMM_DISABLE | PTL_ME_EVENT_UNLINK_DISABLE; if (ompi_mtl_portals4.use_logical) { me.match_id.rank = PTL_RANK_ANY; } else { me.match_id.phys.nid = PTL_NID_ANY; me.match_id.phys.pid = PTL_PID_ANY; } me.match_bits = MTL_PORTALS4_LONG_MSG; me.ignore_bits = MTL_PORTALS4_CONTEXT_MASK | MTL_PORTALS4_SOURCE_MASK | MTL_PORTALS4_TAG_MASK; ret = PtlMEAppend(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_idx, &me, PTL_OVERFLOW_LIST, NULL, &ompi_mtl_portals4.long_overflow_me_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: PtlMEAppend failed: %d\n", __FILE__, __LINE__, ret); goto error; } /* attach short unex recv blocks */ ret = ompi_mtl_portals4_recv_short_init(); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: short receive block initialization failed: %d\n", __FILE__, __LINE__, ret); goto error; } ompi_mtl_portals4.opcount = 0; #if OPAL_ENABLE_DEBUG ompi_mtl_portals4.recv_opcount = 0; #endif #if OMPI_MTL_PORTALS4_FLOW_CONTROL ret = ompi_mtl_portals4_flowctl_init(); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: ompi_mtl_portals4_flowctl_init failed: %d\n", __FILE__, __LINE__, ret); goto error; } #endif return OMPI_SUCCESS; error: if (!PtlHandleIsEqual(ompi_mtl_portals4.long_overflow_me_h, PTL_INVALID_HANDLE)) { PtlMEUnlink(ompi_mtl_portals4.long_overflow_me_h); } if (!PtlHandleIsEqual(ompi_mtl_portals4.zero_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(ompi_mtl_portals4.zero_md_h); } if (!PtlHandleIsEqual(ompi_mtl_portals4.send_md_h, PTL_INVALID_HANDLE)) { PtlMDRelease(ompi_mtl_portals4.send_md_h); } if (ompi_mtl_portals4.read_idx != (ptl_pt_index_t) ~0UL) { PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.read_idx); } if (ompi_mtl_portals4.recv_idx != (ptl_pt_index_t) ~0UL) { PtlPTFree(ompi_mtl_portals4.ni_h, ompi_mtl_portals4.recv_idx); } if (!PtlHandleIsEqual(ompi_mtl_portals4.send_eq_h, PTL_INVALID_HANDLE)) { PtlEQFree(ompi_mtl_portals4.send_eq_h); } if (!PtlHandleIsEqual(ompi_mtl_portals4.recv_eq_h, PTL_INVALID_HANDLE)) { PtlEQFree(ompi_mtl_portals4.recv_eq_h); } return OMPI_ERROR; }