/** * This does the actual short-send using PAMI_Send_immediate. This * will cause the data to be injected immediately, avoiding call-backs * and allowing us to declare more info on the stack. We can mark it * done at the end. */ static pami_result_t SendShortHandoff(pami_context_t context, void * cookie) { assert(cookie == NULL); unsigned quad[] = {(unsigned)task, 0x11, 0x22, 0x33}; pami_task_t remote_task = 1-task; size_t remote_context = (task+SHORT_DISPATCH)&(num_contexts-1); pami_endpoint_t dest; PAMI_Endpoint_create(client, remote_task, remote_context, &dest); pami_send_immediate_t parameters = { {0,0}, {0,0}, 0 }; parameters.dispatch = SHORT_DISPATCH; /*parameters.hints = {0}; */ parameters.dest = dest; parameters.header.iov_base = quad; parameters.header.iov_len = sizeof(quad); parameters.data.iov_base = sbuf; parameters.data.iov_len = SSIZE; PAMI_Send_immediate(context, ¶meters); printf("Task=%zu Channel=%p <Sent short msg> data=%x\n", task, context, sbuf[0]); done.sshort.send = 1; return PAMI_SUCCESS; }
void MPIDI_WinCtrlSend(pami_context_t context, MPIDI_Win_control_t *control, int rank, MPID_Win *win) { pami_task_t taskid; MPIDI_WinLock_info *winLock; control->win = win->mpid.info[rank].win; control->rank = win->comm_ptr->rank; taskid=MPID_VCR_GET_LPID(win->comm_ptr->vcr,rank); pami_endpoint_t dest; pami_result_t rc; taskid=MPID_VCR_GET_LPID(win->comm_ptr->vcr,rank); rc = PAMI_Endpoint_create(MPIDI_Client,taskid, 0, &dest); MPID_assert(rc == PAMI_SUCCESS); if ((control->type == MPIDI_WIN_MSGTYPE_UNLOCK) || (control->type == MPIDI_WIN_MSGTYPE_UNLOCKALL)) { pami_send_t params = { .send = { .dispatch = MPIDI_Protocols_WinCtrl, .dest = dest, .header = { .iov_base = control, .iov_len = sizeof(MPIDI_Win_control_t), }, }, .events = { .cookie = win, .local_fn = NULL, .remote_fn= MPIDI_WinUnlockDoneCB, }, };
/** * This does the actual long-send using PAMI_Send. */ static pami_result_t SendLongHandoff(pami_context_t context, void * cookie) { assert(cookie != NULL); unsigned* quad = (unsigned*)cookie; pami_task_t remote_task = 1-task; size_t remote_context = (task+LONG_DISPATCH)&(num_contexts-1); pami_endpoint_t dest; PAMI_Endpoint_create(client, remote_task, remote_context, &dest); pami_send_t parameters; bzero(¶meters, sizeof(pami_send_t)); parameters.send.dispatch = LONG_DISPATCH; /*parameters.send.hints = {0}; */ parameters.send.dest = dest; parameters.send.header.iov_base = quad; parameters.send.header.iov_len = 4*sizeof(unsigned); parameters.send.data.iov_base = lbuf; parameters.send.data.iov_len = LSIZE; parameters.events.cookie = lbuf; parameters.events.local_fn = SendLongDoneCB; parameters.events.remote_fn = NULL; PAMI_Send(context, ¶meters); return PAMI_SUCCESS; }
static void createEndpointTable (pami_client_t client, int num) { pami_configuration_t configuration; configuration.name = PAMI_CLIENT_NUM_TASKS; pami_result_t result = PAMI_Client_query(client, &configuration,1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Unable to query PAMI_CLIENT_NUM_TASKS\n"); abort(); } size_t global_tasks = configuration.value.intval; _endpoint = (pami_endpoint_t *) malloc (sizeof(pami_endpoint_t) * global_tasks * num); size_t i, j; for (i=0; i<global_tasks; i++) { for (j=0; j<num; j++) { PAMI_Endpoint_create (client, i, j, &_endpoint[i*num+j]); fprintf (stderr, "_endpoint[%zu] = 0x%08x\n", i*num+j, _endpoint[i*num+j]); } } };
/** * \brief Send a high-priority msginfo struct (control data) * * \param[in] control The pointer to the msginfo structure * \param[in] peerrank The node to whom the control message is to be sent */ static inline void MPIDI_CtrlSend(pami_context_t context, MPIDI_MsgInfo * msginfo, pami_task_t peerrank) { pami_endpoint_t dest; PAMI_Endpoint_create(MPIDI_Client, peerrank, 0, &dest); TRACE_ERR("CtrlSend: type=%d local=%u remote=%u\n", msginfo->control, MPIR_Process.comm_world->rank, peerrank); pami_send_immediate_t params = { .dispatch = MPIDI_Protocols_Control, .dest = dest, .header = { .iov_base = msginfo, .iov_len = sizeof(MPIDI_MsgInfo), }, .data = { .iov_base = NULL, .iov_len = 0, }, };
static void * allgather_test(void* p) { thread_data_t *td = (thread_data_t*)p; pami_context_t myContext = (pami_context_t)td->context; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Allgather variables */ size_t allgather_num_algorithm[2]; pami_algorithm_t *allgather_always_works_algo = NULL; pami_metadata_t *allgather_always_works_md = NULL; pami_algorithm_t *allgather_must_query_algo = NULL; pami_metadata_t *allgather_must_query_md = NULL; pami_xfer_type_t allgather_xfer = PAMI_XFER_ALLGATHER; volatile unsigned allgather_poll_flag = 0; int nalg= 0; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t allgather; int rc=0; /* Allocate buffer(s) */ int err = 0; void* buf = NULL; err = posix_memalign(&buf, 128, (gMax_byte_count) + gBuffer_offset); assert(err == 0); buf = (char*)buf + gBuffer_offset; void* rbuf = NULL; err = posix_memalign(&rbuf, 128, (gMax_byte_count * num_ep) + gBuffer_offset); assert(err == 0); rbuf = (char*)rbuf + gBuffer_offset; /* Query the world geometry for barrier algorithms */ rc |= query_geometry(client, myContext, newgeometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); /* Query the world geometry for allgather algorithms */ rc |= query_geometry(client, myContext, newgeometry, allgather_xfer, allgather_num_algorithm, &allgather_always_works_algo, &allgather_always_works_md, &allgather_must_query_algo, &allgather_must_query_md); barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; blocking_coll(myContext, &barrier, &bar_poll_flag); pami_endpoint_t my_ep, zero_ep; PAMI_Endpoint_create(client,task_id,td->tid,&my_ep); PAMI_Endpoint_create(client,0,0,&zero_ep); for (nalg = 0; nalg < allgather_num_algorithm[0]; nalg++) { allgather.cb_done = cb_done; allgather.cookie = (void*) & allgather_poll_flag; allgather.algorithm = allgather_always_works_algo[nalg]; allgather.cmd.xfer_allgather.sndbuf = buf; allgather.cmd.xfer_allgather.stype = PAMI_TYPE_BYTE; allgather.cmd.xfer_allgather.stypecount = 0; allgather.cmd.xfer_allgather.rcvbuf = rbuf; allgather.cmd.xfer_allgather.rtype = PAMI_TYPE_BYTE; allgather.cmd.xfer_allgather.rtypecount = 0; gProtocolName = allgather_always_works_md[nalg].name; if (my_ep == zero_ep) { printf("# Allgather Bandwidth Test(size:%zu) -- context = %d, protocol: %s\n",num_tasks, td->tid, gProtocolName); printf("# Size(bytes) iterations bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(allgather_always_works_md[nalg].name,gSelected) == NULL) && gSelector) || ((strstr(allgather_always_works_md[nalg].name,gSelected) != NULL) && !gSelector)) continue; int i, j; for (i = gMin_byte_count; i <= gMax_byte_count; i *= 2) { size_t dataSent = i; int niter; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; allgather.cmd.xfer_allgather.stypecount = i; allgather.cmd.xfer_allgather.rtypecount = i; allgather_initialize_sndbuf (buf, i, td->logical_rank); memset(rbuf, 0xFF, i); blocking_coll(myContext, &barrier, &bar_poll_flag); ti = timer(); for (j = 0; j < niter; j++) { blocking_coll (myContext, &allgather, &allgather_poll_flag); } tf = timer(); blocking_coll(myContext, &barrier, &bar_poll_flag); int rc_check; rc |= rc_check = allgather_check_rcvbuf (rbuf, i, num_ep); if (rc_check) fprintf(stderr, "%s FAILED validation\n", gProtocolName); usec = (tf - ti) / (double)niter; if (my_ep == zero_ep) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } } } free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); free(allgather_always_works_algo); free(allgather_always_works_md); free(allgather_must_query_algo); free(allgather_must_query_md); buf = (char*)buf - gBuffer_offset; free(buf); rbuf = (char*)rbuf - gBuffer_offset; free(rbuf); pthread_exit(NULL); }
int main(int argc, char*argv[]) { pami_client_t client; pami_context_t *context; pami_task_t task_id, root_zero=0; size_t num_tasks; pami_geometry_t world_geometry; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Gatherv variables */ size_t gatherv_num_algorithm[2]; pami_algorithm_t *next_algo = NULL; pami_metadata_t *next_md= NULL; pami_algorithm_t *gatherv_always_works_algo = NULL; pami_metadata_t *gatherv_always_works_md = NULL; pami_algorithm_t *gatherv_must_query_algo = NULL; pami_metadata_t *gatherv_must_query_md = NULL; pami_xfer_type_t gatherv_xfer = PAMI_XFER_GATHERV; volatile unsigned gatherv_poll_flag = 0; int nalg= 0, total_alg; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t gatherv; /* Process environment variables and setup globals */ setup_env(); assert(gNum_contexts > 0); context = (pami_context_t*)malloc(sizeof(pami_context_t) * gNum_contexts); /* Initialize PAMI */ int rc = pami_init(&client, /* Client */ context, /* Context */ NULL, /* Clientname=default */ &gNum_contexts, /* gNum_contexts */ NULL, /* null configuration */ 0, /* no configuration */ &task_id, /* task id */ &num_tasks); /* number of tasks */ if (rc == 1) return 1; /* Allocate buffer(s) */ int err = 0; void* buf = NULL; err = posix_memalign(&buf, 128, (gMax_byte_count * num_tasks) + gBuffer_offset); assert(err == 0); buf = (char*)buf + gBuffer_offset; void* rbuf = NULL; err = posix_memalign(&rbuf, 128, (gMax_byte_count * num_tasks) + gBuffer_offset); assert(err == 0); rbuf = (char*)rbuf + gBuffer_offset; size_t *lengths = (size_t*)malloc(num_tasks * sizeof(size_t)); assert(lengths); size_t *displs = (size_t*)malloc(num_tasks * sizeof(size_t)); assert(displs); unsigned iContext = 0; for (; iContext < gNum_contexts; ++iContext) { if (task_id == root_zero) printf("# Context: %u\n", iContext); /* Query the world geometry for barrier algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); if (rc == 1) return 1; /* Query the world geometry for gatherv algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, gatherv_xfer, gatherv_num_algorithm, &gatherv_always_works_algo, &gatherv_always_works_md, &gatherv_must_query_algo, &gatherv_must_query_md); if (rc == 1) return 1; barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; blocking_coll(context[iContext], &barrier, &bar_poll_flag); total_alg = gatherv_num_algorithm[0]+gatherv_num_algorithm[1]; for (nalg = 0; nalg < total_alg; nalg++) { metadata_result_t result = {0}; unsigned query_protocol; if(nalg < gatherv_num_algorithm[0]) { query_protocol = 0; next_algo = &gatherv_always_works_algo[nalg]; next_md = &gatherv_always_works_md[nalg]; } else { query_protocol = 1; next_algo = &gatherv_must_query_algo[nalg-gatherv_num_algorithm[0]]; next_md = &gatherv_must_query_md[nalg-gatherv_num_algorithm[0]]; } root_zero = 0; gatherv.cb_done = cb_done; gatherv.cookie = (void*) & gatherv_poll_flag; gatherv.algorithm = *next_algo; gatherv.cmd.xfer_gatherv.sndbuf = buf; gatherv.cmd.xfer_gatherv.stype = PAMI_TYPE_BYTE; gatherv.cmd.xfer_gatherv.stypecount = 0; gatherv.cmd.xfer_gatherv.rcvbuf = rbuf; gatherv.cmd.xfer_gatherv.rtype = PAMI_TYPE_BYTE; gatherv.cmd.xfer_gatherv.rtypecounts = lengths; gatherv.cmd.xfer_gatherv.rdispls = displs; gProtocolName = next_md->name; if (task_id == root_zero) { printf("# Gatherv Bandwidth Test(size:%zu) -- context = %d, protocol: %s, Metadata: range %zu <-> %zd, mask %#X\n",num_tasks, iContext, gProtocolName, next_md->range_lo,(ssize_t)next_md->range_hi, next_md->check_correct.bitmask_correct); printf("# Size(bytes) iterations bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(next_md->name, gSelected) == NULL) && gSelector) || ((strstr(next_md->name, gSelected) != NULL) && !gSelector)) continue; size_t i, j; unsigned checkrequired = next_md->check_correct.values.checkrequired; /*must query every time */ assert(!checkrequired || next_md->check_fn); /* must have function if checkrequired. */ int dt,op=4/*SUM*/; for (dt = 0; dt < dt_count; dt++) { if ((gFull_test && ((dt != DT_NULL) && (dt != DT_BYTE))) || gValidTable[op][dt]) { if (task_id == 0) printf("Running gatherv: %s\n", dt_array_str[dt]); for (i = MAX(1,gMin_byte_count/get_type_size(dt_array[dt])); i <= gMax_byte_count/get_type_size(dt_array[dt]); i *= 2) { size_t dataSent = i * get_type_size(dt_array[dt]); int niter; size_t k = 0; for (k = 0; k < num_tasks; k++) { lengths[k] = i; displs[k] = k * i; } lengths[k-1] = 0; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; if(query_protocol) { size_t sz=get_type_size(dt_array[dt])*i; result = check_metadata(*next_md, gatherv, dt_array[dt], sz, /* metadata uses bytes i, */ gatherv.cmd.xfer_gatherv.sndbuf, dt_array[dt], sz, gatherv.cmd.xfer_gatherv.rcvbuf); if (next_md->check_correct.values.nonlocal) { /* \note We currently ignore check_correct.values.nonlocal because these tests should not have nonlocal differences (so far). */ result.check.nonlocal = 0; } if (result.bitmask) continue; } blocking_coll(context[iContext], &barrier, &bar_poll_flag); ti = timer(); for (j = 0; j < niter; j++) { root_zero = (root_zero + num_tasks - 1) % num_tasks; pami_endpoint_t root_ep; PAMI_Endpoint_create(client, root_zero, 0, &root_ep); gatherv.cmd.xfer_gatherv.root = root_ep; gather_initialize_sndbuf_dt (buf, i, task_id, dt); if (task_id == root_zero) memset(rbuf, 0xFF, i*num_tasks); if (task_id != num_tasks - 1) { gatherv.cmd.xfer_gatherv.stypecount = i; } gatherv.cmd.xfer_gatherv.stype = dt_array[dt]; gatherv.cmd.xfer_gatherv.rtype = dt_array[dt]; if (checkrequired) /* must query every time */ { result = next_md->check_fn(&gatherv); if (result.bitmask) continue; } blocking_coll(context[iContext], &gatherv, &gatherv_poll_flag); if (task_id == root_zero) { int rc_check; rc |= rc_check = gather_check_rcvbuf_dt(num_tasks-1, rbuf, i, dt); if (rc_check) fprintf(stderr, "%s FAILED validation on %s\n", gProtocolName, dt_array_str[dt]); } } tf = timer(); blocking_coll(context[iContext], &barrier, &bar_poll_flag); usec = (tf - ti) / (double)niter; if (task_id == root_zero) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } } } } } free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); free(gatherv_always_works_algo); free(gatherv_always_works_md); free(gatherv_must_query_algo); free(gatherv_must_query_md); } /*for(unsigned iContext = 0; iContext < gNum_contexts; ++iContexts)*/ buf = (char*)buf - gBuffer_offset; free(buf); rbuf = (char*)rbuf - gBuffer_offset; free(rbuf); free(lengths); free(displs); rc |= pami_shutdown(&client, context, &gNum_contexts); return rc; }
int main (int argc, char ** argv) { volatile size_t _rts_active = 1; volatile size_t _ack_active = 1; memset(&null_send_hint, 0, sizeof(null_send_hint)); pami_client_t client; pami_context_t context[2]; char cl_string[] = "TEST"; pami_result_t result = PAMI_ERROR; result = PAMI_Client_create (cl_string, &client, NULL, 0); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami client. result = %d\n", result); return 1; } #ifdef TEST_CROSSTALK size_t num = 2; #else size_t num = 1; #endif result = PAMI_Context_createv(client, NULL, 0, context, num); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami context(s). result = %d\n", result); return 1; } pami_configuration_t configuration; configuration.name = PAMI_CLIENT_TASK_ID; result = PAMI_Client_query(client, &configuration,1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } pami_task_t task_id = configuration.value.intval; fprintf (stderr, "My task id = %d\n", task_id); configuration.name = PAMI_CLIENT_NUM_TASKS; result = PAMI_Client_query(client, &configuration,1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } size_t num_tasks = configuration.value.intval; fprintf (stderr, "Number of tasks = %zu\n", num_tasks); if (num_tasks < 2) { fprintf (stderr, "Error. This test requires at least 2 tasks. Number of tasks in this job: %zu\n", num_tasks); return 1; } pami_dispatch_hint_t options={}; #ifdef USE_SHMEM_OPTION options.use_shmem = PAMI_HINT_ENABLE; fprintf (stderr, "##########################################\n"); fprintf (stderr, "shared memory optimizations forced ON\n"); fprintf (stderr, "##########################################\n"); #elif defined(NO_SHMEM_OPTION) options.use_shmem = PAMI_HINT_DISABLE; fprintf (stderr, "##########################################\n"); fprintf (stderr, "shared memory optimizations forced OFF\n"); fprintf (stderr, "##########################################\n"); #endif size_t i = 0; #ifdef TEST_CROSSTALK for (i=0; i<2; i++) #endif { pami_dispatch_callback_function fn; fprintf (stderr, "Before PAMI_Dispatch_set(%d) .. &_rts_active = %p, _rts_active = %zu\n", DISPATCH_ID_RTS, &_rts_active, _rts_active); fn.p2p = dispatch_rts; result = PAMI_Dispatch_set (context[i], DISPATCH_ID_RTS, fn, (void *)&_rts_active, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable register pami dispatch. result = %d\n", result); return 1; } fprintf (stderr, "Before PAMI_Dispatch_set(%d) .. &_ack_active = %p, _ack_active = %zu\n", DISPATCH_ID_ACK, &_ack_active, _ack_active); fn.p2p = dispatch_ack; result = PAMI_Dispatch_set (context[i], DISPATCH_ID_ACK, fn, (void *)&_ack_active, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable register pami dispatch. result = %d\n", result); return 1; } } if (task_id == 0) { pami_send_immediate_t parameters; #ifdef TEST_CROSSTALK fprintf (stdout, "PAMI_Rget('simple') functional test [crosstalk]\n"); fprintf (stdout, "\n"); PAMI_Endpoint_create (client, num_tasks-1, 1, ¶meters.dest); #else fprintf (stdout, "PAMI_Rget('simple') functional test\n"); fprintf (stdout, "\n"); PAMI_Endpoint_create (client, num_tasks-1, 0, ¶meters.dest); #endif /* Allocate some memory from the heap. */ void * send_buffer = malloc (BUFFERSIZE); /* Initialize the memory for validation. */ initialize_data ((uint32_t *)send_buffer, BUFFERSIZE, 0); print_data (send_buffer, BUFFERSIZE); /* Send an 'rts' message to the target task and provide the memory region */ rts_info_t rts_info; PAMI_Endpoint_create (client, 0, 0, &rts_info.origin); rts_info.bytes = BUFFERSIZE; /* Create a memory region for this memoru buffer */ size_t bytes = 0; pami_result_t pami_rc = PAMI_Memregion_create (context[0], send_buffer, BUFFERSIZE, &bytes, &(rts_info.memregion)); if (PAMI_SUCCESS != pami_rc) { fprintf (stderr, "PAMI_Memregion_create failed with rc = %d\n", pami_rc) ; exit(1); } parameters.dispatch = DISPATCH_ID_RTS; parameters.header.iov_base = &rts_info; parameters.header.iov_len = sizeof(rts_info_t); parameters.data.iov_base = NULL; parameters.data.iov_len = 0; fprintf (stderr, "Before PAMI_Send_immediate()\n"); PAMI_Send_immediate (context[0], ¶meters); /* wait for the 'ack' */ fprintf (stderr, "Wait for 'ack', _ack_active = %zu\n", _ack_active); while (_ack_active != 0) { result = PAMI_Context_advance (context[0], 100); if (result != PAMI_SUCCESS && result != PAMI_EAGAIN) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } /* Destroy the local memory region */ PAMI_Memregion_destroy (context[0], &(rts_info.memregion)); free (send_buffer); switch (_ack_status) { case 0: fprintf (stdout, "Test PASSED\n"); break; case 1: fprintf (stdout, "Test FAILED (rget error)\n"); break; case 2: fprintf (stdout, "Test FAILED (data error)\n"); break; default: fprintf (stdout, "Test FAILED (unknown error)\n"); break; } } else if (task_id == num_tasks-1) { #ifdef TEST_CROSSTALK size_t contextid = 1; #else size_t contextid = 0; #endif /* wait for the 'rts' */ fprintf (stderr, "Wait for 'rts', _rts_active = %zu, contextid = %zu\n", _rts_active, contextid); while (_rts_active != 0) { result = PAMI_Context_advance (context[contextid], 100); if (result != PAMI_SUCCESS && result != PAMI_EAGAIN) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } } fprintf (stderr, "Test completed .. cleanup\n"); result = PAMI_Context_destroyv (context, num); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami context. result = %d\n", result); return 1; } result = PAMI_Client_destroy(&client); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami client. result = %d\n", result); return 1; } /*fprintf (stdout, "Success (%d)\n", task_id); */ return 0; };
int main (int argc, char ** argv) { /*volatile size_t send_active = 2; */ volatile size_t send_active = 1; volatile size_t recv_active = 1; pami_client_t client; pami_context_t context; char cl_string[] = "TEST"; pami_result_t result = PAMI_ERROR; fprintf (stderr, "Before Client initialize\n"); result = PAMI_Client_create (cl_string, &client, NULL, 0); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to initialize pami client. result = %d\n", result); return 1; } fprintf (stderr, "After Client initialize\n"); fprintf (stderr, "before context createv\n"); { result = PAMI_Context_createv(client, NULL, 0, &context, 1); } if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami context. result = %d\n", result); return 1; } fprintf (stderr, "after context createv\n"); pami_configuration_t configuration; configuration.name = PAMI_CLIENT_TASK_ID; result = PAMI_Client_query(client, &configuration,1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } size_t task_id = configuration.value.intval; fprintf (stderr, "My task id = %zu\n", task_id); configuration.name = PAMI_CLIENT_NUM_TASKS; result = PAMI_Client_query(client, &configuration,1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } /*size_t num_tasks = configuration.value.intval; */ size_t dispatch = 0; pami_dispatch_callback_function fn; fn.p2p = test_dispatch; pami_dispatch_hint_t options={}; fprintf (stderr, "Before PAMI_Dispatch_set() .. &recv_active = %p, recv_active = %zu\n", &recv_active, recv_active); result = PAMI_Dispatch_set (context, dispatch, fn, (void *)&recv_active, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable register pami dispatch. result = %d\n", result); return 1; } pami_send_t parameters; parameters.send.dispatch = dispatch; parameters.send.header.iov_base = (void *)&dispatch; /* send *something* */ parameters.send.header.iov_len = sizeof(size_t); parameters.send.data.iov_base = (void *)&dispatch; /* send *something* */ parameters.send.data.iov_len = sizeof(size_t); parameters.events.cookie = (void *) &send_active; parameters.events.local_fn = send_done_local; /*parameters.events.remote_fn = send_done_remote; */ parameters.events.remote_fn = NULL; #if 1 int iter; for (iter=0; iter < 100; iter++) { fprintf (stderr, "before send ...\n"); PAMI_Endpoint_create (client, task_id, 0, ¶meters.send.dest); result = PAMI_Send (context, ¶meters); fprintf (stderr, "... after send.\n"); fprintf (stderr, "before send-recv advance loop (send_active = %zu, recv_active = %zu) ...\n", send_active, recv_active); while (send_active || recv_active) { result = PAMI_Context_advance (context, 100); if ( (result != PAMI_SUCCESS) && (result != PAMI_EAGAIN) ) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } fprintf (stderr, "... after send-recv advance loop\n"); send_active = recv_active = 1; } #endif result = PAMI_Context_destroyv(&context, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami context. result = %d\n", result); return 1; } result = PAMI_Client_destroy(&client); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to finalize pami client. result = %d\n", result); return 1; } return 0; };
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; const size_t num_local_tasks = config[3].value.intval; TEST_ASSERT(num_contexts>1,"num_contexts>1"); int ppn = (int)num_local_tasks; int nnodes = world_size/ppn; int mycore = world_size%nnodes; int mynode = (world_rank-mycore)/ppn; 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 ); 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"); #ifdef PROGRESS_THREAD int status = pthread_create(&Progress_thread, NULL, &Progress_function, NULL); TEST_ASSERT(status==0, "pthread_create"); #endif /************************************************************************/ 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 shared_mr; result = PAMI_Memregion_create(contexts[1], rbuf, bytes, &bytes_out, &shared_mr); TEST_ASSERT(result == PAMI_SUCCESS && bytes==bytes_out,"PAMI_Memregion_create"); pami_memregion_t local_mr; result = PAMI_Memregion_create(contexts[0], sbuf, bytes, &bytes_out, &local_mr); 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( world_size * sizeof(pami_endpoint_t) ); for (int target=0; target<world_size; target++) { result = PAMI_Endpoint_create(client, (pami_task_t) target, 1 /* async context*/, &(target_eps[target]) ); 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( world_size * sizeof(pami_memregion_t) ); result = allgather(world_geometry, contexts[0], sizeof(pami_memregion_t), &shared_mr, shmrs); TEST_ASSERT(result == PAMI_SUCCESS,"allgather"); if (world_rank==0) { printf("starting A2A \n"); fflush(stdout); } result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); #ifdef SEPARATE_COMPLETION done_t active = { .local = world_size, .remote = world_size }; #else int active = world_size; #endif uint64_t t0 = GetTimeBase(); for (int count=0; count<world_size; count++) { int t = world_rank+count; int target = t%world_size; //printf("%ld: attempting Rput to %ld (bytes=%ld,loff=%ld, roff=%ld) \n", // (long)world_rank, (long)target, bytes, n*sizeof(double), // target*n*sizeof(double), world_rank*n*sizeof(double)); //printf("%ld: attempting Rput to %ld \n", (long)world_rank, (long)target), //fflush(stdout); pami_rput_simple_t parameters; parameters.rma.dest = target_eps[target]; //parameters.rma.hints = ; parameters.rma.bytes = n*sizeof(double); parameters.rma.cookie = &active; #ifdef SEPARATE_COMPLETION parameters.rma.done_fn = cb_done_local; parameters.put.rdone_fn = cb_done_remote; #else parameters.rma.done_fn = NULL; parameters.put.rdone_fn = cb_done; #endif parameters.rdma.local.mr = &local_mr; parameters.rdma.local.offset = target*n*sizeof(double); parameters.rdma.remote.mr = &shmrs[target]; parameters.rdma.remote.offset = world_rank*n*sizeof(double); result = PAMI_Rput(contexts[0], ¶meters); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Rput"); } #ifdef SEPARATE_COMPLETION while (active.local>0) { result = PAMI_Context_trylock_advancev(&(contexts[0]), 1, 1000); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev"); } #endif uint64_t t1 = GetTimeBase(); double dt1 = (t1-t0)*tic; #ifdef SEPARATE_COMPLETION while (active.remote>0) #else while (active>0) #endif { result = PAMI_Context_trylock_advancev(&(contexts[0]), 1, 1000); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev"); } 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_Rput 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"); result = PAMI_Memregion_destroy(contexts[0], &shared_mr); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Memregion_destroy"); result = PAMI_Memregion_destroy(contexts[0], &local_mr); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Memregion_destroy"); free(target_eps); free(shmrs); free(rbuf); free(sbuf); } /************************************************************************/ #ifdef PROGRESS_THREAD void * rv; status = pthread_cancel(Progress_thread); TEST_ASSERT(status==0, "pthread_cancel"); status = pthread_join(Progress_thread, &rv); TEST_ASSERT(status==0, "pthread_join"); #endif 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; }
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[3]; size_t num_contexts; config[0].name = PAMI_CLIENT_NUM_TASKS; config[1].name = PAMI_CLIENT_TASK_ID; config[2].name = PAMI_CLIENT_NUM_CONTEXTS; result = PAMI_Client_query(client, config, 3); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query"); world_size = config[0].value.intval; world_rank = config[1].value.intval; num_contexts = config[2].value.intval; TEST_ASSERT(num_contexts>1,"num_contexts>1"); if (world_rank==0) { printf("hello world from rank %ld of %ld \n", world_rank, world_size ); 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"); int status = pthread_create(&Progress_thread, NULL, &Progress_function, NULL); TEST_ASSERT(status==0, "pthread_create"); /************************************************************************/ int n = (argc>1 ? atoi(argv[1]) : 1000); size_t bytes = n * sizeof(int); int * local = (int *) safemalloc(bytes); for (int i=0; i<n; i++) local[i] = world_rank; /* create the endpoint */ int target = (world_rank>0 ? world_rank-1 : world_size-1); pami_endpoint_t target_ep; result = PAMI_Endpoint_create(client, (pami_task_t) target, 1, &target_ep); //result = PAMI_Endpoint_create(client, (pami_task_t) target, 0, &target_ep); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Endpoint_create"); /* register the dispatch function */ pami_dispatch_callback_function dispatch_cb; size_t dispatch_id = 37; dispatch_cb.p2p = dispatch_recv_cb; pami_dispatch_hint_t dispatch_hint = {0}; int dispatch_cookie = 1000000+world_rank; //dispatch_hint.recv_immediate = PAMI_HINT_DISABLE; result = PAMI_Dispatch_set(contexts[0], dispatch_id, dispatch_cb, &dispatch_cookie, dispatch_hint); result = PAMI_Dispatch_set(contexts[1], dispatch_id, dispatch_cb, &dispatch_cookie, dispatch_hint); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Dispatch_set"); /* make sure everything is ready */ result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); // The iovec structure describes a buffer. It contains two fields: // void *iov_base - Contains the address of a buffer. // size_t iov_len - Contains the length of the buffer. int header = 37373; int active = 1; pami_send_t parameters; parameters.send.header.iov_base = &header; parameters.send.header.iov_len = sizeof(int); parameters.send.data.iov_base = local; parameters.send.data.iov_len = bytes; parameters.send.dispatch = dispatch_id; //parameters.send.hints = ; parameters.send.dest = target_ep; parameters.events.cookie = &active; parameters.events.local_fn = cb_done; parameters.events.remote_fn = NULL;//cb_done; uint64_t t0 = GetTimeBase(); result = PAMI_Send(contexts[0], ¶meters); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Send"); while (active) { //result = PAMI_Context_advance( contexts[0], 100); //TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_advance"); result = PAMI_Context_trylock_advancev(&(contexts[0]), 1, 1000); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev"); } uint64_t t1 = GetTimeBase(); uint64_t dt = t1-t0; /* barrier on non-progressing context to make sure CHT does its job */ barrier(world_geometry, contexts[0]); printf("%ld: PAMI_Send of %ld bytes achieves %lf MB/s \n", (long)world_rank, bytes, 1.6e9*1e-6*(double)bytes/(double)dt ); fflush(stdout); result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); free(local); /************************************************************************/ void * rv; status = pthread_cancel(Progress_thread); TEST_ASSERT(status==0, "pthread_cancel"); status = pthread_join(Progress_thread, &rv); TEST_ASSERT(status==0, "pthread_join"); 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; }
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[3]; size_t num_contexts; config[0].name = PAMI_CLIENT_NUM_TASKS; config[1].name = PAMI_CLIENT_TASK_ID; config[2].name = PAMI_CLIENT_NUM_CONTEXTS; result = PAMI_Client_query(client, config, 3); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query"); world_size = config[0].value.intval; world_rank = config[1].value.intval; num_contexts = config[2].value.intval; TEST_ASSERT(num_contexts>1,"num_contexts>1"); if (world_rank==0) { printf("hello world from rank %ld of %ld \n", world_rank, world_size ); 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"); int status = pthread_create(&Progress_thread, NULL, &Progress_function, NULL); TEST_ASSERT(status==0, "pthread_create"); /************************************************************************/ int n = (argc>1 ? atoi(argv[1]) : 1000000); size_t bytes = n * sizeof(int); int * shared = (int *) safemalloc(bytes); for (int i=0; i<n; i++) shared[i] = world_rank; int * local = (int *) safemalloc(bytes); for (int i=0; i<n; i++) local[i] = -1; result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); int ** shptrs = (int **) safemalloc( world_size * sizeof(int *) ); result = allgather(world_geometry, contexts[0], sizeof(int*), &shared, shptrs); TEST_ASSERT(result == PAMI_SUCCESS,"allgather"); int target = (world_rank>0 ? world_rank-1 : world_size-1); pami_endpoint_t target_ep; result = PAMI_Endpoint_create(client, (pami_task_t) target, 1, &target_ep); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Endpoint_create"); result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); int active = 1; pami_get_simple_t parameters; parameters.rma.dest = target_ep; //parameters.rma.hints = ; parameters.rma.bytes = bytes; parameters.rma.cookie = &active; parameters.rma.done_fn = cb_done; parameters.addr.local = local; parameters.addr.remote = shptrs[target]; uint64_t t0 = GetTimeBase(); result = PAMI_Get(contexts[0], ¶meters); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Rget"); while (active) { //result = PAMI_Context_advance( contexts[0], 100); //TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_advance"); result = PAMI_Context_trylock_advancev(&(contexts[0]), 1, 1000); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev"); } uint64_t t1 = GetTimeBase(); uint64_t dt = t1-t0; /* barrier on non-progressing context to make sure CHT does its job */ barrier(world_geometry, contexts[0]); printf("%ld: PAMI_Get of %ld bytes achieves %lf MB/s \n", (long)world_rank, bytes, 1.6e9*1e-6*(double)bytes/(double)dt ); fflush(stdout); int errors = 0; //target = (world_rank<(world_size-1) ? world_rank+1 : 0); target = (world_rank>0 ? world_rank-1 : world_size-1); for (int i=0; i<n; i++) if (local[i] != target) errors++; if (errors>0) for (int i=0; i<n; i++) if (local[i] != target) printf("%ld: local[%d] = %d (%d) \n", (long)world_rank, i, local[i], target); else printf("%ld: no errors :-) \n", (long)world_rank); fflush(stdout); result = barrier(world_geometry, contexts[0]); TEST_ASSERT(result == PAMI_SUCCESS,"barrier"); free(shptrs); free(local); free(shared); /************************************************************************/ void * rv; status = pthread_cancel(Progress_thread); TEST_ASSERT(status==0, "pthread_cancel"); status = pthread_join(Progress_thread, &rv); TEST_ASSERT(status==0, "pthread_join"); 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; }
void optiq_pami_transport_init(struct optiq_transport *self) { #ifdef __bgq__ const char client_name[] = "OPTIQ"; struct optiq_pami_transport *pami_transport; pami_result_t result; pami_configuration_t query_configurations[3]; size_t contexts; int configuration_count = 0; pami_configuration_t *configurations = NULL; pami_transport = (struct optiq_pami_transport *) optiq_transport_get_concrete_transport(self); optiq_pami_data_init(pami_transport); pami_transport->num_contexts = 1; /* * Create client */ result = PAMI_Client_create(client_name, &pami_transport->client, configurations, configuration_count); assert(result == PAMI_SUCCESS); if (result != PAMI_SUCCESS) { return; } /* * Create context */ result = PAMI_Context_createv(pami_transport->client, configurations, configuration_count, &pami_transport->context, pami_transport->num_contexts); assert(result == PAMI_SUCCESS); if (result != PAMI_SUCCESS) { return; } query_configurations[0].name = PAMI_CLIENT_NUM_TASKS; query_configurations[1].name = PAMI_CLIENT_TASK_ID; query_configurations[2].name = PAMI_CLIENT_NUM_CONTEXTS; result = PAMI_Client_query(pami_transport->client, query_configurations, 3); self->size = query_configurations[0].value.intval; self->rank = query_configurations[1].value.intval; contexts = query_configurations[2].value.intval; pami_transport->rank = self->rank; pami_transport->size = self->size; pami_transport->node_id = self->rank; assert(contexts >= 1); /*Create endpoint for communication*/ pami_transport->endpoints = (pami_endpoint_t *)core_memory_alloc(sizeof(pami_endpoint_t) * self->size, "endpoints", "pami_init"); for (int i = 0; i < self->size; i++) { PAMI_Endpoint_create(pami_transport->client, i, 0, &pami_transport->endpoints[i]); } /* * Register dispatch IDs */ pami_dispatch_callback_function fn; pami_dispatch_hint_t options = {}; /*Message has come notification*/ fn.p2p = optiq_recv_message_fn; result = PAMI_Dispatch_set (pami_transport->context, RECV_MESSAGE_DISPATCH_ID, fn, (void *) pami_transport, options); assert(result == PAMI_SUCCESS); if (result != PAMI_SUCCESS) { return; } /*Job done notification*/ fn.p2p = optiq_recv_job_done_notification_fn; result = PAMI_Dispatch_set (pami_transport->context, JOB_DONE_NOTIFICATION_DISPATCH_ID, fn, (void *) pami_transport, options); assert(result == PAMI_SUCCESS); if (result != PAMI_SUCCESS) { return; } /*Other initialization*/ pami_transport->avail_recv_messages = &self->avail_recv_messages; pami_transport->in_use_recv_messages = &self->in_use_recv_messages; pami_transport->avail_send_messages = &self->avail_send_messages; #endif }
int main(int argc, char* argv[]) { int status = MPI_SUCCESS; pami_result_t result = PAMI_ERROR; int provided = MPI_THREAD_SINGLE; MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); /* IBM: --ranks-per-node 64 fails to init threads but this */ /* IBM: testcase doesn't really care so don't exit */ TEST_ASSERT((provided>=MPI_THREAD_MULTIPLE),"MPI_Init_thread"); /* initialize the second client */ char * clientname = "test"; /* IBM: PE PAMI requires a client name */ 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[3]; size_t num_contexts; config[0].name = PAMI_CLIENT_NUM_TASKS; config[1].name = PAMI_CLIENT_TASK_ID; config[2].name = PAMI_CLIENT_NUM_CONTEXTS; result = PAMI_Client_query(client, config, 3); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Client_query"); world_size = config[0].value.intval; world_rank = config[1].value.intval; num_contexts = config[2].value.intval; if (world_rank==0) printf("hello world from rank %ld of %ld, number of contexts %zu \n", world_rank, world_size, num_contexts );/*IBM: debug num_contexts */ fflush(stdout); /* initialize the contexts */ pami_context_t * 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"); /************************************************************************/ /* IBM: Updating the test with the assumption that we will Rput the */ /* IBM: local byte array to our neighbor's shared byte array. */ int n = (argc>1 ? atoi(argv[1]) : 1000); size_t bytes = n * sizeof(int), bytes_out;/* IBM: debug - scale up testing */ int * shared = (int *) safemalloc(bytes); for (int i=0; i<n; i++) shared[i] = -1; /*IBM: initialize with -1, replaced with neighbor's rank */ pami_memregion_t shared_mr; result = PAMI_Memregion_create(contexts[0], shared, bytes, &bytes_out, &shared_mr); TEST_ASSERT(result == PAMI_SUCCESS && bytes==bytes_out,"PAMI_Memregion_create"); int * local = (int *) safemalloc(bytes); for (int i=0; i<n; i++) local[i] = world_rank; /*IBM: initialize with our rank */ pami_memregion_t local_mr; result = PAMI_Memregion_create(contexts[0], local, bytes, &bytes_out, &local_mr); /* IBM: local */ TEST_ASSERT(result == PAMI_SUCCESS && bytes==bytes_out,"PAMI_Memregion_create"); status = MPI_Barrier(MPI_COMM_WORLD); TEST_ASSERT(result == MPI_SUCCESS,"MPI_Barrier"); pami_memregion_t * shmrs = (pami_memregion_t *) safemalloc( world_size * sizeof(pami_memregion_t) ); status = MPI_Allgather(&shared_mr, sizeof(pami_memregion_t), MPI_BYTE, shmrs, sizeof(pami_memregion_t), MPI_BYTE, MPI_COMM_WORLD); TEST_ASSERT(result == MPI_SUCCESS,"MPI_Allgather"); int target = (world_rank>0 ? world_rank-1 : world_size-1); pami_endpoint_t target_ep; result = PAMI_Endpoint_create(client, (pami_task_t) target, 0, &target_ep); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Endpoint_create"); int active = 2; pami_rput_simple_t parameters; parameters.rma.dest = target_ep; parameters.rma.bytes = bytes; parameters.rma.cookie = &active; parameters.rma.done_fn = cb_done; parameters.rdma.local.mr = &local_mr; parameters.rdma.local.offset = 0; parameters.rdma.remote.mr = &shmrs[target]; /*IBM: target's mem region */ parameters.rdma.remote.offset = 0; parameters.put.rdone_fn = cb_done; result = PAMI_Rput(contexts[0], ¶meters); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Rput"); while (active) { //result = PAMI_Context_advance( contexts[0], 100); //TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_advance"); result = PAMI_Context_trylock_advancev(contexts, 1, 1000); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev"); } /* IBM: I'm done with Rput but my world_rank + 1 neighbor might not be so need to advance */ /* IBM: Could do a barrier or send/recv a completion message instead ....*/ active = 10; /* IBM: Arbitrary - advance some more - 10*10000 good enough? */ while (--active) /* IBM*/ { /* IBM*/ result = PAMI_Context_trylock_advancev(contexts, 1, 10000); /* IBM*/ /*TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Context_trylock_advancev");*/ /* IBM*/ } /* IBM*/ int errors = 0; target = (world_rank<(world_size-1) ? world_rank+1 : 0); for (int i=0; i<n; i++) if ((shared[i] != target) || (local[i] != world_rank)) /*IBM: also verify didn't change local */ errors++; if (errors>0) { printf("%ld: %d errors :-( \n", (long)world_rank, errors); /*IBM: grep "errors" in scaled up output */ for (int i=0; i<n; i++) printf("%ld: local[%d] = %d , shared[%d] = %d (%d) \n", (long)world_rank, i, local[i], i, shared[i], target); /*IBM: print both arrays */ } else printf("%ld: no errors :-) \n", (long)world_rank); MPI_Barrier(MPI_COMM_WORLD); result = PAMI_Memregion_destroy(contexts[0], &shared_mr); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Memregion_destroy"); result = PAMI_Memregion_destroy(contexts[0], &local_mr); TEST_ASSERT(result == PAMI_SUCCESS,"PAMI_Memregion_destroy"); free(shmrs); free(local); free(shared); /************************************************************************/ /* 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"); status = MPI_Barrier(MPI_COMM_WORLD); TEST_ASSERT(result == MPI_SUCCESS,"MPI_Barrier"); MPI_Finalize(); if (world_rank==0) printf("%ld: end of test \n", world_rank ); fflush(stdout); return 0; }
int main (int argc, char ** argv) { pami_client_t client; pami_context_t context; pami_task_t task; size_t size; pami_dispatch_callback_function fn; pami_dispatch_hint_t options; pami_result_t result = PAMI_ERROR; /* ====== INITIALIZE ====== */ result = PAMI_Client_create ("TEST", &client, NULL, 0); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to initialize pami client. result = %d\n", result); return 1; } task = client_task (client); size = client_size (client); result = PAMI_Context_createv (client, NULL, 0, &context, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami context. result = %d\n", result); return 1; } fn.p2p = dispatch_fn; options.recv_immediate = PAMI_HINT_DEFAULT; result = PAMI_Dispatch_set (context, DISPATCH_ID_DEFAULT_EXPECT_IMMEDIATE, fn, (void *) EXPECT_IMMEDIATE, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to register DISPATCH_ID_DEFAULT_EXPECT_IMMEDIATE. result = %d\n", result); return 1; } options.recv_immediate = PAMI_HINT_DEFAULT; result = PAMI_Dispatch_set (context, DISPATCH_ID_DEFAULT_EXPECT_ASYNC, fn, (void *) EXPECT_ASYNC, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to register DISPATCH_ID_DEFAULT_EXPECT_ASYNC. result = %d\n", result); return 1; } options.recv_immediate = PAMI_HINT_ENABLE; result = PAMI_Dispatch_set (context, DISPATCH_ID_ENABLE, fn, (void *) EXPECT_IMMEDIATE, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to register DISPATCH_ID_ENABLE. result = %d\n", result); return 1; } options.recv_immediate = PAMI_HINT_DISABLE; result = PAMI_Dispatch_set (context, DISPATCH_ID_DISABLE, fn, (void *) EXPECT_ASYNC, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to register DISPATCH_ID_DISABLE. result = %d\n", result); return 1; } /* ====== START TEST ====== */ __test_errors = 0; __test_recvs = 0; size_t test_count = 0; volatile size_t send_active = 0; pami_send_t parameters; parameters.send.header.iov_base = __junk; parameters.send.header.iov_len = 0; parameters.send.data.iov_base = __junk; parameters.send.data.iov_len = 0; parameters.send.dispatch = 0; parameters.events.cookie = (void *) & send_active; parameters.events.local_fn = decrement; parameters.events.remote_fn = NULL; result = PAMI_Endpoint_create (client, 0, 0, ¶meters.send.dest); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: PAMI_Endpoint_create() failed for task 0, context 0 with %d.\n", result); return 1; } /* =================================================================== * 'recv_immediate' default * * (header+data) > recv_immediate_max MUST be an asynchronous receive * * A zero-byte send will \b always result in an immediate receive. * \see pami_dispatch_p2p_function * * Data sizes to test: * - recv_immediate_max + 1 * - 0 */ parameters.send.data.iov_len = recv_immediate_max (context, DISPATCH_ID_DEFAULT_EXPECT_ASYNC) + 1; parameters.send.dispatch = DISPATCH_ID_DEFAULT_EXPECT_ASYNC; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } parameters.send.data.iov_len = 0; parameters.send.dispatch = DISPATCH_ID_DEFAULT_EXPECT_IMMEDIATE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } /* =================================================================== * 'recv_immediate' enabled * * All receives are 'immediate'. (header+data) > recv_immediate_max is * invalid, but may not neccesarily return an error. * * Data sizes to test: * - 0 * - recv_immediate_max * - recv_immediate_max + 1 ...... ? */ parameters.send.data.iov_len = 0; parameters.send.dispatch = DISPATCH_ID_ENABLE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } parameters.send.data.iov_len = recv_immediate_max (context, DISPATCH_ID_DEFAULT_EXPECT_ASYNC); parameters.send.dispatch = DISPATCH_ID_ENABLE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } #if 0 parameters.send.data.iov_len = recv_immediate_max (context, DISPATCH_ID_DEFAULT_EXPECT_ASYNC) + 1; parameters.send.dispatch = DISPATCH_ID_ENABLE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %d with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } #endif /* =================================================================== * 'recv_immediate' disabled * * All receives are NOT 'immediate' - even "zero byte data" * * Data sizes to test: * - 0 * - recv_immediate_max * - recv_immediate_max + 1 */ parameters.send.data.iov_len = 0; parameters.send.dispatch = DISPATCH_ID_DISABLE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } parameters.send.data.iov_len = recv_immediate_max (context, DISPATCH_ID_DEFAULT_EXPECT_ASYNC); parameters.send.dispatch = DISPATCH_ID_DISABLE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } parameters.send.data.iov_len = recv_immediate_max (context, DISPATCH_ID_DEFAULT_EXPECT_ASYNC) + 1; parameters.send.dispatch = DISPATCH_ID_DISABLE; test_count++; if (task == 1) { send_active++; result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error: Unable to send to 0x%08x using dispatch %zu with %d.\n", parameters.send.dest, parameters.send.dispatch, result); return 1; } } /* ====== WAIT FOR COMMUNICATION COMPLETION ====== */ if (task == 0) { while (__test_recvs < test_count) PAMI_Context_advance (context, 1000); } else if (task == 1) { while (send_active) PAMI_Context_advance (context, 1000); } /* ====== CLEANUP ====== */ result = PAMI_Context_destroyv (&context, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy context, result = %d\n", result); return 1; } result = PAMI_Client_destroy (&client); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami client. result = %d\n", result); return 1; } /* ====== REPORT ERRORS ====== */ if (__test_errors > 0) { fprintf (stderr, "Error. Non-compliant PAMI receive immediate implementation! error count = %zu\n", __test_errors); return 1; } return 0; }
int main(int argc, char*argv[]) { pami_client_t client; pami_context_t *context; pami_task_t task_id, root=0; size_t num_tasks; pami_geometry_t world_geometry; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Reduce variables */ size_t reduce_num_algorithm[2]; pami_algorithm_t *reduce_always_works_algo = NULL; pami_metadata_t *reduce_always_works_md = NULL; pami_algorithm_t *reduce_must_query_algo = NULL; pami_metadata_t *reduce_must_query_md = NULL; pami_xfer_type_t reduce_xfer = PAMI_XFER_REDUCE; volatile unsigned reduce_poll_flag = 0; int i, j, nalg = 0; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t reduce; pami_type_t pami_stype = 0; pami_type_t pami_rtype = 0; pami_result_t ret; /* Process environment variables and setup globals */ setup_env(); assert(gNum_contexts > 0); context = (pami_context_t*)malloc(sizeof(pami_context_t) * gNum_contexts); /* Allocate buffer(s) */ int err = 0; void* sbuf = NULL; err = posix_memalign(&sbuf, 128, gMax_byte_count + gBuffer_offset); assert(err == 0); sbuf = (char*)sbuf + gBuffer_offset; void* rbuf = NULL; err = posix_memalign(&rbuf, 128, gMax_byte_count + gBuffer_offset); assert(err == 0); rbuf = (char*)rbuf + gBuffer_offset; /* Initialize PAMI */ int rc = pami_init(&client, /* Client */ context, /* Context */ NULL, /* Clientname=default */ &gNum_contexts, /* gNum_contexts */ NULL, /* null configuration */ 0, /* no configuration */ &task_id, /* task id */ &num_tasks); /* number of tasks */ if (rc == 1) return 1; ret = PAMI_Type_create(&pami_stype); if(ret != PAMI_SUCCESS) return 1; ret = PAMI_Type_create(&pami_rtype); if(ret != PAMI_SUCCESS) return 1; PAMI_Type_add_typed(pami_stype, PAMI_TYPE_DOUBLE, 0, 1, sizeof(double)*2); PAMI_Type_add_typed(pami_rtype, PAMI_TYPE_DOUBLE, sizeof(double), 1, sizeof(double)); ret = PAMI_Type_complete(pami_stype, sizeof(double)); if(ret != PAMI_SUCCESS){ printf("Invalid atom size for stype\n"); return 1; } ret = PAMI_Type_complete(pami_rtype, sizeof(double)); if(ret != PAMI_SUCCESS){ printf("Invalid atom size for rtype\n"); return 1; } /* Query the world geometry for barrier algorithms */ rc |= query_geometry_world(client, context[0], &world_geometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); if (rc == 1) return 1; barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; unsigned iContext = 0; for (; iContext < gNum_contexts; ++iContext) { if (task_id == 0) printf("# Context: %u\n", iContext); /* Query the world geometry for reduce algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, reduce_xfer, reduce_num_algorithm, &reduce_always_works_algo, &reduce_always_works_md, &reduce_must_query_algo, &reduce_must_query_md); if (rc == 1) return 1; for (nalg = 0; nalg < reduce_num_algorithm[0]; nalg++) { if (task_id == 0) /* root not set yet */ { printf("# Reduce Bandwidth Test -- context = %d, root varies, protocol: %s\n", iContext, reduce_always_works_md[nalg].name); printf("# Size(bytes) cycles bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(reduce_always_works_md[nalg].name, gSelected) == NULL) && gSelector) || ((strstr(reduce_always_works_md[nalg].name, gSelected) != NULL) && !gSelector)) continue; gProtocolName = reduce_always_works_md[nalg].name; reduce.cb_done = cb_done; reduce.cookie = (void*) & reduce_poll_flag; reduce.algorithm = reduce_always_works_algo[nalg]; reduce.cmd.xfer_reduce.sndbuf = sbuf; reduce.cmd.xfer_reduce.rcvbuf = rbuf; reduce.cmd.xfer_reduce.rtype = PAMI_TYPE_BYTE; reduce.cmd.xfer_reduce.rtypecount = 0; if (task_id == 0) /* root not set yet */ printf("Running Reduce: Non-Contiguous datatype PAMI_DATA_SUM\n"); for (i = 1; i <= gMax_byte_count/(sizeof(double)*2); i *= 2) { size_t sz=sizeof(double)*2; size_t dataSent = i * sz; int niter; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; reduce.cmd.xfer_reduce.stypecount = i; reduce.cmd.xfer_reduce.rtypecount = i; reduce.cmd.xfer_reduce.stype = pami_stype; reduce.cmd.xfer_reduce.rtype = pami_rtype; reduce.cmd.xfer_reduce.op = PAMI_DATA_SUM; initialize_sndbuf (sbuf, i, task_id, num_tasks); memset(rbuf, 0xFF, i*2*sizeof(double)); /* We aren't testing barrier itself, so use context 0. */ blocking_coll(context[0], &barrier, &bar_poll_flag); ti = timer(); root = 0; for (j = 0; j < niter; j++) { pami_endpoint_t root_ep; PAMI_Endpoint_create(client, root, 0, &root_ep); reduce.cmd.xfer_reduce.root = root_ep; if (task_id == root) reduce.cmd.xfer_reduce.rcvbuf = rbuf; else reduce.cmd.xfer_reduce.rcvbuf = NULL; blocking_coll(context[iContext], &reduce, &reduce_poll_flag); root = (root + 1) % num_tasks; } tf = timer(); /* We aren't testing barrier itself, so use context 0. */ blocking_coll(context[0], &barrier, &bar_poll_flag); if(task_id < niter) /* only validate tasks which were roots in niter loop */ { int rc_check; rc |= rc_check = check_rcvbuf (rbuf, i, task_id, num_tasks); if (rc_check) fprintf(stderr, "%s FAILED validation\n", gProtocolName); } usec = (tf - ti) / (double)niter; if (task_id == root) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } if(!i)i++; } } free(reduce_always_works_algo); free(reduce_always_works_md); free(reduce_must_query_algo); free(reduce_must_query_md); } /*for(unsigned iContext = 0; iContext < gNum_contexts; ++iContexts)*/ free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); sbuf = (char*)sbuf - gBuffer_offset; free(sbuf); rbuf = (char*)rbuf - gBuffer_offset; free(rbuf); rc |= pami_shutdown(&client, context, &gNum_contexts); return rc; }
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 void * allreduce_test(void* p) { thread_data_t *td = (thread_data_t*)p; pami_context_t myContext = (pami_context_t)td->context; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Allreduce variables */ size_t allreduce_num_algorithm[2]; pami_algorithm_t *allreduce_always_works_algo = NULL; pami_metadata_t *allreduce_always_works_md = NULL; pami_algorithm_t *allreduce_must_query_algo = NULL; pami_metadata_t *allreduce_must_query_md = NULL; pami_xfer_type_t allreduce_xfer = PAMI_XFER_ALLREDUCE; volatile unsigned allreduce_poll_flag = 0; int nalg= 0; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t allreduce; int rc = 0; /* Allocate buffer(s) */ int err = 0; void* sbuf = NULL; err = posix_memalign(&sbuf, 128, gMax_byte_count + gBuffer_offset); assert(err == 0); sbuf = (char*)sbuf + gBuffer_offset; void* rbuf = NULL; err = posix_memalign(&rbuf, 128, gMax_byte_count + gBuffer_offset); assert(err == 0); rbuf = (char*)rbuf + gBuffer_offset; /* Query the world geometry for barrier algorithms */ rc |= query_geometry(client, myContext, newgeometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); /* Query the world geometry for allreduce algorithms */ rc |= query_geometry(client, myContext, newgeometry, allreduce_xfer, allreduce_num_algorithm, &allreduce_always_works_algo, &allreduce_always_works_md, &allreduce_must_query_algo, &allreduce_must_query_md); barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; blocking_coll(myContext, &barrier, &bar_poll_flag); pami_endpoint_t my_ep, zero_ep; PAMI_Endpoint_create(client,task_id,td->tid,&my_ep); PAMI_Endpoint_create(client,0,0,&zero_ep); for (nalg = 0; nalg < allreduce_num_algorithm[0]; nalg++) { if (my_ep == zero_ep) { printf("# Allreduce Bandwidth Test(size:%zu) -- context = %d, protocol: %s\n",num_tasks, td->tid, allreduce_always_works_md[nalg].name); printf("# Size(bytes) iterations bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(allreduce_always_works_md[nalg].name, gSelected) == NULL) && gSelector) || ((strstr(allreduce_always_works_md[nalg].name, gSelected) != NULL) && !gSelector)) continue; gProtocolName = allreduce_always_works_md[nalg].name; allreduce.cb_done = cb_done; allreduce.cookie = (void*) & allreduce_poll_flag; allreduce.algorithm = allreduce_always_works_algo[nalg]; allreduce.cmd.xfer_allreduce.sndbuf = sbuf; allreduce.cmd.xfer_allreduce.rcvbuf = rbuf; allreduce.cmd.xfer_allreduce.rtype = PAMI_TYPE_BYTE; allreduce.cmd.xfer_allreduce.rtypecount = 0; int op, dt,i,j; for (dt = 0; dt < dt_count; dt++) { for (op = 0; op < op_count; op++) { if (gValidTable[op][dt]) { if (my_ep == zero_ep) printf("Running Allreduce: %s, %s\n", dt_array_str[dt], op_array_str[op]); for (i = MAX(1,gMin_byte_count/get_type_size(dt_array[dt])); i <= gMax_byte_count/get_type_size(dt_array[dt]); i *= 2) { size_t sz=get_type_size(dt_array[dt]); size_t dataSent = i * sz; int niter; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; allreduce.cmd.xfer_allreduce.stypecount = i; allreduce.cmd.xfer_allreduce.rtypecount = dataSent; allreduce.cmd.xfer_allreduce.stype = dt_array[dt]; allreduce.cmd.xfer_allreduce.op = op_array[op]; reduce_initialize_sndbuf (sbuf, i, op, dt, td->logical_rank, num_ep); blocking_coll(myContext, &barrier, &bar_poll_flag); ti = timer(); for (j = 0; j < niter; j++) { blocking_coll(myContext, &allreduce, &allreduce_poll_flag); } tf = timer(); /* We aren't testing barrier itself, so use context 0. */ blocking_coll(myContext, &barrier, &bar_poll_flag); int rc_check; rc |= rc_check = reduce_check_rcvbuf (rbuf, i, op, dt, td->logical_rank, num_ep); if (rc_check) fprintf(stderr, "%s FAILED validation\n", gProtocolName); usec = (tf - ti) / (double)niter; if (my_ep == zero_ep) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } } } } } } free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); free(allreduce_always_works_algo); free(allreduce_always_works_md); free(allreduce_must_query_algo); free(allreduce_must_query_md); sbuf = (char*)sbuf - gBuffer_offset; free(sbuf); rbuf = (char*)rbuf - gBuffer_offset; free(rbuf); rc = PAMI_Fence_all (myContext, fence_cb_done, &fence_arrivals); while (fence_arrivals != 0) rc = PAMI_Context_advance (myContext, 1); pthread_exit(NULL); }
int main(int argc, char*argv[]) { pami_client_t client; pami_context_t *context; pami_task_t task_id; size_t num_tasks; pami_geometry_t world_geometry; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Bcast variables */ size_t bcast_num_algorithm[2]; pami_algorithm_t *bcast_always_works_algo = NULL; pami_metadata_t *bcast_always_works_md = NULL; pami_algorithm_t *bcast_must_query_algo = NULL; pami_metadata_t *bcast_must_query_md = NULL; pami_xfer_type_t bcast_xfer = PAMI_XFER_BROADCAST; volatile unsigned bcast_poll_flag = 0; int nalg= 0; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t broadcast; /* Process environment variables and setup globals */ setup_env(); assert(gNum_contexts > 0); context = (pami_context_t*)malloc(sizeof(pami_context_t) * gNum_contexts); /* Initialize PAMI */ int rc = pami_init(&client, /* Client */ context, /* Context */ NULL, /* Clientname=default */ &gNum_contexts, /* gNum_contexts */ NULL, /* null configuration */ 0, /* no configuration */ &task_id, /* task id */ &num_tasks); /* number of tasks */ if (rc != PAMI_SUCCESS) return 1; int o; for(o = -1; o <= gOptimize ; o++) /* -1 = default, 0 = de-optimize, 1 = optimize */ { pami_configuration_t configuration[1]; configuration[0].name = PAMI_GEOMETRY_OPTIMIZE; configuration[0].value.intval = o; /* de/optimize */ if(o == -1) ; /* skip update, use defaults */ else rc |= update_geometry(client, context[0], world_geometry, configuration, 1); if (rc != PAMI_SUCCESS) return 1; if(gNumRoots > num_tasks) gNumRoots = num_tasks; /* Allocate buffer(s) */ int err = 0; void* buf = NULL; err = posix_memalign(&buf, 128, gMax_byte_count + gBuffer_offset); assert(err == 0); buf = (char*)buf + gBuffer_offset; unsigned iContext = 0; for (; iContext < gNum_contexts; ++iContext) { if (task_id == 0) printf("# Context: %u\n", iContext); /* Query the world geometry for barrier algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); if (rc != PAMI_SUCCESS) return 1; /* Query the world geometry for broadcast algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, bcast_xfer, bcast_num_algorithm, &bcast_always_works_algo, &bcast_always_works_md, &bcast_must_query_algo, &bcast_must_query_md); if (rc != PAMI_SUCCESS) return 1; barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; blocking_coll(context[iContext], &barrier, &bar_poll_flag); for (nalg = 0; nalg < bcast_num_algorithm[1]; nalg++) { broadcast.cb_done = cb_done; broadcast.cookie = (void*) & bcast_poll_flag; broadcast.algorithm = bcast_must_query_algo[nalg]; broadcast.cmd.xfer_broadcast.buf = buf; broadcast.cmd.xfer_broadcast.type = PAMI_TYPE_BYTE; broadcast.cmd.xfer_broadcast.typecount = 0; gProtocolName = bcast_must_query_md[nalg].name; metadata_result_t result = {0}; int k; for (k=0; k< gNumRoots; k++) { pami_endpoint_t root_ep; pami_task_t root_task = (pami_task_t)k; PAMI_Endpoint_create(client, root_task, 0, &root_ep); broadcast.cmd.xfer_broadcast.root = root_ep; if (task_id == root_task) { printf("# Broadcast Bandwidth Test(size:%zu) -- context = %d, optimize = %d, root = %d protocol: %s, Metadata: range %zu <-> %zd, mask %#X\n",num_tasks, iContext, o, root_task, gProtocolName, bcast_must_query_md[nalg].range_lo, bcast_must_query_md[nalg].range_hi, bcast_must_query_md[nalg].check_correct.bitmask_correct); printf("# Size(bytes) iterations bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(bcast_must_query_md[nalg].name,gSelected) == NULL) && gSelector) || ((strstr(bcast_must_query_md[nalg].name,gSelected) != NULL) && !gSelector)) continue; unsigned checkrequired = bcast_must_query_md[nalg].check_correct.values.checkrequired; /*must query every time */ assert(!checkrequired || bcast_must_query_md[nalg].check_fn); /* must have function if checkrequired. */ int i, j; for (i = gMin_byte_count; i <= gMax_byte_count; i *= 2) { size_t dataSent = i; int niter; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; broadcast.cmd.xfer_broadcast.typecount = i; result = check_metadata(bcast_must_query_md[nalg], broadcast, PAMI_TYPE_BYTE, dataSent, /* metadata uses bytes i, */ broadcast.cmd.xfer_broadcast.buf, PAMI_TYPE_BYTE, dataSent, broadcast.cmd.xfer_broadcast.buf); if (bcast_must_query_md[nalg].check_correct.values.nonlocal) { /* \note We currently ignore check_correct.values.nonlocal because these tests should not have nonlocal differences (so far). */ result.check.nonlocal = 0; } if (result.bitmask) continue; if (task_id == root_task) bcast_initialize_sndbuf (buf, i, root_task); else memset(buf, 0xFF, i); blocking_coll(context[iContext], &barrier, &bar_poll_flag); ti = timer(); for (j = 0; j < niter; j++) { if (checkrequired) /* must query every time */ { result = bcast_must_query_md[nalg].check_fn(&broadcast); if (result.bitmask) continue; } blocking_coll (context[iContext], &broadcast, &bcast_poll_flag); } blocking_coll(context[iContext], &barrier, &bar_poll_flag); tf = timer(); int rc_check; rc |= rc_check = bcast_check_rcvbuf (buf, i, root_task); if (rc_check) fprintf(stderr, "%s FAILED validation\n", gProtocolName); usec = (tf - ti) / (double)niter; if (task_id == root_task) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } } } } free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); free(bcast_always_works_algo); free(bcast_always_works_md); free(bcast_must_query_algo); free(bcast_must_query_md); } /*for(unsigned iContext = 0; iContext < gNum_contexts; ++iContexts)*/ buf = (char*)buf - gBuffer_offset; free(buf); } /* optimize loop */ rc |= pami_shutdown(&client, context, &gNum_contexts); return rc; }
int main(int argc, char*argv[]) { pami_client_t client; pami_context_t *context; pami_task_t task_id, root_zero=0; size_t num_tasks; pami_geometry_t world_geometry; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Gatherv variables */ size_t gatherv_num_algorithm[2]; pami_algorithm_t *gatherv_always_works_algo = NULL; pami_metadata_t *gatherv_always_works_md = NULL; pami_algorithm_t *gatherv_must_query_algo = NULL; pami_metadata_t *gatherv_must_query_md = NULL; pami_xfer_type_t gatherv_xfer = PAMI_XFER_GATHERV_INT; volatile unsigned gatherv_poll_flag = 0; int nalg = 0; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t gatherv; /* Process environment variables and setup globals */ setup_env(); assert(gNum_contexts > 0); context = (pami_context_t*)malloc(sizeof(pami_context_t) * gNum_contexts); /* Initialize PAMI */ int rc = pami_init(&client, /* Client */ context, /* Context */ NULL, /* Clientname=default */ &gNum_contexts, /* gNum_contexts */ NULL, /* null configuration */ 0, /* no configuration */ &task_id, /* task id */ &num_tasks); /* number of tasks */ if (rc == 1) return 1; /* Allocate buffer(s) */ int err = 0; void* buf = NULL; err = posix_memalign(&buf, 128, (gMax_byte_count * num_tasks) + gBuffer_offset); assert(err == 0); buf = (char*)buf + gBuffer_offset; void* rbuf = NULL; err = posix_memalign(&rbuf, 128, (gMax_byte_count * num_tasks) + gBuffer_offset); assert(err == 0); rbuf = (char*)rbuf + gBuffer_offset; int *lengths = (int*)malloc(num_tasks * sizeof(int)); assert(lengths); int *displs = (int*)malloc(num_tasks * sizeof(int)); assert(displs); unsigned iContext = 0; for (; iContext < gNum_contexts; ++iContext) { if (task_id == root_zero) printf("# Context: %u\n", iContext); /* Query the world geometry for barrier algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); if (rc == 1) return 1; /* Query the world geometry for gatherv algorithms */ rc |= query_geometry_world(client, context[iContext], &world_geometry, gatherv_xfer, gatherv_num_algorithm, &gatherv_always_works_algo, &gatherv_always_works_md, &gatherv_must_query_algo, &gatherv_must_query_md); if (rc == 1) return 1; barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; blocking_coll(context[iContext], &barrier, &bar_poll_flag); for (nalg = 0; nalg < gatherv_num_algorithm[0]; nalg++) { root_zero = 0; gatherv.cb_done = cb_done; gatherv.cookie = (void*) & gatherv_poll_flag; gatherv.algorithm = gatherv_always_works_algo[nalg]; gatherv.cmd.xfer_gatherv_int.sndbuf = buf; gatherv.cmd.xfer_gatherv_int.stype = PAMI_TYPE_BYTE; gatherv.cmd.xfer_gatherv_int.stypecount = 0; gatherv.cmd.xfer_gatherv_int.rcvbuf = rbuf; gatherv.cmd.xfer_gatherv_int.rtype = PAMI_TYPE_BYTE; gatherv.cmd.xfer_gatherv_int.rtypecounts = lengths; gatherv.cmd.xfer_gatherv_int.rdispls = displs; gProtocolName = gatherv_always_works_md[nalg].name; if (task_id == root_zero) { printf("# Gatherv_int Bandwidth Test(size:%zu) -- context = %d, protocol: %s\n",num_tasks, iContext, gProtocolName); printf("# Size(bytes) iterations bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(gatherv_always_works_md[nalg].name,gSelected) == NULL) && gSelector) || ((strstr(gatherv_always_works_md[nalg].name,gSelected) != NULL) && !gSelector)) continue; size_t i, j; for (i = gMin_byte_count; i <= gMax_byte_count; i *= 2) { size_t dataSent = i; int niter; size_t k = 0; for (k = 0; k < num_tasks; k++) { lengths[k] = i; displs[k] = k * i; } lengths[k-1] = 0; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; blocking_coll(context[iContext], &barrier, &bar_poll_flag); ti = timer(); for (j = 0; j < niter; j++) { root_zero = (root_zero + num_tasks - 1) % num_tasks; pami_endpoint_t root_ep; PAMI_Endpoint_create(client, root_zero, 0, &root_ep); gatherv.cmd.xfer_gatherv_int.root = root_ep; gather_initialize_sndbuf(task_id, buf, i); if (task_id == root_zero) memset(rbuf, 0xFF, i*num_tasks); if (task_id != num_tasks - 1) gatherv.cmd.xfer_gatherv_int.stypecount = i; blocking_coll(context[iContext], &gatherv, &gatherv_poll_flag); if (task_id == root_zero) { int rc_check; rc |= rc_check = gather_check_rcvbuf(num_tasks-1, rbuf, i); if (rc_check) fprintf(stderr, "%s FAILED validation\n", gProtocolName); } } tf = timer(); blocking_coll(context[iContext], &barrier, &bar_poll_flag); usec = (tf - ti) / (double)niter; if (task_id == root_zero) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } } } free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); free(gatherv_always_works_algo); free(gatherv_always_works_md); free(gatherv_must_query_algo); free(gatherv_must_query_md); } /*for(unsigned iContext = 0; iContext < gNum_contexts; ++iContexts)*/ buf = (char*)buf - gBuffer_offset; free(buf); rbuf = (char*)rbuf - gBuffer_offset; free(rbuf); free(lengths); free(displs); rc |= pami_shutdown(&client, context, &gNum_contexts); return rc; }
int main (int argc, char ** argv) { pami_client_t client; pami_context_t context[2]; pami_task_t task_id; size_t num_tasks = 0; size_t ncontexts = 0; size_t errors = 0; pami_result_t result = PAMI_ERROR; pami_type_t subtype; pami_type_t compound_type; pami_type_t simple_type; info_t exchange[MAX_TASKS]; double data[BUFFERSIZE]; volatile unsigned ready; { /* init */ ready = 0; unsigned i; for (i = 0; i < MAX_TASKS; i++) exchange[i].active = 0; for (i = 0; i < BUFFERSIZE; i++) data[i] = E; result = PAMI_Client_create ("TEST", &client, NULL, 0); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami client. result = %d\n", result); return 1; } pami_configuration_t configuration; configuration.name = PAMI_CLIENT_TASK_ID; result = PAMI_Client_query(client, &configuration, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } task_id = configuration.value.intval; /*fprintf (stderr, "My task id = %d\n", task_id);*/ configuration.name = PAMI_CLIENT_NUM_TASKS; result = PAMI_Client_query(client, &configuration, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } num_tasks = configuration.value.intval; /*if (task_id == 0) fprintf (stderr, "Number of tasks = %zu\n", num_tasks);*/ if ((num_tasks < 2) || (num_tasks > MAX_TASKS)) { fprintf (stderr, "Error. This test requires 2-%d tasks. Number of tasks in this job: %zu\n", MAX_TASKS, num_tasks); return 1; } if (task_id == num_tasks - 1) { for (i = 0; i < 320; i++) data[i] = PI; } configuration.name = PAMI_CLIENT_NUM_CONTEXTS; result = PAMI_Client_query(client, &configuration, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable query configuration (%d). result = %d\n", configuration.name, result); return 1; } ncontexts = (configuration.value.intval < 2) ? 1 : 2; /*if (task_id == 0) fprintf (stderr, "maximum contexts = %zu, number of contexts used in this test = %zu\n", configuration.value.intval, ncontexts);*/ result = PAMI_Context_createv(client, NULL, 0, context, ncontexts); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami context(s). result = %d\n", result); return 1; } pami_dispatch_hint_t options = {}; for (i = 0; i < ncontexts; i++) { pami_dispatch_callback_function fn; fn.p2p = dispatch_exchange; result = PAMI_Dispatch_set (context[i], EXCHANGE_DISPATCH_ID, fn, (void *) exchange, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable register pami 'exchange' dispatch. result = %d\n", result); return 1; } fn.p2p = dispatch_notify; result = PAMI_Dispatch_set (context[i], NOTIFY_DISPATCH_ID, fn, (void *) & ready, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable register pami 'notify' dispatch. result = %d\n", result); return 1; } } /* *********************************** * Create the pami types ************************************/ /* This compound noncontiguous type is composed of one double, skips a double, * two doubles, skips a double, three doubles, skips a double, five doubles, * skips a double, six doubles, skips a double, seven doubles, skips a double, * eight doubles, then skips two doubles. * * This results in a type with 32 doubles that is 40 doubles * 'wide'. */ PAMI_Type_create (&subtype); PAMI_Type_add_simple (subtype, sizeof(double), /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 2); /* stride */ PAMI_Type_add_simple (subtype, sizeof(double) * 2, /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 3); /* stride */ PAMI_Type_add_simple (subtype, sizeof(double) * 3, /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 4); /* stride */ PAMI_Type_add_simple (subtype, sizeof(double) * 5, /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 6); /* stride */ PAMI_Type_add_simple (subtype, sizeof(double) * 6, /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 7); /* stride */ PAMI_Type_add_simple (subtype, sizeof(double) * 7, /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 8);/* stride */ PAMI_Type_add_simple (subtype, sizeof(double) * 8, /* bytes */ 0, /* offset */ 1, /* count */ sizeof(double) * 10);/* stride */ PAMI_Type_complete (subtype, sizeof(double)); /* This noncontiguous type is composed of the above compound type, repeated * ten times with no stride. * * This results in a type with 320 doubles that is 400 doubles * 'wide'. */ PAMI_Type_create (&compound_type); PAMI_Type_add_typed (compound_type, subtype, /* subtype */ 0, /* offset */ 10, /* count */ sizeof(double) * 32); /* stride */ PAMI_Type_complete (compound_type, sizeof(double)); /* This simple noncontiguous type is composed of eight contiguous doubles, * then skips a _single_ double, repeated 40 times. * * This results in a type with 320 doubles that is 360 doubles 'wide'. */ PAMI_Type_create (&simple_type); PAMI_Type_add_simple (simple_type, sizeof(double) * 8, /* bytes */ 0, /* offset */ 40, /* count */ sizeof(double) * 9); /* stride */ PAMI_Type_complete (simple_type, sizeof(double)); /* Create a memory region for the local data buffer. */ size_t bytes; result = PAMI_Memregion_create (context[0], (void *) data, BUFFERSIZE, &bytes, &exchange[task_id].mr); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create memory region. result = %d\n", result); return 1; } else if (bytes < BUFFERSIZE) { fprintf (stderr, "Error. Unable to create memory region of a large enough size. result = %d\n", result); return 1; } /* Broadcast the memory region to all tasks - including self. */ for (i = 0; i < num_tasks; i++) { pami_send_immediate_t parameters; parameters.dispatch = EXCHANGE_DISPATCH_ID; parameters.header.iov_base = (void *) & bytes; parameters.header.iov_len = sizeof(size_t); parameters.data.iov_base = (void *) & exchange[task_id].mr; parameters.data.iov_len = sizeof(pami_memregion_t); PAMI_Endpoint_create (client, i, 0, ¶meters.dest); result = PAMI_Send_immediate (context[0], ¶meters); } /* Advance until all memory regions have been received. */ for (i = 0; i < num_tasks; i++) { while (exchange[i].active == 0) PAMI_Context_advance (context[0], 100); } } /* init done */ pami_send_immediate_t notify; notify.dispatch = NOTIFY_DISPATCH_ID; notify.header.iov_base = NULL; notify.header.iov_len = 0; notify.data.iov_base = NULL; notify.data.iov_len = 0; volatile size_t active = 1; pami_rget_typed_t parameters; parameters.rma.hints = (pami_send_hint_t) {0}; parameters.rma.cookie = (void *) & active; parameters.rma.done_fn = decrement; parameters.rma.bytes = 320 * sizeof(double); if (task_id == 0) { fprintf (stdout, "PAMI_Rget('typed') functional test %s\n", (ncontexts < 2) ? "" : "[crosstalk]"); fprintf (stdout, "\n"); parameters.rdma.local.mr = &exchange[0].mr; parameters.rdma.remote.mr = &exchange[num_tasks - 1].mr; PAMI_Endpoint_create (client, num_tasks - 1, ncontexts - 1, ¶meters.rma.dest); PAMI_Endpoint_create (client, num_tasks - 1, ncontexts - 1, ¬ify.dest); } else { parameters.rdma.local.mr = &exchange[num_tasks - 1].mr; parameters.rdma.remote.mr = &exchange[0].mr; PAMI_Endpoint_create (client, 0, 0, ¶meters.rma.dest); PAMI_Endpoint_create (client, 0, 0, ¬ify.dest); } /* ******************************************************************** */ /* contiguous -> contiguous transfer test */ /* ******************************************************************** */ if (task_id == 0) { parameters.rdma.local.offset = 0; parameters.rdma.remote.offset = 0; parameters.type.local = PAMI_TYPE_DOUBLE; parameters.type.remote = PAMI_TYPE_DOUBLE; active = 1; PAMI_Rget_typed (context[0], ¶meters); while (active > 0) PAMI_Context_advance (context[0], 100); /* Notify the remote task that the data has been transfered. */ PAMI_Send_immediate (context[0], ¬ify); } else if (task_id == num_tasks - 1) { /* Wait for notification that the data has been transfered. */ while (ready == 0) PAMI_Context_advance (context[ncontexts - 1], 100); ready = 0; } /* ******************************************************************** */ /* contiguous -> non-contiguous transfer test */ /* ******************************************************************** */ if (task_id == num_tasks - 1) { parameters.rdma.local.offset = 4 * 1024; parameters.rdma.remote.offset = 0; parameters.type.local = simple_type; parameters.type.remote = PAMI_TYPE_DOUBLE; active = 1; PAMI_Rget_typed (context[ncontexts - 1], ¶meters); while (active > 0) PAMI_Context_advance (context[ncontexts - 1], 100); /* Notify the remote task that the data has been transfered. */ PAMI_Send_immediate (context[ncontexts - 1], ¬ify); } else if (task_id == 0) { /* Wait for notification that the data has been transfered. */ while (ready == 0) PAMI_Context_advance (context[0], 100); ready = 0; } /* ******************************************************************** */ /* non-contiguous -> non-contiguous transfer test */ /* ******************************************************************** */ if (task_id == 0) { parameters.rdma.local.offset = 4 * 1024; parameters.rdma.remote.offset = 4 * 1024; parameters.type.local = compound_type; parameters.type.remote = simple_type; active = 1; PAMI_Rget_typed (context[0], ¶meters); while (active > 0) PAMI_Context_advance (context[0], 100); /* Notify the remote task that the data has been transfered. */ PAMI_Send_immediate (context[0], ¬ify); } else if (task_id == num_tasks - 1) { /* Wait for notification that the data has been transfered. */ while (ready == 0) PAMI_Context_advance (context[ncontexts - 1], 100); ready = 0; } /* ******************************************************************** */ /* non-contiguous -> contiguous transfer test */ /* ******************************************************************** */ if (task_id == num_tasks - 1) { parameters.rdma.local.offset = 8 * 1024; parameters.rdma.remote.offset = 4 * 1024; parameters.type.local = PAMI_TYPE_DOUBLE; parameters.type.remote = compound_type; active = 1; PAMI_Rget_typed (context[ncontexts - 1], ¶meters); while (active > 0) PAMI_Context_advance (context[ncontexts - 1], 100); /* Notify the remote task that the data has been transfered. */ PAMI_Send_immediate (context[ncontexts - 1], ¬ify); } else if (task_id == 0) { /* Wait for notification that the data has been transfered. */ while (ready == 0) PAMI_Context_advance (context[0], 100); ready = 0; } /* ******************************************************************** */ /* VERIFY data buffers */ /* ******************************************************************** */ if (task_id == num_tasks - 1) { if (task_id == 0) { unsigned i = 0; for (; i < 320; i++) { if (data[i] != PI) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, PI, data[i]); } } for (; i < 512; i++) { if (data[i] != E) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, E, data[i]); } } unsigned j = 0; for (; j < 40; j++) { unsigned n = 0; for (; n < 8; n++) { if (data[i] != PI) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, PI, data[i]); } i++; } if (data[i] != E) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, E, data[i]); } i++; } for (; i < 1024; i++) { if (data[i] != E) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, E, data[i]); } } for (; i < 1024 + 320; i++) { if (data[i] != PI) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, PI, data[i]); } } for (; i < BUFFERSIZE; i++) { if (data[i] != E) { errors++; fprintf (stderr, "Error. data[%d] != %g ..... (%g)\n", i, E, data[i]); } } } } { /* cleanup */ result = PAMI_Context_destroyv(context, ncontexts); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami context. result = %d\n", result); return 1; } result = PAMI_Client_destroy(&client); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami client. result = %d\n", result); return 1; } if (task_id == num_tasks - 1) { if (errors) fprintf (stdout, "Test completed with errors (%zu)\n", errors); else fprintf (stdout, "Test completed with success\n"); } } /* cleanup done */ return (errors != 0); };
int main (int argc, char ** argv) { pami_client_t client; pami_context_t context; pami_configuration_t * configuration = NULL; char cl_string[] = "TEST"; pami_result_t result = PAMI_ERROR; result = PAMI_Client_create (cl_string, &client, NULL, 0); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to initialize pami client. result = %d\n", result); return 1; } pami_task_t task = PAMIX_Client_task (client); size_t size = PAMIX_Client_size (client); result = PAMI_Context_createv (client, configuration, 0, &context, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to create pami context. result = %d\n", result); return 1; } /* Attempt to send using a dispatch id that has not been registered. */ char metadata[1024]; char buffer[1024]; volatile unsigned recv_active = 1; volatile unsigned send_active = 1; pami_send_t parameters; parameters.send.dispatch = 10; parameters.send.header.iov_base = metadata; parameters.send.header.iov_len = 8; parameters.send.data.iov_base = buffer; parameters.send.data.iov_len = 8; parameters.events.cookie = (void *) & send_active; parameters.events.local_fn = decrement; parameters.events.remote_fn = NULL; PAMI_Endpoint_create (client, size-1, 0, ¶meters.send.dest); if (task == 0) { result = PAMI_Send (context, ¶meters); if (result == PAMI_SUCCESS) { fprintf (stderr, "Test failure. Expected error when using an unregistered dispatch id.\n"); return 1; } } size_t dispatch = 10; pami_dispatch_callback_function fn; fn.p2p = test_dispatch; pami_dispatch_hint_t options = {}; result = PAMI_Dispatch_set (context, dispatch, fn, (void *) & recv_active, options); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable register pami dispatch. result = %d\n", result); return 1; } if (task == 0) { PAMI_Endpoint_create (client, size-1, 0, ¶meters.send.dest); result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to send using a registered dispatch id.\n"); return 1; } while (send_active) { result = PAMI_Context_advance (context, 1000); if ( (result != PAMI_SUCCESS) && (result != PAMI_EAGAIN) ) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } while (recv_active) { result = PAMI_Context_advance (context, 1000); if ( (result != PAMI_SUCCESS) && (result != PAMI_EAGAIN) ) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } } else if (task == (size-1)) { PAMI_Endpoint_create (client, 0, 0, ¶meters.send.dest); while (recv_active) { result = PAMI_Context_advance (context, 1000); if ( (result != PAMI_SUCCESS) && (result != PAMI_EAGAIN) ) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } result = PAMI_Send (context, ¶meters); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to send using a registered dispatch id.\n"); return 1; } while (send_active) { result = PAMI_Context_advance (context, 1000); if ( (result != PAMI_SUCCESS) && (result != PAMI_EAGAIN) ) { fprintf (stderr, "Error. Unable to advance pami context. result = %d\n", result); return 1; } } } result = PAMI_Context_destroyv(&context, 1); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to destroy pami context. result = %d\n", result); return 1; } result = PAMI_Client_destroy(&client); if (result != PAMI_SUCCESS) { fprintf (stderr, "Error. Unable to finalize pami client. result = %d\n", result); return 1; } return 0; };
static void * gatherv_test(void* p) { thread_data_t *td = (thread_data_t*)p; pami_context_t myContext = (pami_context_t)td->context; /* Barrier variables */ size_t barrier_num_algorithm[2]; pami_algorithm_t *bar_always_works_algo = NULL; pami_metadata_t *bar_always_works_md = NULL; pami_algorithm_t *bar_must_query_algo = NULL; pami_metadata_t *bar_must_query_md = NULL; pami_xfer_type_t barrier_xfer = PAMI_XFER_BARRIER; volatile unsigned bar_poll_flag = 0; /* Gatherv variables */ size_t gatherv_num_algorithm[2]; pami_algorithm_t *gatherv_always_works_algo = NULL; pami_metadata_t *gatherv_always_works_md = NULL; pami_algorithm_t *gatherv_must_query_algo = NULL; pami_metadata_t *gatherv_must_query_md = NULL; pami_xfer_type_t gatherv_xfer = PAMI_XFER_GATHERV; volatile unsigned gatherv_poll_flag = 0; int nalg= 0; double ti, tf, usec; pami_xfer_t barrier; pami_xfer_t gatherv; int rc = 0; if(gNumRoots == -1) gNumRoots = num_ep; /* Allocate buffer(s) */ int err = 0; void* buf = NULL; err = posix_memalign(&buf, 128, (gMax_byte_count * num_ep) + gBuffer_offset); assert(err == 0); buf = (char*)buf + gBuffer_offset; void* rbuf = NULL; err = posix_memalign(&rbuf, 128, (gMax_byte_count * num_ep) + gBuffer_offset); assert(err == 0); rbuf = (char*)rbuf + gBuffer_offset; size_t *lengths = (size_t*)malloc(num_ep * sizeof(size_t)); assert(lengths); size_t *displs = (size_t*)malloc(num_ep * sizeof(size_t)); assert(displs); /* Query the world geometry for barrier algorithms */ rc |= query_geometry(client, myContext, newgeometry, barrier_xfer, barrier_num_algorithm, &bar_always_works_algo, &bar_always_works_md, &bar_must_query_algo, &bar_must_query_md); /* Query the world geometry for gatherv algorithms */ rc |= query_geometry(client, myContext, newgeometry, gatherv_xfer, gatherv_num_algorithm, &gatherv_always_works_algo, &gatherv_always_works_md, &gatherv_must_query_algo, &gatherv_must_query_md); barrier.cb_done = cb_done; barrier.cookie = (void*) & bar_poll_flag; barrier.algorithm = bar_always_works_algo[0]; blocking_coll(myContext, &barrier, &bar_poll_flag); pami_endpoint_t my_ep, zero_ep; PAMI_Endpoint_create(client,task_id,td->tid,&my_ep); PAMI_Endpoint_create(client,0,0,&zero_ep); for (nalg = 0; nalg < gatherv_num_algorithm[0]; nalg++) { gatherv.cb_done = cb_done; gatherv.cookie = (void*) & gatherv_poll_flag; gatherv.algorithm = gatherv_always_works_algo[nalg]; gatherv.cmd.xfer_gatherv.sndbuf = buf; gatherv.cmd.xfer_gatherv.stype = PAMI_TYPE_BYTE; gatherv.cmd.xfer_gatherv.stypecount = 0; gatherv.cmd.xfer_gatherv.rcvbuf = rbuf; gatherv.cmd.xfer_gatherv.rtype = PAMI_TYPE_BYTE; gatherv.cmd.xfer_gatherv.rtypecounts = lengths; gatherv.cmd.xfer_gatherv.rdispls = displs; gProtocolName = gatherv_always_works_md[nalg].name; if (my_ep == zero_ep) { printf("# Gatherv Bandwidth Test(size:%zu) -- context = %d, protocol: %s\n",num_tasks, td->tid, gProtocolName); printf("# Size(bytes) iterations bytes/sec usec\n"); printf("# ----------- ----------- ----------- ---------\n"); } if (((strstr(gatherv_always_works_md[nalg].name,gSelected) == NULL) && gSelector) || ((strstr(gatherv_always_works_md[nalg].name,gSelected) != NULL) && !gSelector)) continue; size_t i, j; for (i = gMin_byte_count; i <= gMax_byte_count; i *= 2) { size_t dataSent = i; int niter; size_t k = 0; for (k = 0; k < num_ep; k++) { lengths[k] = i; displs[k] = k * i; } lengths[k-1] = 0; if (dataSent < CUTOFF) niter = gNiterlat; else niter = NITERBW; blocking_coll(myContext, &barrier, &bar_poll_flag); ti = timer(); int ctxt_id = 0; pami_task_t root_task = 0; for (j = 0; j < niter; j++) { pami_endpoint_t root_ep; PAMI_Endpoint_create(client, root_task, ctxt_id, &root_ep); gatherv.cmd.xfer_gatherv.root = root_ep; gather_initialize_sndbuf(td->logical_rank, buf, i); if (root_ep == zero_ep) memset(rbuf, 0xFF, i*num_ep); if (td->logical_rank != num_ep - 1) gatherv.cmd.xfer_gatherv.stypecount = i; blocking_coll(myContext, &gatherv, &gatherv_poll_flag); if (my_ep == zero_ep) { int rc_check; rc |= rc_check = gather_check_rcvbuf(num_tasks-1, rbuf, i); if (rc_check) fprintf(stderr, "%s FAILED validation\n", gProtocolName); } ctxt_id = (ctxt_id + 1)%gNum_contexts; if(ctxt_id == 0) root_task = (root_task +1)%num_tasks; } tf = timer(); blocking_coll(myContext, &barrier, &bar_poll_flag); usec = (tf - ti) / (double)niter; if (my_ep == zero_ep) { printf(" %11lld %16d %14.1f %12.2f\n", (long long)dataSent, niter, (double)1e6*(double)dataSent / (double)usec, usec); fflush(stdout); } } } free(bar_always_works_algo); free(bar_always_works_md); free(bar_must_query_algo); free(bar_must_query_md); free(gatherv_always_works_algo); free(gatherv_always_works_md); free(gatherv_must_query_algo); free(gatherv_must_query_md); buf = (char*)buf - gBuffer_offset; free(buf); rbuf = (char*)rbuf - gBuffer_offset; free(rbuf); free(lengths); free(displs); rc = PAMI_Fence_all (myContext, fence_cb_done, &fence_arrivals); while (fence_arrivals != 0) rc = PAMI_Context_advance (myContext, 1); pthread_exit(NULL); }