PROGRAM M8D c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c Benchmark #8 -- Dynamic Program c c Small dense matrices (Part a) c c Assumption: All values in the A matrices are nonnegative c (Since these are state transition porbabilities, this c is a reasonable assumption.) c c The Problem: c c Given: A[1],A[2],...A[K], N x N floating point matrices c D, an 8-bit integer vector of length T where c 1 <= D(t) <= K for t = 1,2,...T c c Calculate: Y[0],Y[1],...Y[T] 64-bit floating point vectors of length N c P[1],P[2],...P[T] 32-bit integer vectors of length N c B, a T+1 long 32-bit integer vector where c 1 <= B(t) <= N for t = 0,1,2,...T c according to the following algorithm. c c Y[0](i) = 1 for i = 1,2,...N c For t = 1,2,...,T c k = D(t) c For j = 1,2,...,N c Y[t](j) = max Y[t-1](i)*A[k](i,j) c i c P[t](j) = any i which maximized Y[t](j) c Next j c Next t c c Let Z = max Y[T](i), and let I be any i which maximized Z. c i c c Set B(T) = I c For t = T-1,T-2,...,1,0 c Set B(t) = P[t+1](B(t+1)) c Next t c c Output Z and B(t) for t = 0,1,2,...T. c c Parameters: N = 10 K = 30 T = 100,000 ITER = 400 c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c Main Program for the small dense matrix version of Benchmark #8 c c Call time parameters: c c N = Size of the A matrices c Maximum = 30 c Default = 10 c c K = Number of A matrices c Maximum = 50 c Default = 30 c c T = Length of D array c Maximum = Default = 100 000 c c ITER = Number of times to repeat the experiment c Maximum = 1000 c Default = 400 c c NOTE: In order to remove the complexity of using IO c to secondary storage, this benchmark is repeated ITER c times (on different data each time) and the time is c accumulated. This will NOT be considered a legitimate loop c for parallelization, since it is done ONLY to reduce the c complexity of the problem. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c USE LIMITS c Variables for timing purposes REAL CPUTIME,WALL,X0,Y0,CSET,WSET,CRUN,WRUN c c Array for run time parameters CHARACTER*80 ARG, NAME INTEGER ARGLEN EXTERNAL IRAND c c The maximum size of the matrices and vectors PARAMETER (MN=B8_MN) c c The maximum number of matrices PARAMETER (MK=B8_MK) c c The maximum length of the D array PARAMETER (MT = B8_MT) c c Which matrix to use in each step. INTEGER D(MT) c c The matrices REAL A(MN*MN*MK) c c The best path INTEGER B(0:MT) c c The scaling factor which to multiply the columns of AA by in order to c obtain the A matrices REAL TIMES(MN*MK) REAL AA(MN*MN) c c Error flag array INTEGER IER(3) c c Input parameters INTEGER T 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/07 23:07:10 $ $Revision: 1.2 $" // $ "$RCSfile: m8d.f,v $ $Name: rel_5 $", 0) c c Get input parameters c Get N, the matrix size c ARGLEN=GETARG_COM(1,ARG) READ(ARG,5) N 5 FORMAT(I15) c Default IF(N .LE. 0) N = 10 c Check for in range IF(N .GT. MN) THEN PRINT 15, MN,N 15 FORMAT('Maximum allowed value for N is ',I5,' N = ',I5) STOP ENDIF c c Get K, the number of matrices ARGLEN=GETARG_COM(2,ARG) READ(ARG,5) K c Default IF(K .LE. 0) K = 30 c Check for in range IF(K .GT. MK) THEN PRINT 25, MK, K 25 FORMAT('Maximum allowed value for K is ',I5,' K = ',I5) STOP ENDIF c c Get T, the length of the D array ARGLEN=GETARG_COM(3,ARG) READ(ARG,5) T c Default IF(T .LE. 0) T = 100 000 c Check for in range IF(T .GT. MT) THEN PRINT 35, MT, T 35 FORMAT('Maximum allowed value for T is ',I9,' T = ',I9) STOP ENDIF c c Get ITER, the number of iterations of this benchmark to do ARGLEN=GETARG_COM(4,ARG) READ(ARG,5) ITER c Default IF(ITER .LE. 0) ITER = 400 IF(ITER .GT. 1000) ITER = 400 c c Initialize the random number generator I = IRAND(-99908) c c Initialize timing variables CSET=0.0 WSET=0.0 CRUN=0.0 WRUN=0.0 c c For each iteration of the benchmark DO 40 JTER=1,ITER c c Generate D, and matrices A, and array TIMES X0 = CPUTIME() Y0 = WALL() c CALL S8D(N, K, T, D, A, TIMES, AA) c CSET = CSET + CPUTIME() - X0 WSET = WSET + WALL() - Y0 c c Time the actual work being done in subroutine P8D X0 = CPUTIME() Y0 = WALL() CALL P8D(A,D,B,N,K,T,TIMES,AA,Z) CRUN = CRUN + CPUTIME() - X0 WRUN = WRUN + WALL() -Y0 c c Check the results CALL C8D(N,K,T,D,A,B,Z,ZZ,JTER,IER) c 40 CONTINUE c c Output results CALL R8D(N,K,T,ITER,B,Z,ZZ,CSET,WSET,CRUN,WRUN,IER) c STOP END c FUNCTION GETARG (ARGNUM, OUTBUF) c INTEGER GETARG c CHARACTER*80 OUTBUF c INTEGER ARGNUM, IERROR c INTEGER ERRVAL, CONERR cC-----Read argument ARGNUM into character buffer OUTBUF and return the cC-----string length GETARG. c CALL PXFGETARG(ARGNUM, OUTBUF, GETARG, IERROR) cC-----If there is an error, try to analyze and set values like real GETARG c IF( IERROR .NE. 0) THEN cC--------Get error value for invalid argument c CALL PXFCONST ("EINVAL", ERRVAL, CONERR) cC--------Does argument ARGNUM exist? c IF(IERROR .EQ. ERRVAL) THEN cC-----------Does not exist. Make OUTBUF "-1" so a READ of OUTBUF returns -1 c OUTBUF = "-1" cC-----------String length 0 c GETARG = 0 c RETURN c END IF cC--------Get error value for truncated argument c CALL PXFCONST ("ETRUNC", ERRVAL, CONERR) cC--------Was the argument truncated? c IF(IERROR .EQ. ERRVAL) THEN c GETARG = 80 c RETURN c END IF c END IF c RETURN c END