1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
/* $Source: bitbucket.org:berkeleylab/gasnet.git/tests/testcore1.c $
* Copyright 2002, Christian Bell <csbell@cs.berkeley.edu>
* Terms of use are as specified in license.txt
*
* Description: GASNet Core Monotonic checksum test
* This stress tests the ability of the core to successfully send
* AM Requests/Replies through get and/or put functions.
*
* Get version:
* 1. Node A generates 'n' random seeds and keeps a local checksum for each
* . .(barrier)
* 2. Node B gets the 'n' seeds from Node A and keeps its checksum for each
* . .(barrier)
* 3. Node A gets the checksum hashes from Node B and compares them against
* its own copy once the gets are sync'd
*
* Put version:
* Steps 2 and 3 are puts for each other node.
*/
#include "test.h"
#define DEBUG_TRACE
#define CHKSUM_LENGTH 8
#define CHKSUM_NUM 64
#define CHKSUM_TOTAL CHKSUM_LENGTH*CHKSUM_NUM
#define TESTSafe(x, msg) do { \
if (!(x)) { printf msg; gasnet_exit(1); } } while (0)
typedef struct {
uint32_t seed;
unsigned char chksum[CHKSUM_TOTAL];
} monoseed_t;
monoseed_t *_mseed;
static gex_Client_t myclient;
static gex_EP_t myep;
static gex_TM_t myteam;
static gex_Segment_t mysegment;
int myproc;
int numproc;
int peerproc;
int numprocs;
gasnet_seginfo_t *seginfo_table;
/* Test specific globals */
int chksum_iters = 0;
gasnett_atomic_t chksum_success = gasnett_atomic_init(0);
gasnett_atomic_t chksum_received = gasnett_atomic_init(0);
#define CHKSUM_DUMP(chksum) do { \
int i = 0; \
uint8_t *c = (uint8_t *)chksum; \
printf("0x"); \
for (i = 0; i < CHKSUM_TOTAL; i++) \
printf("%0x", c[i]); \
} while (0);
#ifdef VERBOSE
void
monoseed_trace(int iter, int seed, void *chksum_loc, void *chksum_rem)
{
printf("%d> iter=%4d, seed=%12d, chksum_local=", myproc, iter, seed);
CHKSUM_DUMP(chksum_loc);
if (chksum_rem != NULL) {
printf(" chksum_remote=");
CHKSUM_DUMP(chksum_rem);
}
printf("\n"); fflush(stdout);
}
#else
#define monoseed_trace(iter, seed, chksum_loc, chksum_rem)
#endif
void
chksum_gen(int seed, void *buf)
{
int i;
uint64_t chksum;
uint8_t *p = buf;
chksum = test_checksum((void *)&seed, 4);
for (i = 0; i < CHKSUM_NUM; i++) {
chksum = test_checksum((void *)&chksum, CHKSUM_LENGTH);
memcpy(p, &chksum, CHKSUM_LENGTH);
p += CHKSUM_LENGTH;
}
return;
}
void
monoseed_init(int num)
{
int i;
if (myproc % 2 == 0) {
_mseed = (monoseed_t *) test_malloc(sizeof(monoseed_t) * num);
srand((int)TIME());
for (i = 0; i < num; i++) {
_mseed[i].seed = (int) rand() + 1;
chksum_gen(_mseed[i].seed, &_mseed[i].chksum);
}
}
return;
}
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++)
gex_AM_RequestShort2(myteam, (gex_Rank_t)peerproc,
201, 0, 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(gex_Token_t token,
gex_AM_Arg_t iter, gex_AM_Arg_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(
gex_AM_ReplyMedium1(token, 202, &chksum_reqbuf,
CHKSUM_TOTAL, GEX_EVENT_NOW, 0, iter));
return;
}
void
chksum_reph(gex_Token_t token,
void *buf, size_t nbytes, gex_AM_Arg_t iter)
{
gasnett_atomic_increment(&chksum_received, 0);
assert_always(iter < chksum_iters && iter >= 0);
assert_always(nbytes == CHKSUM_TOTAL);
monoseed_trace(iter, _mseed[iter].seed, &_mseed[iter].chksum, buf);
if (memcmp(&_mseed[iter].chksum, buf, CHKSUM_LENGTH) == 0)
gasnett_atomic_increment(&chksum_success, 0);
else {
printf("iter %3d failed! chksum_local=", (int)iter);
CHKSUM_DUMP(&_mseed[iter].chksum);
printf(" chksum_remote=");
CHKSUM_DUMP(buf);
printf("\n");
}
return;
}
/* Test handlers */
int
main(int argc, char **argv)
{
int iters = 0;
gex_AM_Entry_t htable[] = {
{ 201, (gex_AM_Fn_t)chksum_reqh, GEX_FLAG_AM_REQUEST|GEX_FLAG_AM_SHORT, 2 },
{ 202, (gex_AM_Fn_t)chksum_reph, GEX_FLAG_AM_REPLY|GEX_FLAG_AM_MEDIUM, 1 }
};
/* call startup */
GASNET_Safe(gex_Client_Init(&myclient, &myep, &myteam, "testcore1", &argc, &argv, 0));
GASNET_Safe(gex_Segment_Attach(&mysegment, myteam, TEST_SEGSZ_REQUEST));
GASNET_Safe(gex_EP_RegisterHandlers(myep, htable, sizeof(htable)/sizeof(gex_AM_Entry_t)));
test_init("testcore1",0,"(iters)");
assert(CHKSUM_TOTAL <= gex_AM_LUBReplyMedium());
if (argc > 1) iters = atoi(argv[1]);
if (!iters) iters = 1000;
if (argc > 2) test_usage();
/* get SPMD info */
chksum_iters = iters;
myproc = gex_TM_QueryRank(myteam);
numprocs = gex_TM_QuerySize(myteam);
/* Only allow even number for numprocs */
if (numprocs % 2 != 0) {
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 */
}
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);
}
|