Beispiel #1
0
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);
}
Beispiel #2
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);
}
Beispiel #3
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);

  }