*
* ACML version 3.5 Copyright AMD,NAG 2006
*
      PROGRAM MAIN
      IMPLICIT         NONE
*     .. Parameters ..
      INTEGER          MAXM, MAXMN, MAXN, NN
      PARAMETER        (MAXM=5000,MAXMN=25000000,MAXN=5000,NN=6)
      INTEGER          LCBUFF
      PARAMETER        (LCBUFF=2*MAXMN+5*(MAXN+MAXM))
      REAL             ALIM, BLIM
      PARAMETER        (ALIM=0.0,BLIM=1.0)
*     .. Local Scalars ..
      INTEGER          ISIGN, J, M, N, NRUNS
*     .. Local Arrays ..
      COMPLEX          CBUFF(LCBUFF)
      REAL             ENS(NN)
*     .. External Subroutines ..
      EXTERNAL         DOTIME
*     .. Data statements ..
      DATA             ENS/128, 256, 512, 1024, 2048, 4096/
*     .. Executable Statements ..
      CONTINUE
*
*     Time NRUNS forward transforms
*
      ISIGN = -1
      NRUNS = 4
*
      DO 20 J = 1, NN
*
         N = ENS(J)
*
*        To time different data, change ENS, NN, and MAXN, above,
*        accordingly.
*
         M = N
*
         IF (M.GT.MAXN) THEN
            WRITE (*,FMT=*) 'M too large; increase MAXN.'
         ELSE
            CALL DOTIME(M,N,ISIGN,CBUFF(1),CBUFF(M*N+1),ALIM,BLIM,NRUNS)
         END IF
*
   20 CONTINUE
*
      END
*
*-----------------------------------------------------------------------
*-----------------------------------------------------------------------
*
      SUBROUTINE DOTIME(M,N,ISIGN,X,WORK,ALIM,BLIM,NRUNS)
      IMPLICIT         NONE
*     .. Scalar Arguments ..
      REAL             ALIM, BLIM
      INTEGER          ISIGN, M, N, NRUNS
*     .. Array Arguments ..
      COMPLEX          WORK(M*N+5*(M+N)), X(M*N)
*     .. Local Scalars ..
      DOUBLE PRECISION DNFLOP, MFX, TX, TX0, TX1
      INTEGER          INFO, J
*     .. External Functions ..
      DOUBLE PRECISION DSECND
      EXTERNAL         DSECND
*     .. External Subroutines ..
      EXTERNAL         CFFT2D, RANDCVEC
*     .. Intrinsic Functions ..
      INTRINSIC        DBLE, LOG, MIN
*     .. Executable Statements ..
      CONTINUE
*
*     Number of MFLOPs in a CFFT2D of size M-by-N:
*
      DNFLOP = DBLE(M*N)*LOG(DBLE(N*M))*5.0D-6/LOG(2.0D0)
*
*     Generate random vector X
*
      CALL RANDCVEC(ALIM,BLIM,M*N,X)
*
*     Using CFFT2D. Record best time over NRUNS runs.
*
      TX = 1.0D30
      DO 20 J = 1, NRUNS
         TX0 = DSECND()
         CALL CFFT2D(ISIGN,M,N,X,WORK,INFO)
         TX1 = DSECND()
         IF (TX1-TX0.GT.0.0D0) TX = MIN(TX,TX1-TX0)
   20 CONTINUE
*
*     Print the results
*
      IF (INFO.EQ.0) THEN
         IF (TX.LE.0.0D0) THEN
            MFX = 0.0D0
         ELSE
            MFX = DNFLOP/TX
         END IF
         WRITE (*,FMT=*) N, MFX
      ELSE
         WRITE (*,FMT=*) 'CFFT2D failed with INFO = ', INFO
      END IF
*
      RETURN
      END
*
      SUBROUTINE RANDCVEC(ALIM,BLIM,N,A)
*     .. Parameters ..
      INTEGER          MSTATE, MSEED
      PARAMETER        (MSTATE=633,MSEED=624)
*     .. Scalar Arguments ..
      REAL             ALIM, BLIM
      INTEGER          N
*     .. Array Arguments ..
      COMPLEX          A(N)
*     .. Local Scalars ..
      INTEGER          GENID, I, INFO, LSEED, LSTATE, SUBID
*     .. Local Arrays ..
      REAL             IMA(N), REA(N)
      INTEGER          SEED(MSEED), STATE(MSTATE)
*     .. External Subroutines ..
      EXTERNAL         SRANDINITIALIZE, SRANDUNIFORM
*     .. Intrinsic Functions ..
      INTRINSIC        CMPLX
*     .. Executable Statements ..
      CONTINUE
*
*     Use the Mersenne twister generator as the base generator
*
      GENID = 3
      SUBID = 1
*
      LSTATE = MSTATE
      LSEED = 1
      SEED(1) = 1071958
*
*     Initialize the base generator
*
      CALL SRANDINITIALIZE(GENID,SUBID,SEED,LSEED,STATE,LSTATE,INFO)
*
*     Generate real and imaginary parts from a uniform U(ALIM,BLIM)
*     distribution
*
      CALL SRANDUNIFORM(N,ALIM,BLIM,STATE,REA,INFO)
      CALL SRANDUNIFORM(N,ALIM,BLIM,STATE,IMA,INFO)
*
      DO 20 I = 1, N
         A(I) = CMPLX(REA(I),IMA(I))
   20 CONTINUE
*
      RETURN
      END
