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 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
|
/*--- Chris S.: June 1999 */
/*--- reads in, first an integer as a generator type and next elements from */
/*--- a data file */
/*--- checking C interface with pointer checking ---*/
/*--- added 'int gtype' 'scanf("%d\n", @gtype)' and gtype to all init_sprng*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#define USE_MPI Uncomment to test with MPI */
#ifdef SPRNG_MPI
#include <mpi.h>
#endif
#define CHECK_POINTERS
#include "sprng.h"
#ifdef VERBOSE
#define report printf
#else
#define report ignore
#endif
#define PARAM SPRNG_DEFAULT
#define YES 1
#define NO 0
#define diff(a,b) (((a)>(b))?((a)-(b)):((b)-(a)))
int gtype; /*--- adding generator type ---*/
#ifdef __STDC__
void ignore(char *s, ...)
#else
void ignore(s)
char *s;
#endif
{
}
int check_gen() /* Check generator with correct parameters */
{
int *gen1, *gen2, *gen3, *gen4, **gen5, **newgen1, **newgen2, i, size;
char *s;
int tempi, correct, result = YES;
int ngens, seed, nsp;
float tempf1, tempf2;
double tempd1, tempd2;
ngens = 3;
seed = 985456376;
gen1 = init_sprng(gtype,0,ngens,seed,PARAM); /* initiallize generators */
gen2 = init_sprng(gtype,1,ngens,seed,PARAM);
gen3 = init_sprng(gtype,2,ngens,seed,PARAM);
/* ____________________ Check arithmetic ___________________________ */
correct = YES;
for(i=0; i<500; i++) /* check integer arithmetic */
{
scanf("%d\n", &tempi);
if(tempi != isprng(gen1))
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Integer generator does not reproduce correct stream.\n\tArithmetic on this machine may not be compatible with this generator.\n");
else
report("PASSED: Integer generator passed the reproducibility test\n");
correct = YES;
for(i=0; i<500; i++) /* check float arithmetic */
{
tempf1 = get_rn_flt(gen1);
scanf("%f\n", &tempf2);
if(diff(tempf1,tempf2) > 1.0e-6)
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Float generator does not reproduce correct stream\n\tArithmetic on this machine may not be compatible with this generator.\n");
else
report("PASSED: Float generator passed the reproducibility test\n");
correct = YES;
for(i=0; i<500; i++) /* check double precision arithmetic */
{
scanf("%lf\n", &tempd1);
tempd2 = sprng(gen1);
if(diff(tempd1,tempd2)>1.0e-14)
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Double generator does not reproduce correct stream.\n\tArithmetic on this machine may not be compatible with this generator.\n");
else
report("PASSED: Double generator passed the reproducibility test.\n");
/* ____________________ Check spawning ___________________ */
nsp = 0;
nsp += spawn_sprng(gen2,2,&newgen1); /* spawn new generators */
nsp += spawn_sprng(newgen1[1],2,&newgen2);
if(nsp != 4) /* check if spawn_sprng returned correct value */
{
result = NO;
printf("FAILED: Generator was unable to spawn\n");
}
correct = YES;
for(i=0; i<50; i++) /* check new stream */
{
scanf("%d\n", &tempi);
if(tempi != isprng(newgen2[1]))
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Generator does not reproduce correct stream after spawning\n\tThis is probably an error in spawning the generators\n");
else
report("PASSED: Generator spawns correctly\n");
/* _____________________ Pack and unpack generator ______________________ */
size = pack_sprng(newgen2[1], &s); /* pack the original stream */
if(size == 0) /* check if pack_sprng succeeded */
{
result = NO;
printf("FAILED: Generator was unable to pack\n");
}
gen4 = unpack_sprng(s); /* unpack generator */
correct = YES;
for(i=0; i<50; i++) /* check if unpacked stream = original stream*/
{
scanf("%d\n", &tempi);
if(tempi != isprng(gen4))
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Generator does not reproduce correct stream after packing and unpacking\n\tThis is probably an error in packing/unpacking the generators\n");
else
report("PASSED: Generator packs and unpacks stream correctly\n");
correct = YES;
spawn_sprng(gen4,1,&gen5); /* spawn from unpacked stream */
for(i=0; i<50; i++) /* check if spawned stream is correct */
{
scanf("%d\n", &tempi);
if(tempi != isprng(gen5[0]))
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Generator does not spawn correct stream after packing and unpacking\n\tThis is probably an error in packing/unpacking the generators\n");
else
report("PASSED: Generator packs and unpacks spawning information correctly\n");
/* _______________ Free generators ___________________ */
report("Checking free_sprng for integer generator ...\n");
nsp = free_sprng(gen1);
nsp = free_sprng(gen2);
nsp = free_sprng(gen3);
if(nsp != 6) /* check if free rng returns # of available generators */
{
result = NO;
printf("FAILED: Free returns %d instead of %d\n", nsp,6);
}
nsp = free_sprng(gen4);
nsp = free_sprng(gen5[0]);
nsp = free_sprng(newgen1[0]);
nsp = free_sprng(newgen1[1]);
nsp = free_sprng(newgen2[0]);
nsp = free_sprng(newgen2[1]);
if(nsp != 0)
{
result = NO;
printf("FAILED: Free returns %d instead of %d\n", nsp,0);
}
report("\n... Completed checking generator \n\n");
return result;
}
/* Check if generator meets specifications in handling errors */
int check_errors()
{
int *gen1, **gen2, i;
int tempi, correct, result = YES;
int seed, nsp, size;
char s[MAX_PACKED_LENGTH], *s2;
double tempd;
seed = 985456376;
/* ___________ ngens incorrect in init_sprng _____________ */
correct = YES;
fprintf(stderr,"Expect SPRNG WARNING: ngens <= 0.\n");
gen1 = init_sprng(gtype,0,0,seed,PARAM);
for(i=0; i<50; i++) /* ngens should be reset to 1 */
{
scanf("%d\n", &tempi);
if(tempi != isprng(gen1))
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Generator does not produce expected stream when ngens is 0 during initialization.\n");
else
report("PASSED: Generator produces expected stream when ngens is 0 during initialization.\n");
nsp = free_sprng(gen1); /* check if only one stream had been produced */
if(nsp != 0)
{
result = NO;
printf("FAILED: Generator produces %d streams instead of 1 when ngens is 0 during initialization.\n",nsp+1);
}
else
report("PASSED: Generator produces the correct number of streams when ngens is 0 during initialization.\n");
/* _______________ invalid range for gennum _______________ */
correct = YES;
fprintf(stderr,"Expect SPRNG ERROR: gennum not in range\n");
gen1 = init_sprng(gtype,-1,1,seed,PARAM); /* negative gennum */
if(gen1 != NULL)
{
free_sprng(gen1);
result = correct = NO;
}
fprintf(stderr,"Expect SPRNG ERROR: gennum not in range\n");
gen1 = init_sprng(gtype,2,1,seed,PARAM); /* gennum >= ngens */
if(gen1 != NULL)
{
free_sprng(gen1);
result = correct = NO;
}
if(correct == NO)
printf("FAILED: Generator does not return NULL when gennum is incorrect during initialization.\n");
else
report("PASSED: Generator returns NULL when gennum is incorrect during initialization.\n");
/* _______________ Invalid parameter ______________________________ */
correct = YES;
fprintf(stderr,"Expect SPRNG WARNING: Invalid parameter\n");
gen1 = init_sprng(gtype,0,1,seed,1<<30);
for(i=0; i<50; i++) /* check if default parameter is used ... */
{ /* ... when an invalid parameter is passed. */
scanf("%d\n", &tempi);
if(tempi != isprng(gen1))
result = correct = NO;
}
/* _____________________ Check spawn with invalid ngens _________________ */
report("Checking spawn with incorrect nspawned\n");
fprintf(stderr,"Expect SPRNG WARNING: nspawned <= 0.\n");
nsp = spawn_sprng(gen1,0,&gen2);
free_sprng(gen1);
if(nsp != 1) /* check if one generator was spawned */
{
result = NO;
printf("FAILED: Spawn returned %d streams instead of 1 when nspawned was 0.\n", nsp);
}
for(i=0; i<50; i++) /* check spawned stream */
{
scanf("%d\n", &tempi);
if(tempi != isprng(gen2[0]))
result = correct = NO;
}
free_sprng(gen2[0]);
if(correct == NO)
printf("FAILED: Generator does not spawn correct stream when nspawned was 0.\n");
else
report("PASSED: Generator spawns correctly when nspawned was 0.\n");
/* ______________________ Try using freed stream _______________________ */
if(isprng(gen2[0]) != -1)
{
result = NO;
printf("FAILED: isprng accepts freed stream\n");
}
else
report("PASSED: isprng detects freed stream\n");
/* _______________________ Unpack invalid string ________________________ */
memset(s,0,MAX_PACKED_LENGTH); /* set string to 0's */
fprintf(stderr,"Expect SPRNG ERROR: packed string invalid\n");
gen1 = unpack_sprng(s);
if(gen1 != NULL) /* NULL should be returned for invalid string */
{
result = NO;
printf("FAILED: Generator unpacks invalid string\n");
}
else
report("PASSED: Generator detected invalid string while unpacking\n");
/* ________________________ Invalid ID's _________________________________ */
report("Checking handling of invalid ID's\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempd = sprng(&tempi);
if(tempd != -1.0)
{
result = NO;
fprintf(stderr,"FAILED: sprng accepts invalid stream ID\n");
}
else
report("PASSED: sprng handles invalid stream ID correctly\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempd = sprng(NULL);
if(tempd != -1.0)
{
result = NO;
fprintf(stderr,"FAILED: sprng accepts NULL stream ID\n");
}
else
report("PASSED: sprng handles NULL stream ID correctly\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempi = isprng(&tempi);
if(tempi != -1)
{
result = NO;
fprintf(stderr,"FAILED: isprng accepts invalid stream ID\n");
}
else
report("PASSED: isprng handles invalid stream ID correctly\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempi = pack_sprng(&tempi,&s2);
if(tempi != 0)
{
result = NO;
fprintf(stderr,"FAILED: pack accepts invalid stream ID\n");
}
else
report("PASSED: pack handles invalid stream ID correctly\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempi = free_sprng(&tempi);
if(tempi != -1)
{
result = NO;
fprintf(stderr,"FAILED: free_sprng accepts invalid stream ID\n");
}
else
report("PASSED: free_sprng handles invalid stream ID correctly\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempi = spawn_sprng(&tempi,1,&gen2);
if(tempi != 0)
{
result = NO;
fprintf(stderr,"FAILED: spawn_sprng accepts invalid stream ID\n");
}
else
report("PASSED: spawn_sprng handles invalid stream ID correctly\n");
fprintf(stderr,"Expect SPRNG ERROR: Invalid stream ID.\n");
tempi = print_sprng(&tempi);
if(tempi != 0)
{
result = NO;
fprintf(stderr,"FAILED: print_sprng accepts invalid stream ID\n");
}
else
report("PASSED: print_sprng handles invalid stream ID correctly\n");
return result;
}
#ifdef USE_MPI
#ifdef __STDC__
int check_mpi_seed(unsigned int seed)
#else
int check_mpi_seed(seed)
unsigned int seed;
#endif
{
int nprocs, myid, result = YES, i, tag=0;
MPI_Status status;
unsigned int temp;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
if(myid != 0)
MPI_Send(&seed, 1, MPI_UNSIGNED, 0, tag, MPI_COMM_WORLD);
else
for(i=1; i<nprocs; i++)
{
MPI_Recv(&temp,1, MPI_UNSIGNED, i, tag, MPI_COMM_WORLD, &status);
if(temp != seed)
result = NO;
}
if(result == NO)
printf("FAILED: Seeds returned by make_seed differ on different processors\n");
else
report("PASSED: Seeds returned my make_seed on all processes are equal.\n");
return result;
}
#endif
#ifdef __STDC__
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{
int result=YES;
#ifndef CREATE_DATA
int temp, myid;
unsigned int seed1, seed2;
report("Checking make_sprng_seed ... ");
#ifdef USE_MPI
MPI_Init(&argc, &argv);
#endif
seed1 = make_sprng_seed();
#ifdef USE_MPI
result = check_mpi_seed(seed1);
#endif
seed2 = make_sprng_seed();
#ifdef USE_MPI
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
if(myid==0)
{
#endif
if(seed1 != seed2)
report(" ... Checked make_sprng_seed\n");
else
{
result = NO;
printf("\nERROR: make_sprng_seed does not return unique seeds\n");
}
#endif
scanf("%d\n", >ype); /*--- reading in a generator type */
if(check_gen() != YES)
result = NO;
if(check_errors() != YES)
result = NO;
#ifndef CREATE_DATA
if(result == YES)
printf("\nResult:\t PASSED\n\n");
else
printf("\nResult:\t FAILED\n\n");
#endif
#ifdef USE_MPI
}
MPI_Finalize();
#endif
}
|