SUBROUTINE C11 ( C, MODULUS, N, M, NUMSIZE, MODBITS, ERR ) c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c CVS Info c $Date: 2005/01/10 21:56:20 $ c $Revision: 1.2 $ c $RCSfile: c11.F,v $ c $Name: rel_5 $ 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, stored as an array of integers c N = The size of the matrices c M = The size of the sub-matrices on each PE 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 ERR = 2 MPI_GATHER failed, can't calc global hash c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c First determine if N and MODULUS are checkable. c The array NVAL has the 8 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 c If running on more than 1 PE, each PE sums the entries of its subblock of C, c and reduces by MODULUS. Then gather all the local sums to PE0, which c adds them up, mods again, and then takes the low 40 bits. c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c IMPLICIT NONE c #include "bench11.h" #include 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 21:56:20 $ $Revision: 1.2 $" // $ "$RCSfile: c11.F,v $ $Name: rel_5 $", 0) 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, M, NUMSIZE, MODBITS, ERR INTEGER I, J, INVAL, IMODVAL, NUMBITS, GATHERSIZE, IER MPLONG MAXPES, HASHMASK, TEMPINT, HASHMOD 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, M, M ) MPLONG MODULUS ( NUMSIZE ) c c An array to accumulate the hash value on each PE c MPLONG HASH ( MAXNUMSIZE + 2 ) c PARAMETER (MAXPES = 256) c c An array to gather the hash values of the sub-matrices c MPLONG HASHES ( MAXNUMSIZE + 1, MAXPES ) c c The checkable values for N c INTEGER NVAL(8) DATA NVAL / 5, 25, 100, 225, 256, 512, 640, 1024 / 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 8 choices of N and 10 choices of Modulus c MPLONG HASHVAL(8,10) c DATA HASHVAL / 1 196701556000, 043947186305, 415954941181, 431191719692, 1 075966428156, 212736108236, 581788714223, 930414141506, 2 339405043757, 854026220207, 596320431790, 1011062447332, 2 1081646558404, 017515865229, 944700882948, 900606735395, 3 970101264310, 1015647515594, 604848150241, 321147114478, 3 1072606644286, 324925765912, 479507642392, 824083076377, 4 128205667170, 413366486950, 255765451886, 413706993346, 4 173612401038, 221996879184, 524037383687, 547023462324, 5 997398669265, 643552455682, 214037984995, 109566680042, 5 644894836631, 172264824793, 797513203513, 1083418379931, 6 697693377693, 859802640872, 067608713549, 335746255143, 6 569373860052, 655903367024, 361907535629, 550547090012, 7 182948179528, 1006573637617, 1053609606664, 079021183210, 7 988912737077, 523823096749, 218881285726, 793488743659, 8 645006580755, 082070920319, 830040110368, 565923891462, 8 642105336411, 1030224153636, 953815689861, 152957459606, 9 597097122329, 318139893111, 905362215347, 474532250137, 9 638324121124, 702180515800, 41936885391, 491109852649, * 719199877913, 925428265878, 549095547958, 028967597754, * 747817176566, 820228776254, 678070998066, 980791895706 / 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, 8 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, M DO 300, J = 1, M 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 c If many PEs, gather all the sub-hashes to PE 0, add them up, mod again c IF (NPES .GT. 1) THEN c GATHERSIZE = MAXNUMSIZE + 1 c CALL MPI_GATHER ( HASH, GATHERSIZE, MY_INTEGER, * HASHES(1,1), GATHERSIZE, MY_INTEGER, * 0, MPI_COMM_WORLD, IER ) c IF (IER .NE. 0) THEN ERR = 2 IF (VERBOSE .GT. 0) PRINT*, "MPI_GATHER failed, can't check" RETURN ENDIF c IF (MYPE .EQ. 0) THEN c DO 320, I = 2, NPES #ifdef GMP HASHES(MPPTR,I) = LOC ( HASHES(MPDATA,I) ) #endif CALL MPADD ( HASH, HASH, HASHES(1,I) ) 320 CONTINUE c CALL MPMOD( HASH, HASH, MODULUS ) c ENDIF c ENDIF c c Only PE0 does and checks final 40-bit hash c IF (MYPE .EQ. 0) THEN c HASHMOD = HASH(MPDATA) + ISHFT( HASH(MPDATA+1), BITSPERWORD ) HASHMOD = IAND( HASHMOD, HASHMASK ) c print *, hashmod 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 ENDIF c RETURN END