*
* ACML version 3.5 Copyright AMD,NAG 2006
*
      PROGRAM MAIN
      IMPLICIT         NONE
*     .. Parameters ..
      INTEGER          MAXN, NN
      PARAMETER        (MAXN=4194304,NN=19)
      INTEGER          LCBUFF
      PARAMETER        (LCBUFF=4*MAXN+100)
      DOUBLE PRECISION ALIM, BLIM
      PARAMETER        (ALIM=0.0D0,BLIM=1.0D0)
*     .. Local Scalars ..
      INTEGER          ISIGN, J, N, NRUNS
*     .. Local Arrays ..
      COMPLEX *16      CBUFF(LCBUFF)
      DOUBLE PRECISION ENS(NN)
*     .. External Subroutines ..
      EXTERNAL         DOTIME
*     .. Data statements ..
      DATA             ENS/16, 32, 64, 128, 256, 512, 1024, 2048, 4096,
     *                 8192, 16384, 32768, 65536, 131072, 262144,
     *                 524288, 1048576, 2097152, 4194304/
*     .. 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.
*
         IF (N.GT.MAXN) THEN
            WRITE (*,FMT=*) 'N too large; increase MAXN.'
         ELSE
            CALL DOTIME(N,ISIGN,CBUFF(1),CBUFF(N+1),ALIM,BLIM,NRUNS)
         END IF
*
   20 CONTINUE
*
      END
*
*-----------------------------------------------------------------------
*-----------------------------------------------------------------------
*
      SUBROUTINE DOTIME(N,ISIGN,X,WORK,ALIM,BLIM,NRUNS)
      IMPLICIT         NONE
*     .. Scalar Arguments ..
      DOUBLE PRECISION ALIM, BLIM
      INTEGER          ISIGN, N, NRUNS
*     .. Array Arguments ..
      COMPLEX *16      WORK(3*N+100), X(N)
*     .. Local Scalars ..
      DOUBLE PRECISION DNFLOP, MFX, TX, TX0, TX1
      INTEGER          INFO, J
*     .. External Functions ..
      DOUBLE PRECISION DSECND
      EXTERNAL         DSECND
*     .. External Subroutines ..
      EXTERNAL         RANDZVEC, ZFFT1D
*     .. Intrinsic Functions ..
      INTRINSIC        DBLE, LOG, MIN
*     .. Executable Statements ..
      CONTINUE
*
*     Number of MFLOPs in a ZFFT1D of size N:
*
      DNFLOP = DBLE(N)*LOG(DBLE(N))*5.0D-6/LOG(2.0D0)
*
*     Generate random vector X
*
      CALL RANDZVEC(ALIM,BLIM,N,X)
*
*     Initialization call to ZFFT1D
*
      INFO = 0
      CALL ZFFT1D(0,N,X,WORK,INFO)
*
*     Using ZFFT1D. Record best time over NRUNS runs.
*
      TX = 1.0D30
      DO 20 J = 1, NRUNS
         TX0 = DSECND()
         CALL ZFFT1D(ISIGN,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=*) 'ZFFT1D failed with INFO = ', INFO
      END IF
*
      RETURN
      END
*
      SUBROUTINE RANDZVEC(ALIM,BLIM,N,A)
*     .. Parameters ..
      INTEGER          MSTATE, MSEED
      PARAMETER        (MSTATE=633,MSEED=624)
*     .. Scalar Arguments ..
      DOUBLE PRECISION ALIM, BLIM
      INTEGER          N
*     .. Array Arguments ..
      COMPLEX *16      A(N)
*     .. Local Scalars ..
      INTEGER          GENID, I, INFO, LSEED, LSTATE, SUBID
*     .. Local Arrays ..
      DOUBLE PRECISION IMA(N), REA(N)
      INTEGER          SEED(MSEED), STATE(MSTATE)
*     .. External Subroutines ..
      EXTERNAL         DRANDINITIALIZE, DRANDUNIFORM
*     .. Intrinsic Functions ..
      INTRINSIC        DCMPLX
*     .. 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 DRANDINITIALIZE(GENID,SUBID,SEED,LSEED,STATE,LSTATE,INFO)
*
*     Generate real and imaginary parts from a uniform U(ALIM,BLIM)
*     distribution
*
      CALL DRANDUNIFORM(N,ALIM,BLIM,STATE,REA,INFO)
      CALL DRANDUNIFORM(N,ALIM,BLIM,STATE,IMA,INFO)
*
      DO 20 I = 1, N
         A(I) = DCMPLX(REA(I),IMA(I))
   20 CONTINUE
*
      RETURN
      END
