void get_contig ( pami_context_t context, void * lbuf, void * rbuf, void * lbase, void * rbase, pami_memregion_t * lmr, pami_memregion_t * rmr, size_t sndlen, pami_endpoint_t target ) { pami_rget_simple_t rget; rget.rma.dest = target; rget.rma.bytes = sndlen; rget.rma.cookie = (void*)&_send_active; rget.rma.done_fn = cb_done; rget.rma.hints.buffer_registered = PAMI_HINT_ENABLE; rget.rma.hints.use_rdma = PAMI_HINT_ENABLE; rget.rdma.local.mr = lmr; rget.rdma.local.offset = (size_t)lbuf - (size_t)lbase; rget.rdma.remote.mr = rmr; rget.rdma.remote.offset = (size_t)rbuf - (size_t)rbase; assert (_send_active == 1); #if ENABLE_PROGRESS pami_work_t work; PAMI_Context_post (context, &work, (pami_work_function)PAMI_Rget, (void*)&rget); while (_send_active == 1); #else RC( PAMI_Rget (context, &rget) ); while (_send_active) PAMI_Context_advance (context, POLL_CNT); #endif _send_active = 1; }
static void dispatch_rts ( pami_context_t context, /**< IN: PAMI context */ void * cookie, /**< IN: dispatch cookie */ const void * header_addr, /**< IN: header address */ size_t header_size, /**< IN: header size */ const void * pipe_addr, /**< IN: address of PAMI pipe buffer */ size_t pipe_size, /**< IN: size of PAMI pipe buffer */ pami_endpoint_t origin, pami_recv_t * recv) /**< OUT: receive message structure */ { volatile size_t * active = (volatile size_t *) cookie; fprintf (stderr, ">> 'rts' dispatch function. cookie = %p (active: %zu), header_size = %zu, pipe_size = %zu, recv = %p\n", cookie, *active, header_size, pipe_size, recv); rts_info_t * rts = (rts_info_t *) header_addr; fprintf (stderr, " 'rts' dispatch function. rts->origin = 0x%08x, rts->bytes = %zu\n", rts->origin, rts->bytes); /*assert(pipe_addr!=NULL); */ /*pami_memregion_t * origin_memregion = (pami_memregion_t *) pipe_addr; */ get_info_t * get = (get_info_t *) malloc (sizeof(get_info_t)); get->value = active; get->origin = rts->origin; get->bytes = rts->bytes; get->pad = 16; initialize_data (get->buffer, 0, 6); print_data (get->buffer, 12*4); /* Create a memregion for the data buffer. */ size_t bytes = 0; pami_result_t pami_rc = PAMI_Memregion_create (context, get->buffer, 12*4, &bytes, &(get->memregion)); if (PAMI_SUCCESS != pami_rc) { fprintf (stderr, "PAMI_Memregion_create failed with rc = %d\n", pami_rc) ; exit(1); } /* Perform the rdma get operation */ pami_rget_simple_t parameters; parameters.rma.dest = rts->origin; parameters.rma.bytes = rts->bytes; parameters.rma.cookie = get; parameters.rma.done_fn = get_done; parameters.rdma.local.mr = &(get->memregion); parameters.rdma.local.offset = 16; parameters.rdma.remote.mr = &(rts->memregion); parameters.rdma.remote.offset = 0; fprintf (stderr, " 'rts' dispatch function. Before PAMI_Rget()\n"); pami_result_t status = PAMI_Rget (context, ¶meters); fprintf (stderr, " 'rts' dispatch function. After PAMI_Rget(), status = %d\n", status); if (status != PAMI_SUCCESS) get_done (context, (void *) get, status); fprintf (stderr, "<< 'rts' dispatch function.\n"); return; }
void test_fn (int argc, char * argv[], pami_client_t client, pami_context_t context[]) { int num_doubles = 16; if (argc > 1) num_doubles = atoi (argv[1]); size_t num_tasks = size (client); pami_task_t my_task_id = task (client); pami_task_t target_task_id = num_tasks - 1; pami_task_t origin_task_id = 0; /* * Allocate a 'window' of memory region information, one for each task in the * client. Only the 'local' memory region information for this task will * contain a valid data buffer. The memory region information is marked * 'active' when the memory regions are received from each remote task. */ memregion_information_t * mr_info = (memregion_information_t *) malloc (sizeof(memregion_information_t) * num_tasks); unsigned i; for (i = 0; i < num_tasks; i++) { mr_info[i].data.iov_len = 0; mr_info[i].data.iov_base = NULL; mr_info[i].active = 0; } /* * Create a local memregion for each context. * * Note that both memregions will describe the same memory location. This is * necessary when writing portable, platform independent code as the physical * hardware underlying the contexts may, or may not, require separate memory * pinning. */ size_t actual_memregion_bytes = 0; mr_info[my_task_id].data.iov_base = malloc (sizeof(double) * num_doubles); mr_info[my_task_id].data.iov_len = sizeof(double) * num_doubles; PAMI_Memregion_create (context[0], mr_info[my_task_id].data.iov_base, mr_info[my_task_id].data.iov_len, & actual_memregion_bytes, & mr_info[my_task_id].memregion[0]); PAMI_Memregion_create (context[1], mr_info[my_task_id].data.iov_base, mr_info[my_task_id].data.iov_len, & actual_memregion_bytes, & mr_info[my_task_id].memregion[1]); mr_info[my_task_id].active = 1; /* * Register the memory region exchange dispatch; only needed on the * first context of each task. */ pami_dispatch_hint_t mr_hint = {0}; pami_dispatch_callback_function mr_dispatch; mr_dispatch.p2p = exchange_memregion_recv_cb; PAMI_Dispatch_set (context[0], MEMREGION_EXCHANGE_DISPATCH_ID, mr_dispatch, (void *) mr_info, mr_hint); accumulate_test_information_t test_info; test_info.data_buffer.iov_base = malloc (sizeof(double) * num_doubles); test_info.data_buffer.iov_len = sizeof(double) * num_doubles; test_info.scalar = 1.2; test_info.data_fn[ACCUMULATE_TEST_SCALAR_SUM] = accumulate_scalar_sum_data_function; test_info.data_cookie[ACCUMULATE_TEST_SCALAR_SUM] = (void *) & test_info.scalar; test_info.data_fn[ACCUMULATE_TEST_VECTOR_SUM] = accumulate_vector_sum_data_function; test_info.data_cookie[ACCUMULATE_TEST_VECTOR_SUM] = malloc (sizeof(double) * num_doubles); test_info.data_fn[ACCUMULATE_TEST_SCALAR_SUBTRACT] = accumulate_scalar_subtract_data_function; test_info.data_cookie[ACCUMULATE_TEST_SCALAR_SUBTRACT] = (void *) & test_info.scalar; test_info.data_fn[ACCUMULATE_TEST_VECTOR_SUBTRACT] = accumulate_vector_subtract_data_function; test_info.data_cookie[ACCUMULATE_TEST_VECTOR_SUBTRACT] = malloc (sizeof(double) * num_doubles); test_info.data_fn[ACCUMULATE_TEST_VECTOR_MAX_SUM] = accumulate_vector_max_sum_data_function; test_info.data_cookie[ACCUMULATE_TEST_VECTOR_MAX_SUM] = malloc (sizeof(double) * num_doubles); test_info.data_fn[ACCUMULATE_TEST_VECTOR_MIN_SUM] = accumulate_vector_min_sum_data_function; test_info.data_cookie[ACCUMULATE_TEST_VECTOR_MIN_SUM] = malloc (sizeof(double) * num_doubles); /* * Register the accumulate dispatch; needed on both * contexts to enable "crosstalk". */ pami_dispatch_hint_t acc_hint = {0}; acc_hint.recv_immediate = PAMI_HINT_DISABLE; pami_dispatch_callback_function acc_dispatch; acc_dispatch.p2p = accumulate_test_recv_cb; PAMI_Dispatch_set (context[0], ACCUMULATE_TEST_DISPATCH_ID, acc_dispatch, (void *) & test_info, acc_hint); PAMI_Dispatch_set (context[1], ACCUMULATE_TEST_DISPATCH_ID, acc_dispatch, (void *) & test_info, acc_hint); simple_barrier(client, context[0]); /* * Exchange the memory regions */ volatile unsigned mr_exchange_active = 0; pami_send_t mr_exchange_parameters = {0}; mr_exchange_parameters.send.dispatch = MEMREGION_EXCHANGE_DISPATCH_ID; mr_exchange_parameters.send.header.iov_base = NULL; mr_exchange_parameters.send.header.iov_len = 0; mr_exchange_parameters.send.data.iov_base = (void *) mr_info[my_task_id].memregion; mr_exchange_parameters.send.data.iov_len = sizeof(pami_memregion_t) * 2; mr_exchange_parameters.events.cookie = (void *) & mr_exchange_active; mr_exchange_parameters.events.local_fn = decrement; for (i = 0; i < num_tasks; i++) { if (i == my_task_id) continue; PAMI_Endpoint_create (client, i, 0, & mr_exchange_parameters.send.dest); mr_exchange_active++; PAMI_Send (context[0], & mr_exchange_parameters); } /* * Advance until local memory regions have been sent and * all memory regions have been received. */ unsigned num_memregions_active; do { num_memregions_active = 0; for (i = 0; i < num_tasks; i++) num_memregions_active += mr_info[i].active; PAMI_Context_advance (context[0], 1); } while (num_memregions_active < num_tasks); while (mr_exchange_active > 0) PAMI_Context_advance (context[0], 1); #ifdef ASYNC_PROGRESS async_progress_t async_progress; async_progress_open (client, &async_progress); async_progress_enable (&async_progress, context[1]); #endif if (my_task_id == target_task_id) { /* * This is the "passive target" task. */ #ifdef ASYNC_PROGRESS /* * Do "something" besides communication for a little bit. */ sleep(1); #else /* * Advance the second context for a little bit. */ fprintf (stdout, "(%03d) spoofing async progress\n", __LINE__); for (i=0; i<10; i++) { fprintf (stdout, "(%03d) 'async progress context' advancing\n", __LINE__); PAMI_Context_advance (context[1], 100000); fprintf (stdout, "(%03d) 'async progress context' sleeping\n", __LINE__); sleep(1); } #endif } else if (my_task_id == origin_task_id) { /* * This is the "active origin" task. */ { /* * Use rdma put to initialize the remote buffer with the local data. */ volatile unsigned rput_active = 1; pami_rput_simple_t rput_parameters = {0}; PAMI_Endpoint_create (client, target_task_id, 1, & rput_parameters.rma.dest); rput_parameters.rma.bytes = num_doubles * sizeof(double); rput_parameters.rdma.local.mr = mr_info[origin_task_id].memregion; rput_parameters.rdma.local.offset = 0; rput_parameters.rdma.remote.mr = mr_info[target_task_id].memregion; rput_parameters.rdma.remote.offset = 0; rput_parameters.put.rdone_fn = decrement; rput_parameters.rma.cookie = (void *) & rput_active; PAMI_Rput (context[0], & rput_parameters); while (rput_active > 0) PAMI_Context_advance (context[0], 1); } { volatile unsigned send_active = 0; accumulate_test_t test_id = ACCUMULATE_TEST_SCALAR_SUM; pami_send_t send_parameters = {0}; PAMI_Endpoint_create (client, target_task_id, 1, & send_parameters.send.dest); send_parameters.send.dispatch = ACCUMULATE_TEST_DISPATCH_ID; send_parameters.send.header.iov_len = sizeof (accumulate_test_t); send_parameters.send.header.iov_base = (void *) & test_id; send_parameters.send.data.iov_base = test_info.data_buffer.iov_base; send_parameters.send.data.iov_len = test_info.data_buffer.iov_len; send_parameters.events.remote_fn = decrement; send_parameters.events.cookie = (void *) & send_active; for (test_id = ACCUMULATE_TEST_SCALAR_SUM; test_id < ACCUMULATE_TEST_COUNT; test_id++) { send_active = 1; fprintf (stdout, "(%03d) sending data buffer for accumulate test \"%s\"\n", __LINE__, accumulate_test_name[test_id]); PAMI_Send (context[0], & send_parameters); fprintf (stdout, "(%03d) waiting for remote completion of data buffer sent for accumulate test \"%s\"\n", __LINE__, accumulate_test_name[test_id]); while (send_active > 0) PAMI_Context_advance (context[0], 1); fprintf (stdout, "(%03d) data buffer received on remote for accumulate test \"%s\"\n", __LINE__, accumulate_test_name[test_id]); } } { /* * Use rdma get to retrieve the remote buffer and compare results. */ volatile unsigned rget_active = 1; pami_rget_simple_t rget_parameters = {0}; PAMI_Endpoint_create (client, target_task_id, 1, & rget_parameters.rma.dest); rget_parameters.rma.done_fn = decrement; rget_parameters.rma.cookie = (void *) & rget_active; rget_parameters.rma.bytes = sizeof(double) * num_doubles; rget_parameters.rdma.local.mr = mr_info[origin_task_id].memregion; rget_parameters.rdma.local.offset = 0; rget_parameters.rdma.remote.mr = mr_info[target_task_id].memregion; rget_parameters.rdma.remote.offset = 0; PAMI_Rget (context[0], & rget_parameters); while (rget_active > 0) PAMI_Context_advance (context[0], 1); } } else { /* * All other tasks, if any, do nothing and simply enter the barrier. */ } simple_barrier (client, context[0]); #ifdef ASYNC_PROGRESS async_progress_disable (&async_progress, context[1]); async_progress_close (&async_progress); #endif /* * Do cleanup ? */ return; }
int main(int argc, char* argv[]) { pami_result_t result = PAMI_ERROR; /* initialize the second client */ char * clientname = ""; pami_client_t client; result = PAMI_Client_create(clientname, &client, NULL, 0); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_create"); /* query properties of the client */ pami_configuration_t config[4]; config[0].name = PAMI_CLIENT_NUM_TASKS; config[1].name = PAMI_CLIENT_TASK_ID; config[2].name = PAMI_CLIENT_NUM_CONTEXTS; config[3].name = PAMI_CLIENT_NUM_LOCAL_TASKS; result = PAMI_Client_query(client, config, 4); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query"); const size_t world_size = config[0].value.intval; const size_t world_rank = config[1].value.intval; const size_t num_contexts = (config[2].value.intval > 32) ? 32 : config[2].value.intval; /* because I only need 16+16 contexts in c1 mode */ const size_t num_local_tasks = config[3].value.intval; TEST_ASSERT(num_contexts>1,"num_contexts>1"); const int ppn = (int)num_local_tasks; const int nnodes = world_size/ppn; const int mycore = world_size%nnodes; const int mynode = (world_rank-mycore)/ppn; const int num_sync = num_contexts/2; const int num_async = num_contexts/2; const int async_context_begin = num_sync+1; const int async_context_end = num_contexts; if (world_rank==0) { printf("hello world from rank %ld of %ld, node %d of %d, core %d of %d \n", world_rank, world_size, mynode, nnodes, mycore, ppn ); printf("num_contexts = %ld, async_context_begin = %d, async_context_end = %d \n", num_contexts, async_context_begin, async_context_end); fflush(stdout); } /* initialize the contexts */ contexts = (pami_context_t *) safemalloc( num_contexts * sizeof(pami_context_t) ); result = PAMI_Context_createv( client, NULL, 0, contexts, num_contexts ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_createv"); /* setup the world geometry */ pami_geometry_t world_geometry; result = PAMI_Geometry_world(client, &world_geometry ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Geometry_world"); /************************************************************************/ for (int n=1; n<=(256*1024); n*=2) { if (world_rank==0) { printf("starting n = %d \n", n); fflush(stdout); } result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); double * sbuf = safemalloc(world_size*n*sizeof(double)); double * rbuf = safemalloc(world_size*n*sizeof(double)); for (int s=0; s<world_size; s++ ) for (int k=0; k<n; k++) sbuf[s*n+k] = world_rank*n+k; for (int s=0; s<world_size; s++ ) for (int k=0; k<n; k++) rbuf[s*n+k] = -1.0; result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); size_t bytes = world_size * n * sizeof(double), bytes_out; pami_memregion_t * local_mr = safemalloc(num_sync * sizeof(pami_memregion_t) ); pami_memregion_t * shared_mr = safemalloc(num_sync * sizeof(pami_memregion_t) ); for (int i=0; i<num_sync; i++) { result = PAMI_Memregion_create(contexts[i], rbuf, bytes, &bytes_out, &(local_mr[i])); TEST_ASSERT(result == PAMI_SUCCESS && bytes==bytes_out,"PAMI_Memregion_create"); result = PAMI_Memregion_create(contexts[async_context_begin+i], sbuf, bytes, &bytes_out, &(shared_mr[i])); TEST_ASSERT(result == PAMI_SUCCESS && bytes==bytes_out,"PAMI_Memregion_create"); } result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); pami_endpoint_t * target_eps = (pami_endpoint_t *) safemalloc( num_async * world_size * sizeof(pami_endpoint_t) ); for (int target=0; target<world_size; target++) for (int i=0; i<num_async; i++) { result = PAMI_Endpoint_create(client, (pami_task_t) target, i, &(target_eps[target*num_async+i]) ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Endpoint_create"); } result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); pami_memregion_t * shmrs = (pami_memregion_t *) safemalloc( num_async * world_size * sizeof(pami_memregion_t) ); result = allgather(world_geometry, contexts[0], num_async * sizeof(pami_memregion_t), shared_mr, shmrs); TEST_ASSERT(result == PAMI_SUCCESS,"allgather"); /* check now that count will not iterate over an incomplete iteration space */ int remote_targets_per_thread = world_size/num_sync; assert((world_size%num_sync)==0); if (world_rank==0) { printf("starting A2A \n"); fflush(stdout); } result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); int active = world_size; uint64_t t0 = GetTimeBase(); result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); /* GCC prior to 4.7 will not permit const variables to be private i.e. firstprivate */ #ifdef _OPENMP #pragma omp parallel default(shared) firstprivate(n, num_async, num_sync) #endif { #ifdef _OPENMP int tid = omp_get_thread_num(); #else int tid = 0; #endif for (int count=0; count<remote_targets_per_thread; count++) { int target = remote_targets_per_thread*tid + count; target += world_rank; target = target % world_size; //printf("%ld: attempting Rget to %ld \n", (long)world_rank, (long)target); //fflush(stdout); int local_context = tid; /* each thread uses its own context so this is thread-safe */ int remote_context = target % num_async; pami_rget_simple_t parameters; parameters.rma.dest = target_eps[target*num_async+remote_context]; //parameters.rma.hints = ; parameters.rma.bytes = n*sizeof(double); parameters.rma.cookie = &active; parameters.rma.done_fn = cb_done; parameters.rdma.local.mr = &local_mr[local_context]; parameters.rdma.local.offset = target*n*sizeof(double); parameters.rdma.remote.mr = &shmrs[target*num_async+remote_context]; parameters.rdma.remote.offset = world_rank*n*sizeof(double); result = PAMI_Rget(contexts[local_context], ¶meters); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Rget"); } } uint64_t t1 = GetTimeBase(); double dt1 = (t1-t0)*tic; while (active>0) { result = PAMI_Context_trylock_advancev(&(contexts[0]), num_sync+num_async, 1000); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev"); } result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); uint64_t t2 = GetTimeBase(); double dt2 = (t2-t0)*tic; //result = barrier(world_geometry, contexts[0]); //TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); double megabytes = 1.e-6*bytes; printf("%ld: PAMI_Rget A2A: %ld bytes per rank, local %lf seconds (%lf MB/s), remote %lf seconds (%lf MB/s) \n", (long)world_rank, n*sizeof(double), dt1, megabytes/dt1, dt2, megabytes/dt2 ); fflush(stdout); result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); for (int s=0; s<world_size; s++ ) for (int k=0; k<n; k++) { if (rbuf[s*n+k]!=(1.0*s*n+1.0*k)) printf("%4d: rbuf[%d] = %lf (%lf) \n", (int)world_rank, s*n+k, rbuf[s*n+k], (1.0*s*n+1.0*k) ); } fflush(stdout); result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); for (int i=0; i<num_async; i++) { result = PAMI_Memregion_destroy(contexts[i], &(local_mr[i]) ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Memregion_destroy"); result = PAMI_Memregion_destroy(contexts[async_context_begin+i], &(shared_mr[i]) ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Memregion_destroy"); } free(shared_mr); free(local_mr); free(target_eps); free(shmrs); free(rbuf); free(sbuf); } /************************************************************************/ result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); /* finalize the contexts */ result = PAMI_Context_destroyv( contexts, num_contexts ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_destroyv"); free(contexts); /* finalize the client */ result = PAMI_Client_destroy( &client ); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_destroy"); if (world_rank==0) printf("%ld: end of test \n", world_rank ); fflush(stdout); return 0; }
static inline int MPIDI_Get_use_pami_rget(pami_context_t context, MPIDI_Win_request * req) { int use_typed_rdma = 0; if (!req->target.dt.contig || !req->origin.dt.contig) { use_typed_rdma = 0; if (MPIDI_Process.typed_onesided == 1) use_typed_rdma = 1; } if (use_typed_rdma) { pami_result_t rc; pami_rget_typed_t params; /* params need to zero out to avoid passing garbage to PAMI */ params=zero_rget_typed_parms; params.rma.dest=req->dest; params.rma.hints.buffer_registered = PAMI_HINT_ENABLE; params.rma.hints.use_rdma = PAMI_HINT_ENABLE; params.rma.bytes = req->target.dt.size; params.rma.cookie = req; params.rma.done_fn = MPIDI_Win_DoneCB; params.rdma.local.mr=&req->origin.memregion; params.rdma.remote.mr=&req->win->mpid.info[req->target.rank].memregion; params.rdma.remote.offset= req->offset; params.rdma.local.offset = req->state.local_offset; params.type.local = *(pami_type_t *)(req->origin.dt.pointer->device_datatype); params.type.remote = *(pami_type_t *)(req->target.dt.pointer->device_datatype); rc = PAMI_Rget_typed(context, ¶ms); MPID_assert(rc == PAMI_SUCCESS); } else { pami_result_t rc; pami_rget_simple_t params; params=zero_rget_parms; params.rma.dest=req->dest; params.rma.hints.buffer_registered = PAMI_HINT_ENABLE; params.rma.hints.use_rdma = PAMI_HINT_ENABLE; params.rma.bytes = 0; params.rma.cookie = req; params.rma.done_fn = MPIDI_Win_DoneCB; params.rdma.local.mr=&req->origin.memregion; params.rdma.remote.mr=&req->win->mpid.info[req->target.rank].memregion; params.rdma.remote.offset= req->offset; struct MPIDI_Win_sync* sync = &req->win->mpid.sync; TRACE_ERR("Start index=%u/%d l-addr=%p r-base=%p r-offset=%zu (sync->started=%u sync->complete=%u)\n", req->state.index, req->target.dt.num_contig, req->buffer, req->win->mpid.info[req->target.rank].base_addr, req->offset, sync->started, sync->complete); while (req->state.index < req->target.dt.num_contig) { if (sync->started > sync->complete + MPIDI_Process.rma_pending) { TRACE_ERR("Bailing out; index=%u/%d sync->started=%u sync->complete=%u\n", req->state.index, req->target.dt.num_contig, sync->started, sync->complete); return PAMI_EAGAIN; } ++sync->started; params.rma.bytes = req->target.dt.map[req->state.index].DLOOP_VECTOR_LEN; params.rdma.remote.offset = req->offset + (size_t)req->target.dt.map[req->state.index].DLOOP_VECTOR_BUF; params.rdma.local.offset = req->state.local_offset; #ifdef TRACE_ON unsigned* buf = (unsigned*)(req->buffer + params.rdma.local.offset); #endif TRACE_ERR(" Sub index=%u bytes=%zu l-offset=%zu r-offset=%zu buf=%p *(int*)buf=0x%08x\n", req->state.index, params.rma.bytes, params.rdma.local.offset, params.rdma.remote.offset, buf, *buf); /** sync->total will be updated with every RMA and the complete will not change till that RMA has completed. In the meanwhile the rest of the RMAs will have memory leaks */ if (req->target.dt.num_contig - req->state.index == 1) { rc = PAMI_Rget(context, ¶ms); MPID_assert(rc == PAMI_SUCCESS); return PAMI_SUCCESS; } else { rc = PAMI_Rget(context, ¶ms); MPID_assert(rc == PAMI_SUCCESS); req->state.local_offset += params.rma.bytes; ++req->state.index; } } } return PAMI_SUCCESS; }