void test_put(threaddata_t *tdata) { int peer = tdata->tid_peer; int node = tt_thread_map[peer]; void *laddr = tt_addr_map[tdata->tid]; void *raddr = tt_addr_map[peer]; int len; do { len = RANDOM_SIZE(); } while (len > TEST_SEGZ_PER_THREAD); ACTION_PRINTF("tid=%3d> put (%p,%8d) -> tid=%3d,node=%d,addr=%p", tdata->tid, laddr, len, peer, node, raddr); gasnet_put(node, raddr, laddr, len); }
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); }
int main(int argc, char **argv) { int outer_iterations = 0; int inner_iterations = 0; int seedoffset = 0; int numprocs, myproc, peerproc; int sender_p; char *shadow_region_1, *shadow_region_2; int i,j; char *local_base, *target_base; /* call startup */ GASNET_Safe(gasnet_init(&argc, &argv)); /* get SPMD info */ myproc = gasnet_mynode(); numprocs = gasnet_nodes(); if (argc > 1) segsize = atoi(argv[1]); if (!segsize) segsize = 1024*1000; if (argc > 2) outer_iterations = atoi(argv[2]); if (!outer_iterations) outer_iterations = 10; if (argc > 3) inner_iterations = atoi(argv[3]); if (!inner_iterations) inner_iterations = 10; if (argc > 4) seedoffset = atoi(argv[4]); GASNET_Safe(gasnet_attach(NULL, 0, TEST_SEGSZ, TEST_MINHEAPOFFSET)); test_init("testslice",0, "(segsize) (iterations) (# of sizes per iteration) (seed)"); /* parse arguments */ if (argc > 5) test_usage(); if(numprocs & 1) { MSG0("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 */ } sender_p = !(myproc & 1); peerproc = myproc ^ 1; if (seedoffset == 0) { seedoffset = (((unsigned int)TIME()) & 0xFFFF); TEST_BCAST(&seedoffset, 0, &seedoffset, sizeof(&seedoffset)); } TEST_SRAND(myproc+seedoffset); MSG0("Running with segment size = %d outer iterations=%d inner iterations=%d seed=%d", segsize,outer_iterations, inner_iterations, seedoffset); BARRIER(); /* Allocate two shadow regions the same size as the segment */ shadow_region_1 = (char *) test_malloc(segsize); shadow_region_2 = (char *) test_malloc(segsize); /* Fill up the shadow region with random data */ for(i=0; i < segsize; i++) { shadow_region_1[i] = (char) TEST_RAND(0,255); } memset(shadow_region_2,0,segsize); /* Big loop performing the following */ for(i=0; i < outer_iterations; i++) { if(sender_p) { /* Pick a starting point anywhere in the segment */ int starting_point = TEST_RAND(0,(segsize-1)); local_base = TEST_SEG(myproc); target_base = TEST_SEG(peerproc); for(j=0; j < inner_iterations; j++) { /* Pick a length */ int len = TEST_RAND(1,segsize-starting_point); int remote_starting_point = TEST_RAND(0,segsize-len); int local_starting_point_1 = TEST_RAND(0,segsize-len); int local_starting_point_2 = TEST_RAND(0,segsize-len); /* Perform operations */ /* Out of segment put from shadow_region 1 to remote */ gasnet_put(peerproc,target_base+remote_starting_point,shadow_region_1 + starting_point,len); /* In segment get from remote to local segment */ gasnet_get(local_base+local_starting_point_1,peerproc,target_base+remote_starting_point,len); /* Verify */ assert_eq(shadow_region_1 + starting_point, local_base + local_starting_point_1, len,starting_point,i,j,"Out of segment put + in segment get"); /* Out of segment get from remote to shadow_region_2 (starting from 0) */ gasnet_get(shadow_region_2+local_starting_point_2,peerproc,target_base+remote_starting_point,len); /* Verify */ assert_eq(shadow_region_2+local_starting_point_2, shadow_region_1 + starting_point, len,starting_point,i,j,"Out of segment get"); } TEST_PROGRESS_BAR(i,outer_iterations); } BARRIER(); } if(sender_p && !failures) { MSG("testslice PASSED"); } gasnet_exit(0); return 0; }