/* This tester measures the performance of contended HSLs and pthread mutexes. */ int main(int argc, char **argv) { GASNET_Safe(gex_Client_Init(&myclient, &myep, &myteam, "testlockcontend", &argc, &argv, 0)); GASNET_Safe(gex_Segment_Attach(&mysegment, myteam, TEST_SEGSZ_REQUEST)); test_init("testlockcontend",1,"(maxthreads) (iters) (accuracy) (test sections)"); if (argc > 1) maxthreads = atoi(argv[1]); maxthreads = test_thread_limit(maxthreads); if (maxthreads < 1) { printf("Threads must be between 1 and %i\n", TEST_MAXTHREADS); gasnet_exit(-1); } if (argc > 2) iters = atoi(argv[2]); if (!iters) iters = 1000000; if (argc > 3) accuracy = atoi(argv[3]); if (!accuracy) accuracy = 3; if (argc > 4) TEST_SECTION_PARSE(argv[4]); if (argc > 5) test_usage(); mynode = gex_TM_QueryRank(myteam); myseg = TEST_MYSEG(); if (mynode == 0) { printf("Running locks performance test with 1..%i threads and %i iterations...\n",maxthreads,iters); fflush(stdout); MSG0("Spawning pthreads..."); if (TEST_SECTION_BEGIN_ENABLED()) { header("lock/unlock contended pthread mutex (others in thread barrier)"); test_createandjoin_pthreads(threads = maxthreads, &thread_fn1, NULL, 0); } if (TEST_SECTION_BEGIN_ENABLED()) { header("lock/unlock contended HSL (others in thread barrier)"); test_createandjoin_pthreads(threads = maxthreads, &thread_fn2, NULL, 0); } if (TEST_SECTION_BEGIN_ENABLED()) { header("lock/unlock contended pthread mutex (no other threads)"); for (threads=1; threads<=maxthreads; ++threads) { test_createandjoin_pthreads(threads, &thread_fn3, NULL, 0); } } if (TEST_SECTION_BEGIN_ENABLED()) { header("lock/unlock contended HSL (no other threads)"); for (threads=1; threads<=maxthreads; ++threads) { test_createandjoin_pthreads(threads, &thread_fn4, NULL, 0); } } } BARRIER(); MSG("done."); gasnet_exit(0); return 0; }
void *thread_main(void *arg) { thread_data_t *td = (thread_data_t*) arg; int i; int64_t start,total; #if GASNET_PAR gasnet_image_t *imagearray = test_malloc(nodes * sizeof(gasnet_image_t)); for (i=0; i<nodes; ++i) { imagearray[i] = threads_per_node; } gasnet_coll_init(imagearray, td->mythread, NULL, 0, 0); test_free(imagearray); #else gasnet_coll_init(NULL, 0, NULL, 0, 0); #endif MYBARRIER(); if (td->mythread == 0) { printf("Running barrier test with %i iterations...\n",iters); fflush(stdout); } MYBARRIER(); start = TIME(); for (i=0; i < iters; i++) { gasnet_coll_barrier_notify(GASNET_TEAM_ALL, i, GASNET_BARRIERFLAG_IMAGES); GASNET_Safe(gasnet_coll_barrier_wait(GASNET_TEAM_ALL, i, GASNET_BARRIERFLAG_IMAGES)); } total = TIME() - start; MYBARRIER(); if (td->mythread == 0) { printf("Total time: %8.3f sec Avg Named Barrier latency: %8.3f us\n", ((float)total)/1000000, ((float)total)/iters); fflush(stdout); } MYBARRIER(); start = TIME(); for (i=0; i < iters; i++) { gasnet_coll_barrier_notify(GASNET_TEAM_ALL, 0, GASNET_BARRIERFLAG_ANONYMOUS | GASNET_BARRIERFLAG_IMAGES); GASNET_Safe(gasnet_coll_barrier_wait(GASNET_TEAM_ALL, 0, GASNET_BARRIERFLAG_ANONYMOUS | GASNET_BARRIERFLAG_IMAGES)); } total = TIME() - start; MYBARRIER(); if (td->mythread == 0) { printf("Total time: %8.3f sec Avg Anon. Barrier latency: %8.3f us\n", ((float)total)/1000000, ((float)total)/iters); fflush(stdout); } MYBARRIER(); return NULL; }
void grt_init(int argc, char **argv) { pthread_t thread; /* Set up handler table */ if (!entry_table) { entry_table = grt_entry_table; table_size = GRT_TABLE_SIZE; } /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); /* get SPMD info */ grt_id = gasnet_mynode(); grt_num_procs = gasnet_nodes(); gethostname(grt_proc_name, MAX_PROCESSOR_NAME); /* Attach to network */ GASNET_Safe(gasnet_attach(entry_table, table_size, GASNET_HEAP_SIZE, MINHEAPOFFSET)); if (grt_id == 0) { printf("%s\n", argv[0]); #ifdef GRT_WORD_32 printf("We are on a 32-bit machine.\n"); #else printf("We are on a 64-bit machine.\n"); #endif printf("gasnet_AMMaxMedium()=%lu\n", gasnet_AMMaxMedium()); printf("gasnet_AMMaxLongRequest()=%lu\n", gasnet_AMMaxLongRequest()); printf("gasnet_AMMaxLongReply()=%lu\n", gasnet_AMMaxLongReply()); } fflush(stdout); BARRIER(); fflush(stdout); BARRIER(); /* Get segment info */ grt_seginfo = (gasnet_seginfo_t*) malloc(sizeof(gasnet_seginfo_t) * grt_num_procs); GASNET_Safe(gasnet_getSegmentInfo(grt_seginfo, grt_num_procs)); /* Initialize the heap for memory allocation */ grt_heap_base = grt_addr(grt_id, 0); grt_heap = umalloc_makeheap(grt_heap_base, grt_heap_size, UMALLOC_HEAP_GROWS_UP); /* Spawn off a thread to handle remote handler requests */ pthread_create(&thread, NULL, poll, NULL); /* Set up thread list */ linkedlist_init(&thread_list, 0, 0); BARRIER(); }
/* * @brief sending long message * * we have 3 cases: * (1) the target buffer is big enough to store the message * (2) the target buffer is too small, we need to split the message * (3) the message is too big for long message */ void gasnetSendLongMessage(int targetRank, ocrPolicyMsg_t * message, u64 bufferSize, u64 gasnetId, gasnetCommBlock_t *block, gasnet_handlerarg_t addr_hi, gasnet_handlerarg_t addr_lo, u32 segment_size) { if (block != NULL) { void *address = block->addr; if (block->size > bufferSize) { // case 1 : the destination buffer is big enough for the message GASNET_Safe(gasnet_AMRequestLong4(targetRank, AMHANDLER(gasnetAMMessageLong), message, bufferSize, address, gasnetId, addr_hi, addr_lo, segment_size)); } else { // ---------------------------------------------------------------------------- // case 2: the destination buffer is not big enough, needs to split the message // since gasnet AM long does not guarantee the writing of buffer is // synchronized with the handler invocation, we need to wait until // the partner's handler is ready to receive the next package // ---------------------------------------------------------------------------- gasnetSplitToLong(targetRank, message, bufferSize, gasnetId, block, addr_hi, addr_lo, segment_size); } } else { // case 3: no destination buffer available, use am medium to send message gasnetSplitToMedium(targetRank, message, bufferSize, gasnetId, block, addr_hi, addr_lo, segment_size); } }
/* spin-poll until a request is complete */ void mpi_complete(MPI_Request *handle) { while (1) { if (mpi_test(handle)) return; GASNET_Safe(gasnet_AMPoll()); } }
void test_amlong(threaddata_t *tdata) { int peer = RANDOM_PEER(tdata); int node = tt_thread_map[peer]; void *laddr = tt_addr_map[tdata->tid]; void *raddr = tt_addr_map[peer]; size_t len; do { len = RANDOM_SIZE(); } while ((len > gasnet_AMMaxLongRequest()) || (len > gasnet_AMMaxLongReply()) || (len > TEST_SEGZ_PER_THREAD)); tdata->flag = -1; gasnett_local_wmb(); ACTION_PRINTF("tid=%3d> AMLongRequest (sz=%7d) to tid=%3d", tdata->tid, (int)len, peer); GASNET_Safe(gasnet_AMRequestLong2(node, hidx_ping_longhandler, laddr, len, raddr, tdata->ltid, peer)); GASNET_BLOCKUNTIL(tdata->flag == 0); tdata->flag = -1; ACTION_PRINTF("tid=%3d> AMLongRequest to tid=%3d complete.", tdata->tid, peer); }
int main(int argc, char **argv) { int iters = 0; gasnet_handlerentry_t htable[] = { { 201, chksum_reqh }, { 202, chksum_reph } }; /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); GASNET_Safe(gasnet_attach(htable, sizeof(htable)/sizeof(gasnet_handlerentry_t), TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); test_init("testcore1",0,"(iters)"); assert(CHKSUM_TOTAL <= gasnet_AMMaxMedium()); if (argc > 1) iters = atoi(argv[1]); if (!iters) iters = 1000; if (argc > 2) test_usage(); /* get SPMD info */ chksum_iters = iters; myproc = gasnet_mynode(); numprocs = gasnet_nodes(); /* Only allow even number for numprocs */ if (numprocs % 2 != 0) { MSG("WARNING: This test requires an even number of nodes. Test skipped.\n"); gasnet_exit(0); /* exit 0 to prevent false negatives in test harnesses for smp-conduit */ } peerproc = (myproc % 2) ? myproc-1 : myproc+1; seginfo_table = (gasnet_seginfo_t *) test_malloc(sizeof(gasnet_seginfo_t) * numprocs); printf("%d> starting monoseed_init(%d)\n", myproc, iters); monoseed_init(iters); printf("%d> starting chksums_test(%d)\n", myproc, iters); chksum_test(iters); gasnet_exit(0); return(0); }
/* This tester measures the performance of a number of miscellaneous GASNet functions that don't involve actual communication, to assist in evaluating the overhead of the GASNet layer itself */ int main(int argc, char **argv) { gasnet_handlerentry_t htable[] = { { hidx_null_shorthandler, null_shorthandler }, { hidx_justreply_shorthandler, justreply_shorthandler }, { hidx_null_medhandler, null_medhandler }, { hidx_justreply_medhandler, justreply_medhandler }, { hidx_null_longhandler, null_longhandler }, { hidx_justreply_longhandler, justreply_longhandler } }; GASNET_Safe(gasnet_init(&argc, &argv)); GASNET_Safe(gasnet_attach(htable, sizeof(htable)/sizeof(gasnet_handlerentry_t), TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); test_init("testmisc",1,"(iters) (accuracy_digits) (test_sections)"); mynode = gasnet_mynode(); myseg = TEST_MYSEG(); if (argc > 1) iters = atoi(argv[1]); if (!iters) iters = 100000; if (argc > 2) accuracy = atoi(argv[2]); if (!accuracy) accuracy = 3; if (argc > 3) TEST_SECTION_PARSE(argv[3]); if (argc > 4) test_usage(); if (mynode == 0) { printf("Running misc performance test with %i iterations...\n",iters); printf("%-50s Total time Avg. time\n" "%-50s ---------- ---------\n", "", ""); fflush(stdout); } doit1(); MSG("done."); gasnet_exit(0); return 0; }
void ping_shorthandler(gasnet_token_t token, harg_t idx) { gasnet_node_t node; gasnet_AMGetMsgSource(token, &node); PRINT_AM(("node=%2d> AMShort Request for (%d,%d)", (int)gasnet_mynode(), (int)node, (int)idx)); assert(idx >= 0 && idx < threads_num); assert(node < gasnet_nodes()); GASNET_Safe(gasnet_AMReplyShort1(token, hidx_pong_shorthandler, idx)); }
/* ------------------------------------------------------------------------------------ */ void *doAll(void *ptr) { if (ptr) { if (recvr) GASNET_BLOCKUNTIL(done); } else { doAMShort(); doAMMed(); doAMLong(); doAMLongAsync(); if (recvr) GASNET_Safe(gasnet_AMRequestShort0(mynode, hidx_done_shorthandler)); } return NULL; }
void ping_alonghandler(gasnet_token_t token, void *buf, size_t nbytes, gasnet_handlerarg_t iter, gasnet_handlerarg_t chunkidx) { uint8_t *srcbuf; INIT_CHECKS(); validate_chunk("AsyncLong Request", buf, nbytes, iter, chunkidx); if (INSEG(iter)) srcbuf = buf; else { srcbuf = alongreplysrc+chunkidx*nbytes; memcpy(srcbuf, buf, nbytes); } GASNET_Safe(gasnet_AMReplyLong2(token, hidx_pong_longhandler, srcbuf, nbytes, peerrepseg+(depth+chunkidx)*nbytes, iter, chunkidx)); }
void chksum_test(int iters) { int i; int iamsender, iamreceiver; int received; #ifdef VERBOSE int nloop = 0; #endif iamsender = (myproc % 2 == 0); iamreceiver = !iamsender; BARRIER(); if (iamsender) { for (i = 0; i < iters; i++) GASNET_Safe( gasnet_AMRequestShort2((gasnet_node_t)peerproc, 201, i, _mseed[i].seed)); } while ( (received = gasnett_atomic_read(&chksum_received,0)) < iters ) { /* if (iamreceiver) { if (received % 5 == 0) { printf("sleep 1\n"); sleep(1); } } */ #ifdef VERBOSE nloop++; if (nloop % 1000 == 0) { printf("TEST[%d] nloop = %d chksum_received = %d\n", myproc,nloop,received); } #endif gasnet_AMPoll(); } #ifdef VERBOSE printf("TEST[%d] COMPLETE: nloop = %d chksum_received = %d\n", myproc,nloop,received); #endif BARRIER(); if (iamsender) { int success = gasnett_atomic_read(&chksum_success,0); printf("chksum_test(%d) passed %d/%d\n", chksum_iters, success, received); } }
/* * Format is * AMRequestShort2(dest, chksum_reqh, i, seed) * * chksum_reqh(i, seed) generates the checksum and replies with a Medium * * AMReplyMedium(token, chksum_reph, src, nbytes, i) * * chksum_reph(i, src, nbytes) compares src[nbytes] to its copy of the * checksum at i */ void chksum_reqh(gasnet_token_t token, gasnet_handlerarg_t iter, gasnet_handlerarg_t seed) { unsigned char chksum_reqbuf[CHKSUM_TOTAL]; gasnett_atomic_increment(&chksum_received, 0); chksum_gen(seed, &chksum_reqbuf); monoseed_trace(iter, seed, &chksum_reqbuf, NULL); GASNET_Safe( gasnet_AMReplyMedium1(token, 202, &chksum_reqbuf, CHKSUM_TOTAL, iter)); return; }
void test_amshort(threaddata_t *tdata) { int peer = RANDOM_PEER(tdata); int node = tt_thread_map[peer]; ACTION_PRINTF("tid=%3d> AMShortRequest to tid=%3d", tdata->tid, peer); tdata->flag = -1; gasnett_local_wmb(); GASNET_Safe(gasnet_AMRequestShort1(node, hidx_ping_shorthandler, tdata->ltid)); GASNET_BLOCKUNTIL(tdata->flag == 0); tdata->flag = -1; ACTION_PRINTF("tid=%3d> AMShortRequest to tid=%3d complete.", tdata->tid, peer); }
void mpi_probehandler(gasnet_token_t token, harg_t tid) { gasnet_node_t node; int mpipeer; int tag; int reply = 0; gasnet_AMGetMsgSource(token, &node); assert(tt_thread_map[tid] == node); mpipeer = gasnetnode_to_mpirank[node]; tag = tid; MPI_LOCK(); if (mpi_recvhandle[tid] != MPI_REQUEST_NULL) { MPI_Status status; int flag = 0; MPI_SAFE(MPI_Test(&mpi_recvhandle[tid],&flag,&status)); if (flag) { int sz = mpi_bufsz[tid]; assert(mpi_recvhandle[tid] == MPI_REQUEST_NULL); assert(mpi_sendhandle[tid] == MPI_REQUEST_NULL); assert(mpi_buf[tid] != NULL && sz >= 0); ACTION_PRINTF("node=%2d> sending MPI reply message, %i bytes\n", (int)gasnet_mynode(), sz); MPI_SAFE(MPI_Isend(mpi_buf[tid], sz, MPI_BYTE, mpipeer, 10000+tag, MPI_COMM_WORLD, &(mpi_sendhandle[tid]))); assert(mpi_sendhandle[tid] != MPI_REQUEST_NULL); } } else if (mpi_sendhandle[tid] != MPI_REQUEST_NULL) { MPI_Status status; int flag = 0; MPI_SAFE(MPI_Test(&mpi_sendhandle[tid],&flag,&status)); if (flag) { assert(mpi_recvhandle[tid] == MPI_REQUEST_NULL); assert(mpi_sendhandle[tid] == MPI_REQUEST_NULL); reply = 1; } } else { /* nothing to do */ } MPI_UNLOCK(); if (reply) { assert(mpi_buf[tid] != NULL); test_free(mpi_buf[tid]); mpi_buf[tid] = NULL; PRINT_AM(("node=%2d> Sending AMShort MPI Reply for tid=%i\n", (int)gasnet_mynode(), (int)tid)); GASNET_Safe(gasnet_AMReplyShort1(token, hidx_mpi_replyhandler, tid)); } }
void ping_medhandler(gasnet_token_t token, void *buf, size_t nbytes, harg_t idx) { gasnet_node_t node; gasnet_AMGetMsgSource(token, &node); PRINT_AM(("node=%2d> AMMedium Request for (%d,%d)", (int)gasnet_mynode(), (int)node, (int)idx)); assert(idx >= 0 && idx < threads_num); assert(node < gasnet_nodes()); assert(nbytes <= gasnet_AMMaxMedium()); assert((uintptr_t)buf+nbytes < (uintptr_t)TEST_SEG(gasnet_mynode()) || (uintptr_t)buf >= (uintptr_t)TEST_SEG(gasnet_mynode()) + TEST_SEGSZ); GASNET_Safe( gasnet_AMReplyMedium1(token, hidx_pong_medhandler, buf, nbytes, idx)); }
void ping_longhandler(gasnet_token_t token, void *buf, size_t nbytes, harg_t idx, harg_t target_id) { int tid; void *paddr; gasnet_node_t node; gasnet_AMGetMsgSource(token, &node); tid = node * threads_num + idx; paddr = tt_addr_map[tid]; PRINT_AM(("node=%2d> AMLong Request for (%d,%d)", (int)gasnet_mynode(), (int)node, (int)idx)); assert(idx >= 0 && idx < threads_num); assert(node < gasnet_nodes()); assert(nbytes <= gasnet_AMMaxLongRequest()); assert(buf == tt_addr_map[target_id]); assert((uintptr_t)buf + nbytes <= (uintptr_t)TEST_SEG(gasnet_mynode()) + TEST_SEGSZ); GASNET_Safe( gasnet_AMReplyLong1(token, hidx_pong_longhandler, buf, nbytes, paddr, idx)); }
void test_ammedium(threaddata_t *tdata) { int peer = RANDOM_PEER(tdata); int node = tt_thread_map[peer]; void *laddr = tt_addr_map[tdata->tid]; size_t len; do { len = RANDOM_SIZE(); } while (len > gasnet_AMMaxMedium()); ACTION_PRINTF("tid=%3d> AMMediumRequest (sz=%7d) to tid=%3d", tdata->tid, (int)len, peer); tdata->flag = -1; gasnett_local_wmb(); GASNET_Safe(gasnet_AMRequestMedium1(node, hidx_ping_medhandler, laddr, len, tdata->ltid)); GASNET_BLOCKUNTIL(tdata->flag == 0); tdata->flag = -1; ACTION_PRINTF("tid=%3d> AMMediumRequest to tid=%3d complete.", tdata->tid, peer); }
int main(int argc, char **argv) { int help=0; int arg=1; gasnet_handlerentry_t htable[] = { { hidx_ping_shorthandler, ping_shorthandler }, { hidx_pong_shorthandler, pong_shorthandler }, { hidx_ping_medhandler, ping_medhandler }, { hidx_pong_medhandler, pong_medhandler }, { hidx_ping_longhandler, ping_longhandler }, { hidx_pong_longhandler, pong_longhandler }, { hidx_ping_shorthandler_flood, ping_shorthandler_flood }, { hidx_pong_shorthandler_flood, pong_shorthandler_flood }, { hidx_ping_medhandler_flood, ping_medhandler_flood }, { hidx_pong_medhandler_flood, pong_medhandler_flood }, { hidx_ping_longhandler_flood, ping_longhandler_flood }, { hidx_pong_longhandler_flood, pong_longhandler_flood }, { hidx_done_shorthandler, done_shorthandler } }; GASNET_Safe(gasnet_init(&argc, &argv)); mynode = gasnet_mynode(); numnode = gasnet_nodes(); arg = 1; while (argc > arg) { if (!strcmp(argv[arg], "-p")) { #if GASNET_PAR pollers = test_thread_limit(atoi(argv[arg+1])+1)-1; arg += 2; #else if (0 == mynode) { fprintf(stderr, "testam %s\n", GASNET_CONFIG_STRING); fprintf(stderr, "ERROR: The -p option is only available in the PAR configuration.\n"); fflush(NULL); } sleep(1); gasnet_exit(1); #endif } else if (!strcmp(argv[arg], "-in")) { insegment = 1; ++arg; } else if (!strcmp(argv[arg], "-out")) { insegment = 0; ++arg; } else if (!strcmp(argv[arg], "-c")) { crossmachinemode = 1; ++arg; } else if (!strcmp(argv[arg], "-src-noop")) { src_mode = SRC_NOOP; ++arg; } else if (!strcmp(argv[arg], "-src-generate")) { src_mode = SRC_GENERATE; ++arg; } else if (!strcmp(argv[arg], "-src-memcpy")) { src_mode = SRC_MEMCPY; ++arg; } else if (argv[arg][0] == '-') { help = 1; ++arg; } else break; } if (argc > arg) { iters = atoi(argv[arg]); ++arg; } if (!iters) iters = 1000; if (argc > arg) { maxsz = atoi(argv[arg]); ++arg; } if (!maxsz) maxsz = 2*1024*1024; if (argc > arg) { TEST_SECTION_PARSE(argv[arg]); ++arg; } GASNET_Safe(gasnet_attach(htable, sizeof(htable)/sizeof(gasnet_handlerentry_t), TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); #if GASNET_PAR #define PAR_USAGE \ " The -p option gives the number of polling threads, specified as\n" \ " a non-negative integer argument (default is no polling threads).\n" #else #define PAR_USAGE "" #endif test_init("testam", 1, "[options] (iters) (maxsz) (test_sections)\n" " The '-in' or '-out' option selects whether the requestor's\n" " buffer is in the GASNet segment or not (default is 'in').\n" PAR_USAGE " The '-src-*' options select treatment of the payload buffer used for\n" " Medium and Long AMs, as follows:\n" " -src-noop: no per-operation initialization (default)\n" " -src-generate: initialized (w/o memory reads) on each AM injection\n" " -src-memcpy: initialized using memcpy() on each AM injection\n" " The -c option enables cross-machine pairing (default is nearest neighbor).\n"); if (help || argc > arg) test_usage(); TEST_PRINT_CONDUITINFO(); if (insegment) { myseg = TEST_MYSEG(); } else { char *space = test_malloc(alignup(maxsz,PAGESZ) + PAGESZ); myseg = alignup_ptr(space, PAGESZ); } maxmed = MIN(maxsz, gasnet_AMMaxMedium()); maxlongreq = MIN(maxsz, gasnet_AMMaxLongRequest()); maxlongrep = MIN(maxsz, gasnet_AMMaxLongReply()); if (src_mode == SRC_MEMCPY) { zero_buffer = test_calloc(maxsz, 1); } if (crossmachinemode) { if ((numnode%2) && (mynode == numnode-1)) { sender = 1; peer = mynode; } else { gasnet_node_t half = numnode / 2; sender = (mynode < half); peer = sender ? (mynode + half) : (mynode - half); } } else { peer = mynode ^ 1; sender = mynode % 2 == 0; if (peer == numnode) { peer = mynode; } } recvr = !sender || (peer == mynode); // Long Request and Reply (distinct for loopback) reply_addr = TEST_SEG(peer); request_addr = (peer == mynode) ? (void*)((uintptr_t)reply_addr + alignup(maxsz,SIZEOF_GASNET_REGISTER_VALUE_T)) : reply_addr; BARRIER(); #if GASNET_PAR #define PAR_FMT " %i extra recvr polling threads\n" #define PAR_ARG ,pollers #else #define PAR_FMT /*empty*/ #define PAR_ARG /*empty*/ #endif if (mynode == 0) { printf("Running %i iterations of %s AM performance with:\n" " local addresses %sside the segment%s\n" " %s\n" PAR_FMT " ...\n", iters, (crossmachinemode ? "cross-machine ": ""), (insegment ? "in" : "out"), (insegment ? " (default)" : ""), ((src_mode == SRC_NOOP) ? "no payload initialization (default)" :(src_mode == SRC_GENERATE) ? "payload initialized by computation" : "payload initialized using memcpy()") PAR_ARG ); printf(" Msg Sz Description Total time Avg. time Bandwidth\n" " ------ ----------- ---------- --------- ---------\n"); fflush(stdout); } #if GASNET_PAR TEST_SET_WAITMODE(pollers+1); if (pollers) test_createandjoin_pthreads(pollers+1,doAll,NULL,0); else #endif doAll(NULL); MSG("done."); gasnet_exit(0); return 0; }
void *doit(void *id) { gasnett_threadkey_set(mythread,id); if ((uintptr_t)id != 0) { /* additional threads polling, to encourage handler concurrency */ while (!done) { gasnet_AMPoll(); gasnett_sched_yield(); } return 0; } MSG0("Running %sAM%s%s%s%s correctness test %s%swith %i iterations, max_payload=%i, depth=%i...", #if GASNET_PAR (domultith?"multi-threaded ":"single-threaded "), #else "", #endif (amopt?(domed?" Medium":""):""),(amopt?(dolong?" Long":""):""),(amopt?(dolongasync?" LongAsync":""):""), ((doinseg^dooutseg)?(doinseg?" in-segment":" out-of-segment"):""), (dosizesync?"":"loosely-synced "), (doprime?"with priming ":""), iters,max_payload,depth); BARRIER(); if (doprime) { /* issue some initial puts that cover the Long regions, to try and trigger dynamic pinning */ int chunkidx; for (chunkidx = 0; chunkidx < depth; chunkidx++) { /* AMRequestLong primer */ gasnet_put(peerproc, peerreqseg+chunkidx*max_payload, privateseg+chunkidx*max_payload, max_payload); gasnet_put(peerproc, peerreqseg+chunkidx*max_payload, localseg+chunkidx*max_payload, max_payload); /* AMRequestLongAsync primer */ gasnet_put(peerproc, peerreqseg+(depth+chunkidx)*max_payload, privateseg+chunkidx*max_payload, max_payload); gasnet_put(peerproc, peerreqseg+(depth+chunkidx)*max_payload, localseg+chunkidx*max_payload, max_payload); /* AMReplyLong primer */ gasnet_put(peerproc, peerrepseg+chunkidx*max_payload, myseg+chunkidx*max_payload, max_payload); gasnet_put(peerproc, peerrepseg+chunkidx*max_payload, longreplysrc+chunkidx*max_payload, max_payload); /* AMReplyLongAsync primer */ gasnet_put(peerproc, peerrepseg+(depth+chunkidx)*max_payload, myseg+(depth+chunkidx)*max_payload, max_payload); gasnet_put(peerproc, peerrepseg+(depth+chunkidx)*max_payload, alongreplysrc+chunkidx*max_payload, max_payload); } BARRIER(); } { int sz,iter,savesz = 1; int max1 = gasnet_AMMaxMedium(), max2 = maxlong; if (maxlong < gasnet_AMMaxMedium()) { max1 = maxlong; max2 = gasnet_AMMaxMedium(); } assert_always(max1 <= max2); for (sz = 1; sz <= max_payload; ) { if (dosizesync) BARRIER(); /* optional barrier, to synchronize tests at each payload size across nodes */ MSG0("payload = %i",sz); for (iter = 0; iter < iters; iter++) { int chunkidx; uint8_t *srcseg = ITERSEG(iter); /* initialize local seg to known values */ for (chunkidx = 0; chunkidx < depth; chunkidx++) { init_chunk(srcseg,sz,iter,chunkidx); } if (domed && sz <= gasnet_AMMaxMedium()) { /* test Medium AMs */ gasnett_atomic_set(&pong_recvd,0,0); for (chunkidx = 0; chunkidx < depth; chunkidx++) { GASNET_Safe(gasnet_AMRequestMedium2(peerproc, hidx_ping_medhandler, srcseg+chunkidx*sz, sz, iter, chunkidx)); } /* wait for completion */ GASNET_BLOCKUNTIL(gasnett_atomic_read(&pong_recvd,0) == depth); } if (sz <= maxlong) { if (dolong) { /* test Long AMs */ gasnett_atomic_set(&pong_recvd,0,0); for (chunkidx = 0; chunkidx < depth; chunkidx++) { GASNET_Safe(gasnet_AMRequestLong2(peerproc, hidx_ping_longhandler, srcseg+chunkidx*sz, sz, peerreqseg+chunkidx*sz, iter, chunkidx)); } /* wait for completion */ GASNET_BLOCKUNTIL(gasnett_atomic_read(&pong_recvd,0) == depth); } if (dolongasync) { /* test AsyncLong AMs */ gasnett_atomic_set(&pong_recvd,0,0); for (chunkidx = 0; chunkidx < depth; chunkidx++) { GASNET_Safe(gasnet_AMRequestLongAsync2(peerproc, hidx_ping_alonghandler, srcseg+chunkidx*sz, sz, peerreqseg+(depth+chunkidx)*sz, iter, chunkidx)); } /* wait for completion */ GASNET_BLOCKUNTIL(gasnett_atomic_read(&pong_recvd,0) == depth); } } } /* double sz each time, but make sure to also exactly hit MaxMedium, MaxLong and max payload */ if (sz < max1 && savesz * 2 > max1) sz = max1; else if (sz < max2 && savesz * 2 > max2) sz = max2; else if (sz < max_payload && savesz * 2 > max_payload) sz = max_payload; else { sz = savesz * 2; savesz = sz; } } } BARRIER(); done = 1; return(0); }
/* ------------------------------------------------------------------------------------ */ void ping_shorthandler_flood(gasnet_token_t token) { GASNET_Safe(gasnet_AMReplyShort0(token, hidx_pong_shorthandler_flood)); }
int main(int argc, char **argv) { int mynode, nodes, iters=0; int64_t start,total; int i = 0; gasnet_node_t nrows, ncols, my_row, my_col; void *clientdata = NULL; gasnet_team_handle_t my_row_team, my_col_team; static uint8_t *A, *B; gasnet_seginfo_t teamA_scratch; gasnet_seginfo_t teamB_scratch; gasnet_seginfo_t const * test_segs; GASNET_Safe(gasnet_init(&argc, &argv)); GASNET_Safe(gasnet_attach(NULL, 0, TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); #if !GASNET_SEQ MSG0("WARNING: This test does not work for NON-SEQ builds yet.. skipping test\n"); gasnet_exit(0); #endif A = TEST_MYSEG(); gasnet_coll_init(NULL, 0, NULL, 0, 0); test_init("testteam", 1, "(iters) (nrows) (ncols)"); mynode = gasnet_mynode(); nodes = gasnet_nodes(); test_segs = TEST_SEGINFO(); teamA_scratch.addr = test_segs[mynode].addr; teamA_scratch.size = test_segs[mynode].size/2; teamB_scratch.addr = (uint8_t*)teamA_scratch.addr + teamA_scratch.size; teamB_scratch.size = teamA_scratch.size; if (argc > 4) test_usage(); if (argc > 1) iters = atoi(argv[1]); if (!iters) iters = 10000; if (argc > 2) { nrows = atoi(argv[2]); } else { /* search for as near to square as possible */ nrows = sqrt(nodes); while (nodes % nrows) --nrows; } if (argc > 3) { ncols = atoi(argv[3]); } else { ncols = nodes / nrows; } assert_always(nrows*ncols == nodes); MSG0("Running team test with a %u-by-%u grid and %i iterations...\n", (int)nrows, (int)ncols, iters); BARRIER(); my_row = mynode / ncols; my_col = mynode % ncols; my_row_team = gasnet_coll_team_split(GASNET_TEAM_ALL, my_row, my_col, &teamA_scratch); my_col_team = gasnet_coll_team_split(GASNET_TEAM_ALL, my_col, my_row, &teamB_scratch); if (my_col == 0) { printf("row team %u: Running team barrier test with row teams...\n", (int)my_row); fflush(stdout); } BARRIER(); start = TIME(); for (i=0; i < iters; i++) { gasnete_coll_teambarrier_notify(my_row_team); gasnete_coll_teambarrier_wait(my_row_team); } total = TIME() - start; if (my_col == 0) { printf("row team %u: total time: %8.3f sec, avg row team Barrier latency: %8.3f us\n", (int)my_row, ((float)total)/1000000, ((float)total)/iters); fflush(stdout); } if (my_row == 0) { printf("col team %u: Running team barrier test with column teams...\n", (int)my_col); fflush(stdout); } BARRIER(); start = TIME(); for (i=0; i < iters; i++) { gasnete_coll_teambarrier_notify(my_col_team); gasnete_coll_teambarrier_wait(my_col_team); } total = TIME() - start; if (my_row == 0) { printf("col team %u: total time: %8.3f sec Avg column team Barrier latency: %8.3f us\n", (int)my_col, ((float)total)/1000000, ((float)total)/iters); fflush(stdout); } BARRIER(); MSG("done."); gasnet_exit(0); /* for faster exit */ return 0; }
int main(int argc, char **argv) { int arg = 1, help = 0; gasnet_handlerentry_t htable[] = { { hidx_ping_medhandler, ping_medhandler }, { hidx_pong_medhandler, pong_medhandler }, { hidx_ping_longhandler, ping_longhandler }, { hidx_pong_longhandler, pong_longhandler }, { hidx_ping_alonghandler, ping_alonghandler }, }; /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); #define AMOPT() if (!amopt) { amopt = 1; domed = 0; dolong = 0; dolongasync = 0; } while (argc > arg) { if (!strcmp(argv[arg], "-p")) { doprime = 1; ++arg; } else if (!strcmp(argv[arg], "-u")) { dosizesync = 0; ++arg; } else if (!strcmp(argv[arg], "-s")) { domultith = 0; ++arg; } else if (!strcmp(argv[arg], "-n")) { allowretry = 0; ++arg; } else if (!strcmp(argv[arg], "-in")) { doinseg = 1; dooutseg = 0; ++arg; } else if (!strcmp(argv[arg], "-out")) { doinseg = 0; dooutseg = 1; ++arg; } else if (!strcmp(argv[arg], "-m")) { AMOPT(); domed = 1; ++arg; } else if (!strcmp(argv[arg], "-l")) { AMOPT(); dolong = 1; ++arg; } else if (!strcmp(argv[arg], "-a")) { AMOPT(); dolongasync = 1; ++arg; } else if (argv[arg][0] == '-') { help = 1; ++arg; } else break; } if (argc > arg) { iters = atoi(argv[arg]); arg++; } if (!iters) iters = 10; if (argc > arg) { max_payload = atoi(argv[arg]); arg++; } if (!max_payload) max_payload = 1024*1024; if (argc > arg) { depth = atoi(argv[arg]); arg++; } if (!depth) depth = 16; /* round down to largest payload AM allows */ maxlong = MIN(gasnet_AMMaxLongRequest(),gasnet_AMMaxLongReply()); max_payload = MIN(max_payload,MAX(gasnet_AMMaxMedium(),maxlong)); GASNET_Safe(gasnet_attach(htable, sizeof(htable)/sizeof(gasnet_handlerentry_t), TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); test_init("testcore2",0,"[options] (iters) (max_payload) (depth)\n" " -m test AMMedium (defaults to all types)\n" " -l test AMLong (defaults to all types)\n" " -a test AMLongAsync (defaults to all types)\n" " -p prime the AMLong transfer areas with puts, to encourage pinning\n" " -u loosen sychronization to allow diff payload sizes to be in flight at once\n" " -s single-threaded PAR mode (default is to start a polling thread in PAR mode)\n" " -n no retry on failure\n" " -in/-out use only in- or out-of-segment sources for AMLong(Async) (default is both)\n" ); if (help || argc > arg) test_usage(); TEST_PRINT_CONDUITINFO(); /* get SPMD info */ myproc = gasnet_mynode(); numprocs = gasnet_nodes(); peerproc = myproc ^ 1; if (peerproc == gasnet_nodes()) { /* w/ odd # of nodes, last one talks to self */ peerproc = myproc; } myseg = TEST_MYSEG(); peerreqseg = TEST_SEG(peerproc); peerrepseg = peerreqseg+max_payload*depth*2; localseg = myseg + max_payload*depth*4; assert_always(TEST_SEGSZ >= max_payload*depth*5); privateseg = test_malloc(max_payload*depth*3); /* out-of-seg request src, long reply src, along reply src */ longreplysrc = privateseg+max_payload*depth; alongreplysrc = privateseg+max_payload*depth*2; #ifdef GASNET_PAR if (domultith) test_createandjoin_pthreads(2,doit,NULL,0); else #endif doit(0); BARRIER(); test_free(privateseg); MSG("done. (detected %i errs)", test_errs); gasnet_exit(test_errs > 0 ? 1 : 0); return 0; }
void ping_medhandler(gasnet_token_t token, void *buf, size_t nbytes, gasnet_handlerarg_t iter, gasnet_handlerarg_t chunkidx) { INIT_CHECKS(); validate_chunk("Medium Request", buf, nbytes, iter, chunkidx); GASNET_Safe(gasnet_AMReplyMedium2(token, hidx_pong_medhandler, buf, nbytes, iter, chunkidx)); }
int main(int argc, char **argv) { /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); /* parse arguments */ arg = 1; while (argc > arg) { if (!strcmp(argv[arg], "-in")) { insegment = 1; ++arg; } else if (!strcmp(argv[arg], "-out")) { insegment = 0; ++arg; } else if (!strcmp(argv[arg], "-f")) { firstlastmode = 1; ++arg; } else if (!strcmp(argv[arg], "-a")) { fullduplexmode = 1; ++arg; } else if (!strcmp(argv[arg], "-p")) { do_puts = 1; numflavors++; ++arg; } else if (!strcmp(argv[arg], "-g")) { do_gets = 1; numflavors++; ++arg; } else if (!strcmp(argv[arg], "-s")) { do_amshort = 1; numflavors++; ++arg; } else if (!strcmp(argv[arg], "-m")) { do_ammedium = 1; numflavors++; ++arg; } else if (!strcmp(argv[arg], "-l")) { do_amlong = 1; numflavors++; ++arg; } else if (!strcmp(argv[arg], "-b")) { do_bulk = 1; ++arg; } else if (!strcmp(argv[arg], "-n")) { do_nonbulk = 1; ++arg; } else if (!strcmp(argv[arg], "-v")) { do_value = 1; ++arg; } else if (!strcmp(argv[arg], "-i")) { do_implicit = 1; numsync++; ++arg; } else if (!strcmp(argv[arg], "-e")) { do_explicit = 1; numsync++; ++arg; } else if (!strcmp(argv[arg], "-k")) { do_blocking = 1; numsync++; ++arg; } else if (argv[arg][0] == '-') { help = 1; ++arg; } else break; } if (fullduplexmode && firstlastmode) help = 1; if (argc > arg+3) help = 1; if (argc > arg) { iters = atoi(argv[arg]); arg++; } if (!iters) iters = 10; if (argc > arg) { maxdepth = atoi(argv[arg]); arg++; } if (!maxdepth) maxdepth = 1024; /* 1024 default */ if (argc > arg) { maxsz = atoi(argv[arg]); arg++; } if (!maxsz) maxsz = 2*1024*1024; /* 2 MB default */ #ifdef GASNET_SEGMENT_EVERYTHING if (maxsz > TEST_SEGSZ) { MSG("maxsz must be <= %lu on GASNET_SEGMENT_EVERYTHING",(unsigned long)TEST_SEGSZ); gasnet_exit(1); } #endif GASNET_Safe(gasnet_attach(htable, sizeof(htable)/sizeof(gasnet_handlerentry_t), TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); test_init("testqueue",1,"[-in|-out|-a|-f] (iters) (maxdepth) (maxsz)\n" " The 'in' or 'out' option selects whether the initiator-side\n" " memory is in the GASNet segment or not (default is not).\n" " The -a option enables full-duplex mode, where all nodes send.\n" " The -f option enables 'first/last' mode, where the first node\n" " sends to the last, while all other nodes sit idle.\n" " Test types to run: (defaults to everything)\n" " -p : puts\n" " -g : gets\n" " -s : AMShort\n" " -m : AMMedium\n" " -l : AMLong\n" " -n : Test non-bulk put/gets\n" " -b : Test bulk put/gets\n" " -v : Test value-based put/gets\n" " -i : Test implicit-handle put/gets\n" " -e : Test explicit-handle put/gets\n" " -k : Test blocking put/gets\n"); if (help) test_usage(); min_payload = 1; max_payload = maxsz; if (numflavors == 0) { /* default to all */ do_puts = 1; do_gets = 1; do_amshort = 1; do_ammedium = 1; do_amlong = 1; } if (numsync == 0) { /* default to all */ do_implicit = 1; do_explicit = 1; do_blocking = 1; } if (!do_bulk && !do_nonbulk && !do_value) { do_bulk = 1; do_nonbulk = 1; do_value = 1; } if (!do_implicit && !do_explicit && !do_blocking) { do_implicit = 1; do_explicit = 1; do_blocking = 1; } if (max_payload < min_payload) { printf("ERROR: maxsz must be >= %i\n",min_payload); gasnet_exit(1); } /* get SPMD info */ myproc = gasnet_mynode(); numprocs = gasnet_nodes(); if (!firstlastmode) { /* Only allow 1 or even number for numprocs */ if (numprocs > 1 && numprocs % 2 != 0) { MSG0("WARNING: This test requires a unary or even number of nodes. Test skipped.\n"); gasnet_exit(0); /* exit 0 to prevent false negatives in test harnesses for smp-conduit */ } } /* Setting peer thread rank */ if (firstlastmode) { peerproc = numprocs-1; iamsender = (myproc == 0); iamrecver = (myproc == numprocs-1); multisender = 0; } else if (numprocs == 1) { peerproc = 0; iamsender = 1; iamrecver = 1; multisender = 0; } else { peerproc = (myproc % 2) ? (myproc - 1) : (myproc + 1); iamsender = (fullduplexmode || myproc % 2 == 0); iamrecver = (fullduplexmode || !iamsender); multisender = (fullduplexmode || numprocs >= 4); } multisender = 1; /* messes up output on some systems */ myseg = TEST_SEG(myproc); tgtmem = TEST_SEG(peerproc); if (insegment) { msgbuf = (void *) myseg; } else { alloc = (void *) test_calloc(maxsz+PAGESZ,1); /* use calloc to prevent valgrind warnings */ msgbuf = (void *) alignup(((uintptr_t)alloc), PAGESZ); /* ensure page alignment of base */ } assert(((uintptr_t)msgbuf) % PAGESZ == 0); MSG0("Running %squeue test with local addr %sside segment, iters=%i, maxdepth=%i, sz: %i...%i", firstlastmode ? "first/last " : (fullduplexmode ? "full-duplex ": ""), insegment ? "in" : "out", iters, maxdepth, min_payload, max_payload); MSG0("x-axis: queue depth, y-axis: message size, injection time in microseconds\n"); BARRIER(); handles = (gasnet_handle_t *) test_malloc(sizeof(gasnet_handle_t) * maxdepth); vghandles = (gasnet_valget_handle_t *) test_malloc(sizeof(gasnet_valget_handle_t) * maxdepth); do_bulkputgets(); do_nonbulkputgets(); do_valueputgets(); do_blockingputgets(); do_amtests(); BARRIER(); test_free(handles); if (!insegment) { test_free(alloc); } gasnet_exit(0); return 0; }
int main(int argc, char **argv) { static int *A, *B, *C, *D, *E, *F, *G; gasnet_node_t myproc, i; int j; /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); if (argc > 1) { iters = atoi(argv[1]); } if (iters < 1) { iters = 1000; } #if GASNET_PAR if (argc > 2) { threads = atoi(argv[2]); } threads = test_thread_limit(threads); if (threads < 1) { printf("ERROR: Threads must be between 1 and %d\n", TEST_MAXTHREADS); exit(EXIT_FAILURE); } #endif /* get SPMD info */ myproc = gasnet_mynode(); numprocs = gasnet_nodes(); images = numprocs * threads; datasize = iters * (3 + 4 * images); GASNET_Safe(gasnet_attach(NULL, 0, TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); test_init("testcoll",0,"(iters) (threadcnt)"); TEST_SET_WAITMODE(threads); if (argc > 3) test_usage(); MSG0("Running coll test(s) with %d iterations.", iters); R = test_malloc(iters*sizeof(int)); TEST_SRAND(1); /* Number if ints to store */ /* Carve some variables out of the (aligned) segment: */ Aw = test_malloc(iters * sizeof(int *)); Bw = test_malloc(iters * sizeof(int *)); Cw = test_malloc(iters * sizeof(int *)); Dw = test_malloc(iters * sizeof(int *)); Ew = test_malloc(iters * sizeof(int *)); Fw = test_malloc(iters * sizeof(int *)); Gw = test_malloc(iters * sizeof(int *)); A = (int *)TEST_MYSEG(); /* int [1*iters] */ B = A + 1*iters; /* int [1*iters] */ C = B + 1*iters; /* int [N*iters] */ D = C + images*iters; /* int [N*iters] */ E = D + images*iters; /* int [1*iters] */ F = E + 1*iters; /* int [N*iters] */ G = F + images*iters; /* int [N*iters] */ for (j = 0; j < iters; ++j) { Aw[j] = A + j; Bw[j] = B + j; Cw[j] = C + j*images; Dw[j] = D + j*images; Ew[j] = E + j; Fw[j] = F + j*images; Gw[j] = G + j*images; } /* The unaligned equivalents */ Av = test_malloc_2D(iters, images * sizeof(int *)); Bv = test_malloc_2D(iters, images * sizeof(int *)); Cv = test_malloc_2D(iters, images * sizeof(int *)); Dv = test_malloc_2D(iters, images * sizeof(int *)); Ev = test_malloc_2D(iters, images * sizeof(int *)); Fv = test_malloc_2D(iters, images * sizeof(int *)); Gv = test_malloc_2D(iters, images * sizeof(int *)); for (i = 0; i < images; ++i) { /* Using (TEST_SEG(n) + n) yields unaligned even when the segments are aligned. This is to help catch any case where addresses might have been misused that might go undetected if the addresses were aligned */ A = (int *)TEST_SEG(i/threads) + (i/threads) + datasize*(i%threads); B = A + 1*iters; C = B + 1*iters; D = C + images*iters; E = D + images*iters; F = E + 1*iters; G = F + images*iters; for (j = 0; j < iters; ++j) { Av[j][i] = A + j; Bv[j][i] = B + j; Cv[j][i] = C + j*images; Dv[j][i] = D + j*images; Ev[j][i] = E + j; Fv[j][i] = F + j*images; Gv[j][i] = G + j*images; } } BARRIER(); #if GASNET_PAR MSG("Forking %d gasnet threads", threads); { int i; thread_data_t* tt_thread_data = test_malloc(threads*sizeof(thread_data_t)); for (i = 0; i < threads; i++) { tt_thread_data[i].myproc = myproc; tt_thread_data[i].local_id = i; tt_thread_data[i].mythread = i + threads * myproc; tt_thread_data[i].peerthread = i + threads * (((myproc ^ 1) == numprocs) ? myproc : (myproc ^ 1)); } test_createandjoin_pthreads(threads, &thread_main, tt_thread_data, sizeof(tt_thread_data[0])); test_free(tt_thread_data); } #else { thread_data_t td; td.myproc = myproc; td.local_id = 0; td.mythread = myproc; td.peerthread = ((myproc ^ 1) == numprocs) ? myproc : (myproc ^ 1); thread_main(&td); } #endif BARRIER(); test_free(Aw); test_free(Bw); test_free(Cw); test_free(Dw); test_free_2D(Av); test_free_2D(Bv); test_free_2D(Cv); test_free_2D(Dv); test_free(R); MSG("done."); gasnet_exit(0); return 0; }
/* ------------------------------------------------------------------------------------ */ void doAMShort(void) { GASNET_BEGIN_FUNCTION(); if (sender) { /* warm-up */ flag = 0; for (i=0; i < iters; i++) { GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_ping_shorthandler_flood)); } GASNET_BLOCKUNTIL(flag == iters); GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_ping_shorthandler)); GASNET_BLOCKUNTIL(flag == iters+1); } BARRIER(); /* ------------------------------------------------------------------------------------ */ if (TEST_SECTION_BEGIN_ENABLED() && sender) { int64_t start = TIME(); flag = -1; for (i=0; i < iters; i++) { GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_ping_shorthandler)); GASNET_BLOCKUNTIL(flag == i); } report(" AMShort ping-pong roundtrip ReqRep",TIME() - start, iters, 0, 1); } BARRIER(); /* ------------------------------------------------------------------------------------ */ if (TEST_SECTION_ENABLED()) { int64_t start = TIME(); flag = -1; BARRIER(); if (sender && recvr) { assert(peer == mynode); for (i=0; i < iters; i++) { int lim = i << 1; GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_pong_shorthandler)); GASNET_BLOCKUNTIL(flag == lim); lim++; GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_pong_shorthandler)); GASNET_BLOCKUNTIL(flag == lim); } } else if (sender) { for (i=0; i < iters; i++) { GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_pong_shorthandler)); GASNET_BLOCKUNTIL(flag == i); } } else if (recvr) { for (i=0; i < iters; i++) { GASNET_BLOCKUNTIL(flag == i); GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_pong_shorthandler)); } } report(" AMShort ping-pong roundtrip ReqReq",TIME() - start, iters, 0, 1); if (mynode == 0) { printf("\n"); fflush(stdout); } } BARRIER(); /* ------------------------------------------------------------------------------------ */ if (TEST_SECTION_ENABLED()) { if (sender) { int64_t start = TIME(); flag = 0; BARRIER(); for (i=0; i < iters; i++) { GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_pong_shorthandler_flood)); } if (recvr) GASNET_BLOCKUNTIL(flag == iters); BARRIER(); report(" AMShort flood one-way Req",TIME() - start, iters, 0, 0); } else { flag = 0; BARRIER(); GASNET_BLOCKUNTIL(flag == iters); BARRIER(); } if (mynode == 0) { printf("\n"); fflush(stdout); } } BARRIER(); /* ------------------------------------------------------------------------------------ */ if (TEST_SECTION_ENABLED() && sender) { int64_t start = TIME(); flag = 0; for (i=0; i < iters; i++) { GASNET_Safe(gasnet_AMRequestShort0(peer, hidx_ping_shorthandler_flood)); } GASNET_BLOCKUNTIL(flag == iters); report(" AMShort flood roundtrip ReqRep",TIME() - start, iters, 0, 1); if (mynode == 0) { printf("\n"); fflush(stdout); } } BARRIER(); }
int main(int argc, char **argv) { int help=0; int arg=1; GASNET_Safe(gex_Client_Init(&myclient, &myep, &myteam, "testam", &argc, &argv, 0)); mynode = gex_TM_QueryRank(myteam); numnode = gex_TM_QuerySize(myteam); arg = 1; while (argc > arg) { if (!strcmp(argv[arg], "-p")) { #if GASNET_PAR pollers = test_thread_limit(atoi(argv[arg+1])+1)-1; arg += 2; #else if (0 == mynode) { fprintf(stderr, "testam %s\n", GASNET_CONFIG_STRING); fprintf(stderr, "ERROR: The -p option is only available in the PAR configuration.\n"); fflush(NULL); } sleep(1); gasnet_exit(1); #endif } else if (!strcmp(argv[arg], "-in")) { insegment = 1; ++arg; } else if (!strcmp(argv[arg], "-out")) { insegment = 0; ++arg; } else if (!strcmp(argv[arg], "-c")) { crossmachinemode = 1; ++arg; } else if (!strcmp(argv[arg], "-sync-req")) { asynclc = 0; lc_opt = GEX_EVENT_NOW; ++arg; } else if (!strcmp(argv[arg], "-async-req")) { asynclc = 1; lc_opt = GEX_EVENT_GROUP; ++arg; } else if (!strcmp(argv[arg], "-fp")) { use_np = 0; ++arg; } else if (!strcmp(argv[arg], "-np-cb")) { use_np = 1; np_cbuf = 1; ++arg; } else if (!strcmp(argv[arg], "-np-gb")) { use_np = 1; np_cbuf = 0; ++arg; } else if (!strcmp(argv[arg], "-src-noop")) { src_mode = SRC_NOOP; ++arg; } else if (!strcmp(argv[arg], "-src-generate")) { src_mode = SRC_GENERATE; ++arg; } else if (!strcmp(argv[arg], "-src-memcpy")) { src_mode = SRC_MEMCPY; ++arg; } else if (argv[arg][0] == '-') { help = 1; ++arg; } else break; } if (argc > arg) { iters = atoi(argv[arg]); ++arg; } if (!iters) iters = 1000; if (argc > arg) { maxsz = atoi(argv[arg]); ++arg; } if (!maxsz) maxsz = 2*1024*1024; if (argc > arg) { TEST_SECTION_PARSE(argv[arg]); ++arg; } GASNET_Safe(gex_Segment_Attach(&mysegment, myteam, TEST_SEGSZ_REQUEST)); GASNET_Safe(gex_EP_RegisterHandlers(myep, htable, sizeof(htable)/sizeof(gex_AM_Entry_t))); #if GASNET_PAR #define PAR_USAGE \ " The -p option gives the number of polling threads, specified as\n" \ " a non-negative integer argument (default is no polling threads).\n" #else #define PAR_USAGE "" #endif test_init("testam", 1, "[options] (iters) (maxsz) (test_sections)\n" " The '-in' or '-out' option selects whether the requestor's\n" " buffer is in the GASNet segment or not (default is 'in').\n" PAR_USAGE " The '-sync-req' or '-async-req' option selects synchronous or asynchronous\n" " local completion of Medium and Long Requests (default is synchronous).\n" " The '-fp', '-np-gb' or '-np-cb' option selects Fixed- or Negotiated-Payload\n" " for Medium and Long AMs, as follows:\n" " -fp: Fixed-Payload (default)\n" " -np-gb: Negotiated-Payload with GASNet-provided buffer\n" " -np-cb: Negotiated-Payload with client-provided buffer\n" " The '-src-*' options select treatment of the payload buffer used for\n" " Medium and Long AMs, as follows:\n" " -src-noop: no per-operation initialization (default)\n" " -src-generate: initialized (w/o memory reads) on each AM injection\n" " -src-memcpy: initialized using memcpy() on each AM injection\n" " The -c option enables cross-machine pairing (default is nearest neighbor).\n"); if (help || argc > arg) test_usage(); TEST_PRINT_CONDUITINFO(); if (insegment) { myseg = TEST_MYSEG(); } else { char *space = test_malloc(alignup(maxsz,PAGESZ) + PAGESZ); myseg = alignup_ptr(space, PAGESZ); } if (src_mode == SRC_MEMCPY) { zero_buffer = test_calloc(maxsz, 1); } np_lc_opt = np_cbuf ? lc_opt : NULL; if (crossmachinemode) { if ((numnode%2) && (mynode == numnode-1)) { sender = 1; peer = mynode; } else { gex_Rank_t half = numnode / 2; sender = (mynode < half); peer = sender ? (mynode + half) : (mynode - half); } } else { peer = mynode ^ 1; sender = mynode % 2 == 0; if (peer == numnode) { peer = mynode; } } gex_Event_t *tmp_lc_opt = use_np ? np_lc_opt : lc_opt; gex_Flags_t flags = use_np ? ( np_cbuf ? GEX_FLAG_AM_PREPARE_LEAST_CLIENT : GEX_FLAG_AM_PREPARE_LEAST_ALLOC) : 0; maxmedreq = MIN(maxsz, gex_AM_MaxRequestMedium(myteam,peer,tmp_lc_opt,flags,0)); maxmedrep = MIN(maxsz, gex_AM_MaxReplyMedium (myteam,peer,GEX_EVENT_NOW,flags,0)); maxlongreq = MIN(maxsz, gex_AM_MaxRequestLong (myteam,peer,tmp_lc_opt,flags,0)); maxlongrep = MIN(maxsz, gex_AM_MaxReplyLong (myteam,peer,GEX_EVENT_NOW,flags,0)); recvr = !sender || (peer == mynode); // Long Request and Reply (distinct for loopback) reply_addr = TEST_SEG(peer); request_addr = (peer == mynode) ? (void*)((uintptr_t)reply_addr + alignup(maxsz,SIZEOF_GEX_RMA_VALUE_T)) : reply_addr; BARRIER(); #if GASNET_PAR #define PAR_FMT " %i extra recvr polling threads\n" #define PAR_ARG ,pollers #else #define PAR_FMT /*empty*/ #define PAR_ARG /*empty*/ #endif if (mynode == 0) { printf("Running %i iterations of %s AM performance with:\n" " local addresses %sside the segment%s\n" " %ssynchronous LC for Requests%s\n" " %s\n" " %s\n" PAR_FMT " ...\n", iters, (crossmachinemode ? "cross-machine ": ""), (insegment ? "in" : "out"), (insegment ? " (default)" : ""), (asynclc ? "a": ""), (asynclc ? "": " (default)"), (!use_np ? "fixed-Payload (default)" :(np_cbuf ? "negotiated-Payload with client-provided buffer" : "negotiated-Payload with GASNet-provided buffer")), ((src_mode == SRC_NOOP) ? "no payload initialization (default)" :(src_mode == SRC_GENERATE) ? "payload initialized by computation" : "payload initialized using memcpy()") PAR_ARG ); printf(" Msg Sz Description Total time Avg. time Bandwidth\n" " ------ ----------- ---------- --------- ---------\n"); fflush(stdout); } #if GASNET_PAR TEST_SET_WAITMODE(pollers+1); if (pollers) test_createandjoin_pthreads(pollers+1,doAll,NULL,0); else #endif doAll(NULL); MSG("done."); gasnet_exit(0); return 0; }
int main(int argc, char **argv) { static int *A, *B, *C, *D, *E, *F, *G; gasnet_node_t myproc, i; int pollers = 0; int j; /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); int arg = 1; int help = 0; while (argc > arg) { if (!strcmp(argv[arg], "-p")) { #if GASNET_PAR ++arg; if (argc > arg) { pollers = atoi(argv[arg]); arg++; } else help = 1; #else if (0 == gasnet_mynode()) { fprintf(stderr, "testcoll %s\n", GASNET_CONFIG_STRING); fprintf(stderr, "ERROR: The -p option is only available in the PAR configuration.\n"); fflush(NULL); } sleep(1); gasnet_exit(1); #endif } else if (argv[arg][0] == '-') { help = 1; ++arg; } else break; } if (argc > arg) { iters = atoi(argv[arg]); ++arg; } if (iters < 1) { iters = 1000; } #if GASNET_PAR if (argc > arg) { threads = atoi(argv[arg]); ++arg; } threads = test_thread_limit(threads); if (threads < 1) { printf("ERROR: Threads must be between 1 and %d\n", TEST_MAXTHREADS); exit(EXIT_FAILURE); } #endif /* get SPMD info */ myproc = gasnet_mynode(); numprocs = gasnet_nodes(); images = numprocs * threads; datasize = iters * (3 + 4 * images); GASNET_Safe(gasnet_attach(NULL, 0, TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); #if GASNET_PAR #define USAGE "[options] (iters) (threadcnt)\n" \ " The -p option gives the number of polling threads, specified as\n" \ " a non-negative integer argument (default is no polling threads).\n" #else #define USAGE "(iters)\n" #endif test_init("testcoll",0,USAGE); TEST_SET_WAITMODE(threads + pollers); if (argc > arg || help) test_usage(); MSG0("Running coll test(s) with %d iterations.", iters); R = test_malloc(iters*sizeof(int)); /* Number if ints to store */ /* Carve some variables out of the (aligned) segment: */ Aw = test_malloc(iters * sizeof(int *)); Bw = test_malloc(iters * sizeof(int *)); Cw = test_malloc(iters * sizeof(int *)); Dw = test_malloc(iters * sizeof(int *)); Ew = test_malloc(iters * sizeof(int *)); Fw = test_malloc(iters * sizeof(int *)); Gw = test_malloc(iters * sizeof(int *)); A = (int *)TEST_MYSEG(); /* int [1*iters] */ B = A + 1*iters; /* int [1*iters] */ C = B + 1*iters; /* int [N*iters] */ D = C + images*iters; /* int [N*iters] */ E = D + images*iters; /* int [1*iters] */ F = E + 1*iters; /* int [N*iters] */ G = F + images*iters; /* int [N*iters] */ for (j = 0; j < iters; ++j) { Aw[j] = A + j; Bw[j] = B + j; Cw[j] = C + j*images; Dw[j] = D + j*images; Ew[j] = E + j; Fw[j] = F + j*images; Gw[j] = G + j*images; } /* The unaligned equivalents */ Av = test_malloc_2D(iters, images * sizeof(int *)); Bv = test_malloc_2D(iters, images * sizeof(int *)); Cv = test_malloc_2D(iters, images * sizeof(int *)); Dv = test_malloc_2D(iters, images * sizeof(int *)); Ev = test_malloc_2D(iters, images * sizeof(int *)); Fv = test_malloc_2D(iters, images * sizeof(int *)); Gv = test_malloc_2D(iters, images * sizeof(int *)); for (i = 0; i < images; ++i) { /* Using (TEST_SEG(n) + n) yields unaligned even when the segments are aligned. This is to help catch any case where addresses might have been misused that might go undetected if the addresses were aligned */ A = (int *)TEST_SEG(i/threads) + (i/threads) + datasize*(i%threads); B = A + 1*iters; C = B + 1*iters; D = C + images*iters; E = D + images*iters; F = E + 1*iters; G = F + images*iters; for (j = 0; j < iters; ++j) { Av[j][i] = A + j; Bv[j][i] = B + j; Cv[j][i] = C + j*images; Dv[j][i] = D + j*images; Ev[j][i] = E + j; Fv[j][i] = F + j*images; Gv[j][i] = G + j*images; } } BARRIER(); #if GASNET_PAR MSG("Forking %d gasnet threads (%d active, %d polling)", threads+pollers, threads, pollers); { int i; thread_data_t* tt_thread_data = test_malloc(threads*sizeof(thread_data_t)); for (i = 0; i < threads; i++) { tt_thread_data[i].myproc = myproc; tt_thread_data[i].local_id = i; tt_thread_data[i].mythread = i + threads * myproc; tt_thread_data[i].peerthread = i + threads * (((myproc ^ 1) == numprocs) ? myproc : (myproc ^ 1)); } test_createandjoin_pthreads(threads, &thread_main, tt_thread_data, sizeof(tt_thread_data[0])); test_free(tt_thread_data); } #else { thread_data_t td; td.myproc = myproc; td.local_id = 0; td.mythread = myproc; td.peerthread = ((myproc ^ 1) == numprocs) ? myproc : (myproc ^ 1); thread_main(&td); } #endif BARRIER(); test_free(Aw); test_free(Bw); test_free(Cw); test_free(Dw); test_free_2D(Av); test_free_2D(Bv); test_free_2D(Cv); test_free_2D(Dv); test_free(R); MSG("done."); gasnet_exit(0); return 0; }
int main(int argc, char **argv) { int arg; int iters = 0; int size = 0; int j; int help = 0; /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); GASNET_Safe(gasnet_attach(NULL, 0, TEST_SEGSZ_REQUEST, TEST_MINHEAPOFFSET)); test_init("testalign", 1, "[-in|-out] (iters) (size)\n" " The 'in' or 'out' option selects whether the initiator-side\n" " memory is in the GASNet segment or not (default is not).\n" " The -m option enables MB/sec units for bandwidth output (MB=2^20 bytes)."); /* parse arguments */ arg = 1; while (argc > arg) { if (!strcmp(argv[arg], "-in")) { insegment = 1; ++arg; } else if (!strcmp(argv[arg], "-out")) { insegment = 0; ++arg; } else if (!strcmp(argv[arg], "-m")) { unitsMB = 1; ++arg; } else if (argv[arg][0] == '-') { help = 1; ++arg; } else break; } if (help || argc > arg+2) test_usage(); if (argc > arg) iters = atoi(argv[arg++]); if (!iters) iters = 1000; if (argc > arg) size = atoi(argv[arg++]); if (!size) size = DEFAULT_SZ; /* get SPMD info */ myproc = gasnet_mynode(); numprocs = gasnet_nodes(); /* Only allow even number for numprocs */ if (numprocs % 2 != 0) { MSG("WARNING: This test requires an even number of nodes. Test skipped.\n"); gasnet_exit(0); /* exit 0 to prevent false negatives in test harnesses for smp-conduit */ } /* Setting peer thread rank */ peerproc = (myproc % 2) ? (myproc - 1) : (myproc + 1); iamsender = (myproc % 2 == 0); rembuf = (void *) TEST_SEG(peerproc); /* initialize global data in my thread */ if (insegment) { locbuf = (void *)TEST_MYSEG(); } else { /* size + 1 page of alignment + initial alignment padding of PAGESZ-1 */ uintptr_t tmp = (uintptr_t) test_malloc(size + 2 * PAGESZ - 1); locbuf = (void *)((tmp + PAGESZ - 1) & ~(PAGESZ - 1)); } for (j = 1; j <= PAGESZ; j *= 2) oneway_test(iters, size, j); for (j = 1; j <= PAGESZ; j *= 2) oneway_nbi_test(iters, size, j); for (j = 1; j <= PAGESZ; j *= 2) oneway_nb_test(iters, size, j); BARRIER(); gasnet_exit(0); return 0; }