SUBROUTINE S11 ( A, B, N, NUMSIZE, MODBITS ) c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c This subroutine builds the "random" matrices A and B. c c Parameters: c c Provided by calling routine: c N = The size of the matrices to be multiplied c NUMSIZE = The number of words used to store an MP integer c (passed in so S11 can declare arrays with exact dimensions) c MODBITS = The number of bits in the MODULUS c c Returned by this routine: c A = Matrix of multiple precision numbers c B = Matrix of multiple precision numbers c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c IMPLICIT NONE c #include "bench11.h" c INTEGER N, NUMSIZE, ABCNUMSIZE, MODBITS c INTEGER MODSIZE, FULLWORDS, EXTRABITS, EXTRABITMASK, NUMRANDS INTEGER FULLWORDS, EXTRABITS, NUMRANDS INTEGER SKIPBITS, BITCTR, WORDCTR INTEGER*8 MODSIZE, ASIZE, BSIZE, EXTRABITMASK 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:01 $ $Revision: 1.2 $" // $ "$RCSfile: s11.F,v $ $Name: rel_5 $", 0) c c Arrays to hold the matrices c These are allocated in main M11, we set shape here c MPLONG A ( NUMSIZE, N, N ) MPLONG B ( NUMSIZE, N, N ) c c Array to hold enough bits for one row (N long) of A and B c 2 matrices, N may be 2*MAXMATSIZE c c INTEGER*8 on DEC c INTEGER*8 TEMPBITS ( 0 : (4*MAXMATSIZE*MAXBITSIZE)/64 ) c c Other variables c INTEGER IROW, MYFIRST, MYLAST, RANWDS INTEGER I, J, K c ABCNUMSIZE = NUMSIZE - MPHL c cccccccccccccc VERBOSE Output ccccccccccccccc IF(VERBOSE .GT. 0) THEN PRINT*, "CALL S11(",N,", modulus, -, -)" PRINT*, " (Set up the matrices)" ENDIF ccccccccccccccccccccccccccccccccccccccccccccccc c MODSIZE = NUMSIZE - MPHL c c Set up counters and mask needed to fill A and B c FULLWORDS = MODBITS / BITSPERWORD EXTRABITS = MOD ( MODBITS, BITSPERWORD ) IF (EXTRABITS .GT. 0) THEN EXTRABITMASK = ISHFT(BITMASK, EXTRABITS - BITSPERWORD) ENDIF c IF(VERBOSE .GT. 0) THEN PRINT*," Modulus has ",MODBITS," bits" PRINT*," Fill the matrices" ENDIF c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c Use the random number generator to fill the matrices A and B. c c Place the random bits into the multiple precision numbers which c make up A and B. c c Each PE fills the M x M submatrix of A and of B that resides on that PE. c For each row in its block, the PE generates all the random bits c for that row, and then fills only the appropriate columns of A and B. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c Initialize the structures for the multi-precision integers c DO 250, I = 1, N DO 250, J = 1, N #if (GMP32 == 0) A(MPALLOC,I,J) = ABCNUMSIZE A(MPSIZE, I,J) = MODSIZE #else A(MPALLOC,I,J) = ABCNUMSIZE + ISHFT( MODSIZE, 32 ) #endif #ifdef GMP A(MPPTR, I,J) = LOC( A(MPDATA,I,J) ) #endif #if (GMP32 == 0) B(MPALLOC,I,J) = ABCNUMSIZE B(MPSIZE, I,J) = MODSIZE #else B(MPALLOC,I,J) = ABCNUMSIZE + ISHFT( MODSIZE, 32 ) #endif #ifdef GMP B(MPPTR, I,J) = LOC( B(MPDATA,I,J) ) #endif 250 CONTINUE c c RANWDS 64-bit random binary words will fill a row of A and B c RANWDS = ( (2*N*MODBITS) + 63 ) / 64 c DO 450, I = 1, N c c Generate random bits for this row # of A and B in the array TEMPBITS c IROW = I c CALL GET_MY_BDATA64(IROW, 1, 1, RANWDS, 1, -99911, TEMPBITS, * MYFIRST, MYLAST) c c These counters keep track of position in TEMPBITS c WORDCTR = 0 BITCTR = 0 c DO 400, J = 1, N c c Fill the low order words of A(I,J) c DO 300, K = MPDATA, MPDATA + FULLWORDS - 1 #if (BITSPERWORD==64) A(K,I,J) = IOR ( * ISHFT(TEMPBITS(WORDCTR), -BITCTR), * ISHFT(TEMPBITS(WORDCTR+1),64-BITCTR) ) WORDCTR = WORDCTR + 1 #else A(K,I,J) = IAND ( * IOR ( ISHFT(TEMPBITS(WORDCTR), -BITCTR), * ISHFT(TEMPBITS(WORDCTR+1),64-BITCTR) ), * BITMASK ) BITCTR = BITCTR + BITSPERWORD IF (BITCTR .GE. 64) THEN WORDCTR = WORDCTR + 1 BITCTR = BITCTR - 64 ENDIF #endif 300 CONTINUE c c Partially fill the last word of A(I,J) with EXTRABITS bits c IF (EXTRABITS .NE. 0) THEN K = MPDATA + FULLWORDS c A(K,I,J) = IAND ( * IOR ( ISHFT(TEMPBITS(WORDCTR), -BITCTR), * ISHFT(TEMPBITS(WORDCTR+1),64-BITCTR) ), * EXTRABITMASK ) c BITCTR = BITCTR + EXTRABITS IF (BITCTR .GE. 64) THEN WORDCTR = WORDCTR + 1 BITCTR = BITCTR - 64 ENDIF ENDIF c c Fill the low order words of B(I,J) c DO 350, K = MPDATA, MPDATA + FULLWORDS - 1 #if (BITSPERWORD==64) B(K,I,J) = IOR ( * ISHFT(TEMPBITS(WORDCTR), -BITCTR), * ISHFT(TEMPBITS(WORDCTR+1),64-BITCTR) ) WORDCTR = WORDCTR + 1 #else B(K,I,J) = IAND ( * IOR ( ISHFT(TEMPBITS(WORDCTR), -BITCTR), * ISHFT(TEMPBITS(WORDCTR+1),64-BITCTR) ), * BITMASK ) BITCTR = BITCTR + BITSPERWORD IF (BITCTR .GE. 64) THEN WORDCTR = WORDCTR + 1 BITCTR = BITCTR - 64 ENDIF #endif 350 CONTINUE c c Partially fill the last word of B(I,J) with EXTRABITS bits c IF (EXTRABITS .NE. 0) THEN K = MPDATA + FULLWORDS c B(K,I,J) = IAND ( * IOR ( ISHFT(TEMPBITS(WORDCTR), -BITCTR), * ISHFT(TEMPBITS(WORDCTR+1),64-BITCTR) ), * EXTRABITMASK ) c BITCTR = BITCTR + EXTRABITS IF (BITCTR .GE. 64) THEN WORDCTR = WORDCTR + 1 BITCTR = BITCTR - 64 ENDIF ENDIF 400 CONTINUE ! loop on J c 450 CONTINUE ! loop on I c c Go through the entries of A and B. c If the top order word(s) is zero, reset the usage counter. c This normalizes the form of the multiple precision number. c DO 600, I = 1, N DO 610, J = 1, N c c work backwards from highest-order limb c #if (GMP32 == 0) ASIZE = A(MPSIZE,I,J) #else ASIZE = ISHFT( A(1,I,J), -32 ) #endif IF (ASIZE .NE. 0) THEN DO 650 K = NUMSIZE, MPDATA, -1 IF (A(K,I,J) .EQ. 0) THEN ASIZE = ASIZE - 1 ELSE GOTO 660 ENDIF 650 CONTINUE 660 CONTINUE #if (GMP32 == 0) A(MPSIZE,I,J) = ASIZE #else A(1,I,J) = IAND(A(1,I,J),BITMASK32) + ISHFT(ASIZE,32) #endif ENDIF c #if (GMP32 == 0) BSIZE = B(MPSIZE,I,J) #else BSIZE = ISHFT( B(1,I,J), -32 ) #endif IF (BSIZE .NE. 0) THEN DO 670 K = NUMSIZE, MPDATA, -1 IF (B(K,I,J) .EQ. 0) THEN BSIZE = BSIZE - 1 ELSE GOTO 680 ENDIF 670 CONTINUE 680 CONTINUE #if (GMP32 == 0) B(MPSIZE,I,J) = BSIZE #else B(1,I,J) = IAND(B(1,I,J),BITMASK32) + ISHFT(BSIZE,32) #endif ENDIF 610 CONTINUE 600 CONTINUE c cccccccccccccc VERBOSE Output ccccccccccccccc c IF(VERBOSE .GT. 1) THEN C IF((VERBOSE .GT. 1) .AND. (MYPE .EQ. 0)) THEN c c Test for consistency by printing out the filled matrices c PRINT*, "S11 Consistency Check - Matrix A:" DO 700, I = 1, N PRINT*, "Row ", I DO 700, J = 1, N CALL MPWRITE(A(1,I,J)) c print* 700 CONTINUE c PRINT*, "S11 Consistency Check - Matrix B:" DO 750, I = 1, N PRINT*, "Row ", I DO 750, J = 1, N CALL MPWRITE(B(1,I,J)) c print* 750 CONTINUE c c STOP ENDIF c cccccccccccccccccccccccccccccccccccccccccccccccc c RETURN END