/* $Header: /home/harrison/c/tcgmsg/ipcv4.0/RCS/test.c,v 1.1 91/12/06 17:27:41 harrison Exp Locker: harrison $ */ #include #if !defined(SEQUENT) && !defined(CONVEX) #include #endif #include "sndrcv.h" #include "evlog.h" extern char *memalign(); #if defined(ULTRIX) || defined(SGI) || defined(NEXT) || defined(HPUX) extern void *malloc(); #else extern char *malloc(); #endif extern unsigned char CheckByte(); extern double DRAND48_(); #if defined(SUN) extern char *sprintf(); #endif #ifdef IPSC #define bzero(A,N) memset((A), 0, (N)) #endif static void TestProbe() /* Send 100 messages from this process to random destinations all of type mtype. Receipt of these messages are acknowleged with a message of type atype. When all messages have been acked send a message of type ftype (f for finished) to process 0, but keep polling until get a message back of type ttype (t for terminate) indicating that it is OK to terminate. Note: This will NOT work with the shared memory communication mechanism (except on the KSR) and has a finite probability of deadlock over sockets or on the iPSC. */ { long nproc = NNODES_(); long me = NODEID_(); long mtype = 10+MSGINT; long ftype = 11; long ttype = 12; long atype = 13; long anyone= -1; long len = sizeof(long); #define N_MSG 100 long nmsg = N_MSG; long nacks = N_MSG; long sync = 1; long nfinished = 0; long zero = 0; long node, nodefrom, lenmes, incoming; double start = TCGTIME_(); srandom(me*257); while (1) { if (PROBE_(&mtype, &anyone)) { RCV_(&mtype, (char *) &incoming, &len,&lenmes,&anyone,&nodefrom,&sync); SND_(&atype, (char *) &incoming, &zero, &nodefrom, &sync); } else if (nmsg) { while ((node = random() % nproc) == me) ; nmsg--; SND_(&mtype, (char *) &nmsg, &len, &node, &sync); } else if (PROBE_(&atype, &anyone)) { RCV_(&atype, (char *) &incoming,&len,&lenmes,&anyone,&nodefrom,&sync); nacks--; if (nacks == 0) { if (me == 0) nfinished++; else SND_(&ftype, (char *) &nmsg, &zero, &zero, &sync); } } else if (me == 0 && PROBE_(&ftype, &anyone)) { RCV_(&ftype, (char *) &incoming,&len,&lenmes,&anyone,&nodefrom,&sync); nfinished++; } else if (me != 0 && PROBE_(&ttype, &zero)) { RCV_(&ttype, (char *) &incoming,&len,&lenmes,&anyone,&nodefrom,&sync); break; } else if (me == 0 && nfinished == nproc) { for (node=1; node hi) ran = hi; list[i] = ran; } } void Stress() /* Stress the system by passing messages between a ranomly selected list of nodes */ { long me = NODEID_(); long nproc = NNODES_(); long type, lenbuf, node, lenmes, nodefrom, i, j, from, to; long *list_i, *list_j, *list_n; #define N_LEN 11 static long len[N_LEN] = {0,1,2,4,8,4095,4096,4097,16367,16368,16369}; char *buf1, *buf2; long n_stress, mod; long sync = 1; from = 0; lenbuf = sizeof(long); if (me == 0) { (void) printf("Stress test ... randomly exchange messages\n-----------"); (void) printf("\n\nInput no. of messages: "); (void) fflush(stdout); if (scanf("%ld",&n_stress) != 1) Error("Stress: error reading n_stress",(long) -1); if ( (n_stress <= 0) || (n_stress > 10000) ) n_stress = 100; } type = 13 | MSGINT; BRDCST_(&type, (char *) &n_stress, &lenbuf, &from); type++; lenbuf = n_stress * sizeof(long); if ( (list_i = (long *) memalign(sizeof(long), (unsigned) lenbuf)) == (long *) NULL ) Error("Stress: failed to allocate list_i",n_stress); if ( (list_j = (long *) memalign(sizeof(long), (unsigned) lenbuf)) == (long *) NULL ) Error("Stress: failed to allocate list_j",n_stress); if ( (list_n = (long *) memalign(sizeof(long), (unsigned) lenbuf)) == (long *) NULL ) Error("Stress: failed to allocate list_n",n_stress); if ( (buf1 = malloc((unsigned) 16376)) == (char *) NULL ) Error("Stress: failed to allocate buf1", (long) 16376); if ( (buf2 = malloc((unsigned) 16376)) == (char *) NULL ) Error("Stress: failed to allocate buf2", (long) 16376); if (me == 0) { /* Make random list of node pairs and message lengths */ RandList((long) 0, (long) (NNODES_()-1), list_i, n_stress); RandList((long) 0, (long) (NNODES_()-1), list_j, n_stress); RandList((long) 0, (long) (N_LEN-1), list_n, n_stress); for (i=0; i= nproc) ) Error("Stress: from is out of range", from); if ( (to < 0) || (to >= nproc) ) Error("Stress: to is out of range", to); if (from == to) continue; if ( (me == 0) && (j%mod == 0) ) { (void) printf("Stress: test=%ld: from=%ld, to=%ld, len=%ld\n", i, from, to, lenbuf); (void) fflush(stdout); } j++; if (from == me) SND_(&type, buf1, &lenbuf, &to, &sync); else if (to == me) { (void) bzero(buf2, (int) lenbuf); /* Initialize the receive buffer */ buf2[lenbuf] = '+'; RCV_(&type, buf2, &lenbuf, &lenmes, &from, &nodefrom, &sync); if (buf2[lenbuf] != '+') Error("Stress: overran buffer on receive",lenbuf); if (CheckByte((unsigned char *) buf1, lenbuf) != CheckByte((unsigned char *) buf2, lenbuf)) Error("Stress: invalid checksum on receive",lenbuf); if (lenmes != lenbuf) Error("Stress: invalid message length on receive",lenbuf); } } (void) free(buf2); (void) free(buf1); (void) free((char *) list_n); (void) free((char *) list_j); (void) free((char *) list_i); } void RingTest() /* Time passing a message round a ring */ { long me = NODEID_(); long type = 4; long left = (me + NNODES_() - 1) % NNODES_(); long right = (me + 1) % NNODES_(); char *buf, *buf2; unsigned char sum, sum2; long lenbuf, lenmes, nodefrom; double start, used, rate; long max_len; long i; long sync = 1; i = 0; lenbuf = sizeof(long); if (me == 0) { (void) printf("Ring test ... time network performance\n---------\n\n"); (void) printf("Input maximum message size: "); (void) fflush(stdout); if (scanf("%ld", &max_len) != 1) Error("RingTest: error reading max_len",(long) -1); if ( (max_len <= 0) || (max_len >= 4*1024*1024) ) max_len = 256*1024; } type = 4 | MSGINT; BRDCST_(&type, (char *) &max_len, &lenbuf, &i); if ( (buf = malloc((unsigned) max_len)) == (char *) NULL) Error("failed to allocate buf",max_len); if (me == 0) { if ( (buf2 = malloc((unsigned) max_len)) == (char *) NULL) Error("failed to allocate buf2",max_len); for (i=0; i 0) rate = 1.0e-6 * (double) (NNODES_() * lenbuf) / (double) used; else rate = 0.0; printf("len=%ld (%ld) bytes, used=%f s, rate=%f Mb/s (0x%x, 0x%x)\n", lenbuf, lenmes, used, rate, sum, sum2); (void) fflush(stdout); } else { RCV_(&type, buf, &lenbuf, &lenmes, &right, &nodefrom, &sync); SND_(&type, buf, &lenbuf, &left, &sync); } lenbuf *= 2; } if (me == 0) (void) free(buf2); (void) free(buf); } void RcvAnyTest() /* Test receiveing a message from any node */ { long me = NODEID_(); long type = 337 | MSGINT; char buf[8]; long i, j, node, lenbuf, lenmes, nodefrom, receiver, n_msg; long sync = 1; lenbuf = sizeof(long); if (me == 0) { (void) printf("RCV any test ... check is working!\n-----------\n\n"); (void) printf("Input node to receive : "); (void) fflush(stdout); if (scanf("%ld", &receiver) != 1) Error("RcvAnyTest: error reading receiver",(long) -1); if ( (receiver < 0) || (receiver >= NNODES_()) ) receiver = NNODES_()-1; (void) printf("Input number of messages : "); (void) fflush(stdout); if (scanf("%ld", &n_msg) != 1) Error("RcvAnyTest: error reading n_msg",(long) -1); if ( (n_msg <= 0) || (n_msg > 10) ) n_msg = 5; } node = 0; BRDCST_(&type, (char *) &receiver, &lenbuf, &node); type++; BRDCST_(&type, (char *) &n_msg, &lenbuf, &node); type++; lenbuf = 0; type = 321; for (i=0; i= 10000) ) n_val = 100; } node = 0; BRDCST_(&type, (char *) &n_val, &lenbuf, &node); /* Loop thru a few values to visually show it is working */ next = -1; for (i=0; i<10; i++) { if (i > next) next = NXTVAL_(&nproc); if (i == next) { (void) printf("node %ld got value %ld\n",me, i); (void) fflush(stdout); } } nproc = -nproc; next = NXTVAL_(&nproc); nproc = -nproc; /* Now time it for real .. twice*/ for (ntimes=0; ntimes<2; ntimes++) { if (me == 0) start = TCGTIME_(); next = -1; ngot = 0; for (i=0; i next) next = NXTVAL_(&nproc); if (i == next) ngot++; } nproc = -nproc; next = NXTVAL_(&nproc); nproc = -nproc; if (me == 0) { used = TCGTIME_() - start; rate = used / ngot; (void) printf("node 0: From %ld busy iters did %ld, used=%fs per call\n", n_val, ngot, rate); (void) fflush(stdout); } type++; SYNCH_(&type); } } void ToggleDebug() { static long on = 0; long me = NODEID_(); long type = 666 | MSGINT; long lenbuf = sizeof(long); long from=0; long node; if (me == 0) { (void) printf("\nInput node to debug (-1 = all) : "); (void) fflush(stdout); if (scanf("%ld", &node) != 1) Error("ToggleDebug: error reading node",(long) -1); } BRDCST_(&type, (char *) &node, &lenbuf, &from); if ((node < 0) || (node == me)) { on = (on + 1)%2; SETDBG_(&on); } } int main(argc, argv) int argc; char **argv; { long type; long lenbuf; long node, opt; PBEGIN_(argc, argv); (void) printf("In process %ld\n", NODEID_()); (void) fflush(stdout); /* Read user input for action */ lenbuf = sizeof(long); node = 0; while (1) { (void) fflush(stdout); if (NODEID_() == 0) (void) sleep(1); type = 999; SYNCH_(&type); (void) sleep(1); if (NODEID_() == 0) { again: (void) printf("\n\ 0=quit, 1=Ring, 2=Stress, 3=Hello, 4=Probe, 5=NxtVal, 6=Global, 7=Debug: "); (void) fflush(stdout); if (scanf("%ld", &opt) != 1) Error("test: input of option failed",(long) -1); (void) printf("\n"); (void) fflush(stdout); if ( (opt < 0) || (opt > 7) ) goto again; } type = 2 | MSGINT; BRDCST_(&type, (char *) &opt, &lenbuf, &node); switch (opt) { case 0: if (NODEID_() == 0) STATS_(); PEND_(); return 0; /* break; */ case 1: RingTest(); break; case 2: Stress(); break; case 3: Hello(); break; case 4: TestProbe(); break; case 5: NextValueTest(); break; case 6: TestGlobals(); break; case 7: ToggleDebug(); break; default: Error("test: invalid option", opt); break; } } }