/* * Tony Pasqualoni / Sept. 20, 2006 * * Cellular automaton random number generator test: * Measures speed of ca-rng.c and runs Diehard tests. * */ #include #include #include #include #include #include #include "ca-rng.c" /* Compilation: gcc -O2 -lm ca-test.c */ #define MAX_STRING_SIZE 100 #define MEGA 1000000 void speed_test (unsigned int num_amt, unsigned int runs); void diehard_test (unsigned int num_amt, unsigned int runs); void save_bytes_as_image (unsigned int total_rows, unsigned char * rand_bytes); int main (void) { unsigned int num_amt; // set amount of integers to generate: num_amt = 10 * MEGA; // use random() to generate random seed values: srandom(0); speed_test(num_amt, 10); diehard_test(num_amt, 10); exit(0); } void speed_test (unsigned int num_amt, unsigned int runs) { // Measure speed of RNG using clock() function. int i; unsigned int seed; clock_t start, stop; unsigned int run; unsigned int int_32; double total_time; printf ("\nGenerator: cellular automaton\n\n"); printf ("Run: Time to generate %u million integers (seconds):\n",num_amt/MEGA); total_time = 0; for (run = 0; run < runs; run++) { printf("%-3d ",run); seed = random(); start = clock(); ca_rng_initialize(seed); // initialize RNG and set seed for (i = 0; i < num_amt; i++) int_32 = ca_rng_get_int(); // generate a 32-bit unsigned integer stop = clock(); total_time += ((double) (stop - start)) / CLOCKS_PER_SEC; printf(" %-2.6f\n",((double) (stop - start)) / CLOCKS_PER_SEC ); } // for run printf("\nMean time for cellular automaton to generate %u million integers: %2.6f seconds.\n\n", num_amt/MEGA,total_time/runs); } // speed_test void diehard_test (unsigned int num_amt, unsigned int runs) { // Run Diehard tests on integers generated by RNG. // This function uses a Python script, 'parse-diehard.py', to parse Diehard results file. int i; unsigned int * rand_ints; FILE * fp; char fname[MAX_STRING_SIZE]; char sys_command[MAX_STRING_SIZE]; unsigned int run; unsigned int seed; rand_ints = (unsigned int *) malloc (num_amt * sizeof(unsigned int)); if (rand_ints == NULL) { printf ("malloc error.\n"); exit(1); } // back up current results file, if any: system ("cat 2>&1 ./result.txt >> ./result-backup.txt ; rm 2>&1 ./result.txt"); printf("Diehard tests, %u runs:\n\n",runs); printf("Run: Seed:\n"); for (run = 0; run < runs; run++) { // test min and max seed values: seed = 0; if (run == 1) seed = 0xFFFFFFFF; // test for random seed values: if (run > 1) seed = random(); // initialize RNG, set seed, and generate random integers: ca_rng_initialize(seed); for (i = 0; i < num_amt; i++) rand_ints[i] = ca_rng_get_int(); sprintf(fname,"ca-rng-seed-%u.bit",seed); printf("%3u %12u ",run + 1,seed); fp = fopen (fname,"wb"); assert (fwrite (rand_ints, sizeof (unsigned int), num_amt, fp)); fclose(fp); printf("running Diehard tests ... "); fflush(stdout); sprintf(sys_command,"diehard -t %s > /dev/null",fname); system(sys_command); // remove random number file: sprintf(sys_command,"rm %s",fname); system(sys_command); system("parse-diehard.py | grep -i failed"); } fflush(stdout); printf("\n"); free(rand_ints); } void save_bytes_as_image (unsigned int total_rows, unsigned char * rand_bytes) { // Save cellular automaton cells as a PPM image in greyscale: int i,j; FILE * fp; char header[MAX_STRING_SIZE]; unsigned int max_color_value; unsigned char intensity; max_color_value = 255; fp = fopen("ca-rng.ppm","w"); assert(fp); sprintf (header,"P6\n%u %u\n%u\n",CA_WIDTH,total_rows,max_color_value); fprintf (fp,header); for (i = 0; i < total_rows; i++) for (j = 0; j < CA_WIDTH; j++) { intensity = *(rand_bytes + (i * CA_WIDTH) + j); assert (fwrite (&intensity, sizeof (unsigned char), 1, fp)); assert (fwrite (&intensity, sizeof (unsigned char), 1, fp)); assert (fwrite (&intensity, sizeof (unsigned char), 1, fp)); } fclose (fp); } // save_bytes_as_image