SUBROUTINE C11 ( C, MODULUS, N, NUMSIZE, MODBITS, ERR ) c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c This subroutine checks the result matrix C for accuracy. c c Parameters: c c Provided by calling routine: c C = Matrix of multiple precision numbers c MODULUS = Large integer modulus, expressed as an array of c integers c N = The size of the matrices c NUMSIZE = The number of words to store an MP integer c MODBITS = The number of bits in MODULUS c c Returned by this routine: c ERR = An error flag c ERR = -1 Results for given input parameters are unknown c ERR = 0 No errors found c ERR = 1 Results do not agree with previous results c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c First determine if N and MODULUS are checkable. c The array NVAL has the 6 checkable values of N. c The array MODVAL has the hashes of the 10 checkable values of MODULUS. c (The hash is the low-order 40 bits added to the number of bits in MODULUS.) c c To check a result, sum all the entries in the matrix C, c reduce the sum mod MODULUS, and take the low order 40 bits. c This hash is compared with the value stored in the array HASHVAL. c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c IMPLICIT NONE c #include "bench11.h" c c This conditional compile flag (if set to 0) lets us compute check values c for additional dimension or modulus c #define CHECKIT 1 c INTEGER N, NUMSIZE, MODBITS, ERR INTEGER I, J, INVAL, IMODVAL, NUMBITS MPLONG HASHMASK, HASHMOD C--CVS variable declaration TYPE CVS sequence character( 160 ) string integer stringend END TYPE CVS C--CVS initilaize variables TYPE( CVS ),save :: CVS_INFO = $ CVS("BMARKGRP $Date: 2005/01/10 20:46:00 $ $Revision: 1.2 $" // $ "$RCSfile: c11.F,v $ $Name: rel_5 $", 0) c c Arrays to hold the product matrix and the modulus c These are allocated in main M11 at max size, we resize here c MPLONG C ( NUMSIZE, N, N ) MPLONG MODULUS ( NUMSIZE ) c c An array to accumulate the hash value on each PE c MPLONG HASH ( MAXNUMSIZE + 2 ) c c The checkable values for N c INTEGER NVAL(6) DATA NVAL / 5, 25, 100, 225, 256, 512 / c c The hashes of the checkable values for the modulus (defined in m11.F) c MPLONG MODVAL(10) c DATA MODVAL / 769620223922, 1099511627864, 1099511627902, * 837833903585, 437966830978, 662963509255, 1099511628287, * 905988786803, 235144688006, 773679418188 / c c The check values for the 6 choices of N and 10 choices of Modulus c MPLONG HASHVAL(6,10) c DATA HASHVAL / 1 196701556000, 043947186305, 415954941181, 431191719692, 1 075966428156, 212736108236, 2 339405043757, 854026220207, 596320431790, 1011062447332, 2 1081646558404, 017515865229, 3 970101264310, 1015647515594, 604848150241, 321147114478, 3 1072606644286, 324925765912, 4 128205667170, 413366486950, 255765451886, 413706993346, 4 173612401038, 221996879184, 5 997398669265, 643552455682, 214037984995, 109566680042, 5 644894836631, 172264824793, 6 697693377693, 859802640872, 067608713549, 335746255143, 6 569373860052, 655903367024, 7 182948179528, 1006573637617, 1053609606664, 079021183210, 7 988912737077, 523823096749, 8 645006580755, 082070920319, 830040110368, 565923891462, 8 642105336411, 1030224153636, 9 597097122329, 318139893111, 905362215347, 474532250137, 9 638324121124, 702180515800, * 719199877913, 925428265878, 549095547958, 028967597754, * 747817176566, 820228776254 / c HASHMASK = Z'FFFFFFFFFF' c cccccccccccccc VERBOSE Output ccccccccccccccc IF (VERBOSE .GT. 0) THEN PRINT*, "CALL C11(",N,", MODULUS, -, -)" PRINT*, " (Check the results)" ENDIF ccccccccccccccccccccccccccccccccccccccccccccccc c c This conditional compile (if 0) lets us compute check values for c additional dimension or modulus c #if CHECKIT c c Check to see if the size of the matrices can be checked c DO 10, I = 1, 6 IF (N .EQ. NVAL(I)) GOTO 20 10 CONTINUE ERR = -1 IF (VERBOSE .GT. 0) THEN PRINT*, "Matrix Size not found. Cannot check results." ENDIF RETURN c 20 continue INVAL = I c c Hash the MODULUS - add low order 40 bits to number of bits c HASHMOD = MODULUS(MPDATA) + ISHFT(MODULUS(MPDATA+1), BITSPERWORD) HASHMOD = IAND( HASHMOD, HASHMASK ) + MODBITS c c Check to see if the modulus can be checked c DO 30, I = 1, 10 IF (HASHMOD .EQ. MODVAL(I)) GOTO 40 30 CONTINUE ERR = -1 IF (VERBOSE .GT. 0) THEN PRINT*, "Modulus not found. Cannot check results" ENDIF RETURN c 40 CONTINUE IMODVAL = I c #endif CHECKIT c c Compute the hash used to verify the accuracy of the answer. c The hash function adds all of the elements of the product matrix C, c reduces mod MODULUS, and uses the low order 40 bits as the hash. c c Here each PE adds and reduces its submatrix of C to get a sub-hash. c c First initialize HASH c HASH(MPALLOC) = MAXNUMSIZE - 1 #if (GMP32 == 0) HASH(MPSIZE) = 0 #endif #ifdef GMP HASH(MPPTR) = LOC( HASH(MPDATA) ) #endif HASH(MPDATA) = 0 c c Now add them all up c DO 310, I = 1, N DO 300, J = 1, N CALL MPADD( HASH, HASH, C(1,I,J) ) 300 CONTINUE 310 CONTINUE c c Now reduce mod MODULUS c CALL MPMOD( HASH, HASH, MODULUS ) c HASHMOD = HASH(MPDATA) + ISHFT( HASH(MPDATA+1), BITSPERWORD ) HASHMOD = IAND( HASHMOD, HASHMASK ) c #if CHECKIT c IF ( HASHMOD .EQ. HASHVAL(INVAL, IMODVAL) ) THEN ERR = 0 IF (VERBOSE .GT. 0) PRINT*, "Check successful" ELSE ERR = 1 IF (VERBOSE .GT. 0) PRINT*, "Check not successful" ENDIF #else PRINT *, "HASH = ", HASHMOD #endif c RETURN END