/************************************************************************** * * Subroutine C11 checks the result matrix C for accuracy. * * Parameters: * * Provided by calling routine: * C = Matrix of multiple precision numbers * MODULUS = Large integer modulus, expressed as an array of integers * N = The size of the matrices * NUMSIZE = The number of words to store an MP integer * MODBITS = The number of bits in MODULUS * * The routine returns a value: * -1 Results for given input parameters are unknown * 0 No errors found * 1 Results do not agree with previous results * *************************************************************************** * * First determine if N and MODULUS are checkable. * The array NVAL has the 6 checkable values of N. * The array MODVAL has the hashes of the 10 checkable values of MODULUS. * (The hash is the low-order 40 bits added to the number of bits in MODULUS.) * * To check a result, sum all the entries in the matrix C, * reduce the sum mod MODULUS, and take the low order 40 bits. * This hash is compared with the value stored in the array HASHVAL. * **************************************************************************/ #include "bench11.h" /* CVS info */ /* $Date: 2005/01/10 20:57:47 $ */ /* $Revision: 1.2 $ */ /* $RCSfile: c11.c,v $ */ /* $Name: rel_5 $ */ static char cvs_info[] = "BMARKGRP $Date: 2005/01/10 20:57:47 $ $Revision: 1.2 $ $RCSfile: c11.c,v $ $Name: rel_5 $"; /* This conditional compile flag (if set to *0*) lets us compute new check values for additional dimension or modulus */ #define CHECKVALS 1 /* macro to address 3-dim array with variable dimension */ #define c(I,J,K) c[ K + numsize * ( (J) + n * (I) ) ] int c11 ( mplong c[], mplong modulus[], int n, int numsize, int modbits ) { int i, j, matsizeind = -1, modvalind = -1; mplong hashmod; /* An array to accumulate the hash value */ mplong hash [ maxnumsize + 2 ]; /* The checkable values for N */ const int matsize[6] = { 5, 25, 100, 225, 256, 512 }; /* The hashes of the checkable values for the modulus (defined in m11.c) */ const unsigned mplong modval[10] = { 769620223922, 1099511627864, 1099511627902, 837833903585, 437966830978, 662963509255, 1099511628287, 905988786803, 235144688006, 773679418188 }; /* The check values for the 6 choices of N and 10 choices of Modulus */ const mplong hashval[10][6] = { { 196701556000, 43947186305, 415954941181, 431191719692, 75966428156, 212736108236 }, { 339405043757, 854026220207, 596320431790, 1011062447332, 1081646558404, 17515865229 }, { 970101264310, 1015647515594, 604848150241, 321147114478, 1072606644286, 324925765912 }, { 128205667170, 413366486950, 255765451886, 413706993346, 173612401038, 221996879184 }, { 997398669265, 643552455682, 214037984995, 109566680042, 644894836631, 172264824793 }, { 697693377693, 859802640872, 67608713549, 335746255143, 569373860052, 655903367024 }, { 182948179528, 1006573637617, 1053609606664, 79021183210, 988912737077, 523823096749 }, { 645006580755, 82070920319, 830040110368, 565923891462, 642105336411, 1030224153636 }, { 597097122329, 318139893111, 905362215347, 474532250137, 638324121124, 702180515800 }, { 719199877913, 925428265878, 549095547958, 28967597754, 747817176566, 820228776254 } }; const mplong hashmask = 0xFFFFFFFFFF; extern int verbose; if (verbose) { printf( "CALL C11(%d, MODULUS, -, -) \n", n ); printf( " (Check the results) \n" ); } /* This conditional compile (if 0) lets us compute new check values for additional dimension or modulus */ #if CHECKVALS /* Check to see if the size of the matrices can be checked */ for ( i = 0; i < 6; i++ ) { if (n == matsize[i]) { matsizeind = i; break; } } if (matsizeind == -1) { if (verbose) printf( "Matrix Size not found. Cannot check results.\n" ); return(-1); } /* Hash the MODULUS - add low order 40 bits to number of bits */ #if (BITSPERWORD != 64) hashmod = modulus[MPDATA] + ( modulus[MPDATA+1] << BITSPERWORD ); #else hashmod = modulus[MPDATA]; #endif hashmod = ( hashmod & hashmask ) + modbits; /* Check to see if the modulus can be checked */ for ( i = 0; i < 10; i++ ) { if (hashmod == modval[i]) { modvalind = i; break; } } if (modvalind == -1) { if (verbose) printf( "Modulus not found. Cannot check results.\n" ); return(-1); } #endif /* CHECKVALS */ /* * Compute the hash used to verify the accuracy of the answer. * The hash function adds all of the elements of the product matrix C, * reduces mod MODULUS, and uses the low order 40 bits as the hash. */ /* First initialize HASH */ hash[MPALLOC] = maxnumsize - 1; #if (GMP32 == 0) hash[MPSIZE] = 0; #endif #ifdef GMP hash[MPPTR] = (mplong) & hash[MPDATA]; #endif hash[MPDATA] = 0; /* Now add them all up */ for ( i = 0; i < n; i++) for ( j = 0; j < n; j++) { mpadd( hash, hash, &c(i,j,0) ); } /* Now reduce mod MODULUS */ mpmod( hash, hash, modulus ); #if (BITSPERWORD != 64) hashmod = hash[MPDATA] + ( hash[MPDATA+1] << BITSPERWORD ); #else hashmod = hash[MPDATA]; #endif hashmod = hashmod & hashmask; #if CHECKVALS if ( hashmod == hashval[modvalind][matsizeind] ) { if (verbose) printf( "Check successful \n" ); return ( 0 ); } else { if (verbose) printf( "Check not successful \n" ); return ( 1 ); } #else /* print hash = new check value for new N or MODULUS */ printf( "HASH = %ld \n", hashmod ); #endif return(0); }