void test_sleep(threaddata_t *tdata) { unsigned usecs = (unsigned) sleep_min_us + (rand() % (sleep_max_us - sleep_min_us)); ACTION_PRINTF("tid=%3d> sleeping %.3f millisecs", tdata->tid, usecs/1000.0); { uint64_t goal = gasnett_ticks_to_us(gasnett_ticks_now()) + usecs; while (gasnett_ticks_to_us(gasnett_ticks_now()) < goal) gasnett_sched_yield(); } ACTION_PRINTF("tid=%3d> awaking", tdata->tid); }
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 test_mpi(threaddata_t *tdata) { MPI_Request sendhandle = MPI_REQUEST_NULL; MPI_Request recvhandle = MPI_REQUEST_NULL; int peer = tdata->tid_peer; int node = tt_thread_map[peer]; int mpipeer = gasnetnode_to_mpirank[node]; int sz; char *sendbuf; char *recvbuf; int tag = tdata->tid; int i; do { sz = RANDOM_SIZE(); } while (sz == 0); /* some MPI's may barf on 0 byte send/recv */ sendbuf = (char*)test_malloc(sz); recvbuf = (char*)test_malloc(sz); for (i=0; i < MIN(sz,4096); i++) { /* randomize at least the first 4 KB */ sendbuf[i] = (char)rand(); } ACTION_PRINTF("tid=%3d> starting MPI ping-pong with tid=%3d.\n", tdata->tid, peer); MPI_LOCK(); ACTION_PRINTF("tid=%3d> setting MPI_Irecv, %i bytes\n", tdata->tid, sz); MPI_SAFE(MPI_Irecv(recvbuf, sz, MPI_BYTE, mpipeer, 10000+tag, MPI_COMM_WORLD, &recvhandle)); assert(recvhandle != MPI_REQUEST_NULL); ACTION_PRINTF("tid=%3d> sending MPI message, %i bytes\n", tdata->tid, sz); MPI_SAFE(MPI_Isend(sendbuf, sz, MPI_BYTE, mpipeer, tag, MPI_COMM_WORLD, &sendhandle)); assert(sendhandle != MPI_REQUEST_NULL); MPI_UNLOCK(); tdata->flag = -1; gasnett_local_wmb(); ACTION_PRINTF("tid=%3d> MPI AMShortRequest to tid=%3d\n", tdata->tid, peer); GASNET_Safe(gasnet_AMRequestShort2(node, hidx_mpi_handler, tdata->tid, sz)); while (tdata->flag != 0) { ACTION_PRINTF("tid=%3d> MPI probe AMShortRequest to tid=%3d\n", tdata->tid, peer); GASNET_Safe(gasnet_AMRequestShort1(node, hidx_mpi_probehandler, tdata->tid)); gasnett_sched_yield(); test_sleep(tdata); GASNET_Safe(gasnet_AMPoll()); mpi_test(&sendhandle); /* occasional testing may be required for progress */ mpi_test(&recvhandle); } tdata->flag = -1; mpi_complete(&sendhandle); mpi_complete(&recvhandle); /* verify */ for (i=0; i < sz; i++) { if (sendbuf[i] != recvbuf[i]) FATALERR("mismatch at element %i in MPI test.", i); } test_free(sendbuf); test_free(recvbuf); ACTION_PRINTF("tid=%3d> MPI ping-pong with tid=%3d complete.\n", tdata->tid, peer); }