int shmem_transport_fini(void) { ptl_ct_event_t ct; /* synchronize the atomic cache, if there is one */ PtlAtomicSync(); /* wait for remote completion (acks) of all pending events */ PtlCTWait(shmem_transport_portals4_put_ct_h, shmem_transport_portals4_pending_put_counter, &ct); if (shmem_transport_portals4_pending_put_counter != ct.success + ct.failure) { fprintf(stderr, "[%03d] WARNING: put count mismatch: %ld, %ld\n", shmem_internal_my_pe, (long) shmem_transport_portals4_pending_put_counter, (long) (ct.success + ct.failure)); } PtlCTWait(shmem_transport_portals4_get_ct_h, shmem_transport_portals4_pending_get_counter, &ct); if (shmem_transport_portals4_pending_get_counter != ct.success + ct.failure) { fprintf(stderr, "[%03d] WARNING: get count mismatch: %ld, %ld\n", shmem_internal_my_pe, (long) shmem_transport_portals4_pending_get_counter, (long) (ct.success + ct.failure)); } cleanup_handles(); PtlFini(); SHMEM_MUTEX_DESTROY(shmem_internal_mutex_ptl4_pt_state); SHMEM_MUTEX_DESTROY(shmem_internal_mutex_ptl4_frag); SHMEM_MUTEX_DESTROY(shmem_internal_mutex_ptl4_event_slots); SHMEM_MUTEX_DESTROY(shmem_internal_mutex_ptl4_nb_fence); return 0; }
/* ** This is a function used to send the int value rpt to the other side */ void SendRepeat(ArgStruct *p, int rpt) { int rc; int index; ptl_process_t dest; ptl_ct_event_t cnt_value; send_int= rpt; index= PTL_SEND_INT_INDEX; dest.rank= p->source_node; rc= PtlPut(send_int_md_handle, 0, sizeof(int), PTL_NO_ACK_REQ, dest, index, 0, 0, NULL, 0); LIBTEST_CHECK(rc, "PtlPut in SendRepeat()"); rc= PtlCTWait(send_int_ct_handle, total_int_sends, &cnt_value); LIBTEST_CHECK(rc, "PtlCTWait in SendRepeat()"); if (cnt_value.failure != 0) { fprintf(stderr, "SendRepeat() PtlPut failed %d (%d succeeded)\n", (int)cnt_value.failure, (int)cnt_value.success); } total_int_sends++; } /* end of SendRepeat() */
/* ** Send a buffer's worth of data */ void SendData(ArgStruct *p) { int rc; int index; ptl_process_t dest; ptl_ct_event_t cnt_value; index= PTL_XMIT_INDEX; dest.rank= p->source_node; rc= PtlPut(md_handle, 0, p->bufflen, PTL_NO_ACK_REQ, dest, index, 0, 0, NULL, 0); LIBTEST_CHECK(rc, "PtlPut in SendData()"); rc= PtlCTWait(send_ct_handle, total_sends, &cnt_value); LIBTEST_CHECK(rc, "PtlCTWait in SendData()"); if (cnt_value.failure != 0) { fprintf(stderr, "SendData() PtlPut failed %d (%d succeeded)\n", (int)cnt_value.failure, (int)cnt_value.success); } total_sends++; } /* end of SendData() */
/* ** Wait for a buffer's worth of data to arrive */ void RecvData(ArgStruct *p) { int rc; ptl_ct_event_t cnt_value; rc= PtlCTWait(recv_ct_handle, total_recvs, &cnt_value); LIBTEST_CHECK(rc, "PtlCTWait in RecvData"); if (cnt_value.failure != 0) { fprintf(stderr, "RecvData() PtlPut failed %d (%d succeeded)\n", (int)cnt_value.failure, (int)cnt_value.success); } total_recvs++; } /* end of RecvData() */
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; }
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 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; }
int ompi_coll_portals4_barrier_intra(struct ompi_communicator_t *comm, mca_coll_base_module_t *module) { mca_coll_portals4_module_t *portals4_module = (mca_coll_portals4_module_t*) module; int ret, i, dim, hibit, mask, num_msgs; int size = ompi_comm_size(comm); int rank = ompi_comm_rank(comm); ptl_ct_event_t ct; ptl_handle_ct_t ct_h; ptl_handle_me_t me_h; ptl_me_t me; size_t count; ptl_match_bits_t match_bits; ptl_handle_md_t md_h; void *base; ompi_coll_portals4_get_md(0, &md_h, &base); count = opal_atomic_add_size_t(&portals4_module->barrier_count, 1); ret = PtlCTAlloc(mca_coll_portals4_component.ni_h, &ct_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlCTAlloc failed: %d\n", __FILE__, __LINE__, ret); return OMPI_ERR_TEMP_OUT_OF_RESOURCE; } COLL_PORTALS4_SET_BITS(match_bits, ompi_comm_get_cid(comm), 0, COLL_PORTALS4_BARRIER, count); /* Build "tree" out of hypercube */ dim = comm->c_cube_dim; hibit = opal_hibit(rank, dim); --dim; /* receive space */ me.start = NULL; me.length = 0; me.ct_handle = ct_h; me.min_free = 0; me.uid = mca_coll_portals4_component.uid; me.options = PTL_ME_OP_PUT | PTL_ME_EVENT_SUCCESS_DISABLE | PTL_ME_EVENT_LINK_DISABLE | PTL_ME_EVENT_UNLINK_DISABLE | PTL_ME_EVENT_CT_COMM | PTL_ME_EVENT_CT_OVERFLOW; me.match_id.phys.nid = PTL_NID_ANY; me.match_id.phys.pid = PTL_PID_ANY; me.match_bits = match_bits; me.ignore_bits = 0; ret = PtlMEAppend(mca_coll_portals4_component.ni_h, mca_coll_portals4_component.pt_idx, &me, PTL_PRIORITY_LIST, NULL, &me_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlMEAppend failed: %d\n", __FILE__, __LINE__, ret); return OMPI_ERROR; } /* calculate number of children to receive from */ num_msgs = ompi_coll_portals4_get_nchildren(dim + 1, hibit, rank, size); /* send to parent when children have sent to us */ if (rank > 0) { int parent = rank & ~(1 << hibit); ret = PtlTriggeredPut(md_h, 0, 0, PTL_NO_ACK_REQ, ompi_coll_portals4_get_peer(comm, parent), mca_coll_portals4_component.pt_idx, match_bits, 0, NULL, 0, ct_h, num_msgs); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlTriggeredPut failed: %d\n", __FILE__, __LINE__, ret); return OMPI_ERROR; } /* we'll need to wait for the parent response before the next set of comms */ num_msgs++; } /* send to children when parent (or all children if root) has sent to us */ for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) { int peer = rank | mask; if (peer < size) { ret = PtlTriggeredPut(md_h, 0, 0, PTL_NO_ACK_REQ, ompi_coll_portals4_get_peer(comm, peer), mca_coll_portals4_component.pt_idx, match_bits, 0, NULL, 0, ct_h, num_msgs); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlTriggeredPut failed: %d\n", __FILE__, __LINE__, ret); return OMPI_ERROR; } } } /* Wait for all incoming messages */ ret = PtlCTWait(ct_h, num_msgs, &ct); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlCTWait failed: %d\n", __FILE__, __LINE__, ret); return OMPI_ERROR; } /* cleanup */ ret = PtlMEUnlink(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); return OMPI_ERROR; } ret = PtlCTFree(ct_h); if (PTL_OK != ret) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "%s:%d: PtlCTFree failed: %d\n", __FILE__, __LINE__, ret); return OMPI_ERROR; } return OMPI_SUCCESS; }
static int ompi_coll_portals4_scatter_intra_linear_top(const void *sbuf, int scount, struct ompi_datatype_t *sdtype, void *rbuf, int rcount, struct ompi_datatype_t *rdtype, int root, struct ompi_communicator_t *comm, ompi_coll_portals4_request_t *request, mca_coll_base_module_t *module) { mca_coll_portals4_module_t *portals4_module = (mca_coll_portals4_module_t*) module; int ret, line; ptl_ct_event_t ct; ptl_ct_event_t sync_incr_event; int8_t i_am_root; int32_t expected_rtrs = 0; int32_t expected_puts = 0; int32_t expected_acks = 0; int32_t expected_ops = 0; int32_t expected_chained_rtrs = 0; int32_t expected_chained_acks = 0; OPAL_OUTPUT((ompi_coll_base_framework.framework_output, "coll:portals4:scatter_intra_linear_top enter rank %d", request->u.scatter.my_rank)); request->type = OMPI_COLL_PORTALS4_TYPE_SCATTER; request->u.scatter.scatter_buf = NULL; request->u.scatter.scatter_mdh = PTL_INVALID_HANDLE; request->u.scatter.scatter_cth = PTL_INVALID_HANDLE; request->u.scatter.scatter_meh = PTL_INVALID_HANDLE; request->u.scatter.sync_mdh = PTL_INVALID_HANDLE; request->u.scatter.sync_cth = PTL_INVALID_HANDLE; request->u.scatter.sync_meh = PTL_INVALID_HANDLE; request->u.scatter.my_rank = ompi_comm_rank(comm); request->u.scatter.size = ompi_comm_size(comm); request->u.scatter.root_rank = root; request->u.scatter.sbuf = sbuf; request->u.scatter.rbuf = rbuf; request->u.scatter.pack_src_buf = sbuf; request->u.scatter.pack_src_count = scount; request->u.scatter.pack_src_dtype = sdtype; ompi_datatype_get_extent(request->u.scatter.pack_src_dtype, &request->u.scatter.pack_src_lb, &request->u.scatter.pack_src_extent); ompi_datatype_get_true_extent(request->u.scatter.pack_src_dtype, &request->u.scatter.pack_src_true_lb, &request->u.scatter.pack_src_true_extent); if ((root == request->u.scatter.my_rank) && (rbuf == MPI_IN_PLACE)) { request->u.scatter.unpack_dst_buf = NULL; request->u.scatter.unpack_dst_count = 0; request->u.scatter.unpack_dst_dtype = MPI_DATATYPE_NULL; } else { request->u.scatter.unpack_dst_buf = rbuf; request->u.scatter.unpack_dst_count = rcount; request->u.scatter.unpack_dst_dtype = rdtype; request->u.scatter.unpack_dst_offset = 0; ompi_datatype_get_extent(request->u.scatter.unpack_dst_dtype, &request->u.scatter.unpack_dst_lb, &request->u.scatter.unpack_dst_extent); ompi_datatype_get_true_extent(request->u.scatter.unpack_dst_dtype, &request->u.scatter.unpack_dst_true_lb, &request->u.scatter.unpack_dst_true_extent); } opal_output_verbose(30, ompi_coll_base_framework.framework_output, "%s:%d:rank(%d): request->u.scatter.unpack_dst_offset(%lu)", __FILE__, __LINE__, request->u.scatter.my_rank, request->u.scatter.unpack_dst_offset); /**********************************/ /* Setup Common Parameters */ /**********************************/ i_am_root = (request->u.scatter.my_rank == request->u.scatter.root_rank); request->u.scatter.coll_count = opal_atomic_add_size_t(&portals4_module->coll_count, 1); ret = setup_scatter_buffers_linear(comm, request, portals4_module); if (MPI_SUCCESS != ret) { line = __LINE__; goto err_hdlr; } ret = setup_scatter_handles(comm, request, portals4_module); if (MPI_SUCCESS != ret) { line = __LINE__; goto err_hdlr; } ret = setup_sync_handles(comm, request, portals4_module); if (MPI_SUCCESS != ret) { line = __LINE__; goto err_hdlr; } /**********************************/ /* do the scatter */ /**********************************/ if (i_am_root) { /* operations on the sync counter */ expected_rtrs = request->u.scatter.size - 1; /* expect RTRs from non-root ranks */ expected_acks = request->u.scatter.size - 1; /* expect Recv-ACKs from non-root ranks */ /* operations on the scatter counter */ expected_puts = 0; expected_chained_rtrs = 1; expected_chained_acks = 1; /* Chain the RTR and Recv-ACK to the Scatter CT */ sync_incr_event.success=1; sync_incr_event.failure=0; ret = PtlTriggeredCTInc(request->u.scatter.scatter_cth, sync_incr_event, request->u.scatter.sync_cth, expected_rtrs); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } ret = PtlTriggeredCTInc(request->u.scatter.scatter_cth, sync_incr_event, request->u.scatter.sync_cth, expected_rtrs + expected_acks); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } /* root, so put packed bytes to other ranks */ for (int32_t i=0; i<request->u.scatter.size; i++) { /* do not put to my scatter_buf. my data gets unpacked into my out buffer in linear_bottom(). */ if (i == request->u.scatter.my_rank) { continue; } ptl_size_t offset = request->u.scatter.packed_size * i; opal_output_verbose(30, ompi_coll_base_framework.framework_output, "%s:%d:rank(%d): offset(%lu)=rank(%d) * packed_size(%ld)", __FILE__, __LINE__, request->u.scatter.my_rank, offset, i, request->u.scatter.packed_size); ret = PtlTriggeredPut(request->u.scatter.scatter_mdh, (ptl_size_t)request->u.scatter.scatter_buf + offset, request->u.scatter.packed_size, PTL_NO_ACK_REQ, ompi_coll_portals4_get_peer(comm, i), mca_coll_portals4_component.pt_idx, request->u.scatter.scatter_match_bits, 0, NULL, 0, request->u.scatter.scatter_cth, expected_chained_rtrs); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } } } else { /* non-root, so do nothing */ /* operations on the sync counter */ expected_rtrs = 0; expected_acks = 0; /* operations on the scatter counter */ expected_puts = 1; /* scatter put from root */ expected_chained_rtrs = 0; expected_chained_acks = 0; } expected_ops = expected_chained_rtrs + expected_puts; /**********************************************/ /* only non-root ranks are PUT to, so only */ /* non-root ranks must PUT a Recv-ACK to root */ /**********************************************/ if (!i_am_root) { ret = PtlTriggeredPut(request->u.scatter.sync_mdh, 0, 0, PTL_NO_ACK_REQ, ompi_coll_portals4_get_peer(comm, request->u.scatter.root_rank), mca_coll_portals4_component.pt_idx, request->u.scatter.sync_match_bits, 0, NULL, 0, request->u.scatter.scatter_cth, expected_ops); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } } expected_ops += expected_chained_acks; if (!request->u.scatter.is_sync) { /******************************************/ /* put to finish pt when all ops complete */ /******************************************/ ret = PtlTriggeredPut(mca_coll_portals4_component.zero_md_h, 0, 0, PTL_NO_ACK_REQ, ompi_coll_portals4_get_peer(comm, request->u.scatter.my_rank), mca_coll_portals4_component.finish_pt_idx, 0, 0, NULL, (uintptr_t) request, request->u.scatter.scatter_cth, expected_ops); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } } /**************************************/ /* all non-root ranks put RTR to root */ /**************************************/ if (!i_am_root) { ret = PtlPut(request->u.scatter.sync_mdh, 0, 0, PTL_NO_ACK_REQ, ompi_coll_portals4_get_peer(comm, request->u.scatter.root_rank), mca_coll_portals4_component.pt_idx, request->u.scatter.sync_match_bits, 0, NULL, 0); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } } if (request->u.scatter.is_sync) { opal_output_verbose(1, ompi_coll_base_framework.framework_output, "calling CTWait(expected_ops=%d)\n", expected_ops); /********************************/ /* Wait for all ops to complete */ /********************************/ ret = PtlCTWait(request->u.scatter.scatter_cth, expected_ops, &ct); if (PTL_OK != ret) { ret = OMPI_ERROR; line = __LINE__; goto err_hdlr; } opal_output_verbose(1, ompi_coll_base_framework.framework_output, "completed CTWait(expected_ops=%d)\n", expected_ops); } OPAL_OUTPUT((ompi_coll_base_framework.framework_output, "coll:portals4:scatter_intra_linear_top exit rank %d", request->u.scatter.my_rank)); return OMPI_SUCCESS; err_hdlr: if (NULL != request->u.scatter.scatter_buf) free(request->u.scatter.scatter_buf); opal_output(ompi_coll_base_framework.framework_output, "%s:%4d:%4d\tError occurred ret=%d, rank %2d", __FILE__, __LINE__, line, ret, request->u.scatter.my_rank); return ret; }