
C*******************************************************************
C          
C         MIMD(EXPRESS) Wolff Cluster Algorithm        
C          - Single Ant
C
C         Sung-Hoon Ko,  Dec 1993
C              
C ******************************************************************

        PROGRAM  EXPRESS_WolffSpin

        INCLUDE  "exp_wolff.h"
        INTEGER  seed, start, i, j
        INTEGER  d1, d2, d3, byte, type
        REAL*8     time, tstart, tstop, temp
        REAL*8     max_time, min_time, avg_time
        REAL*8     total_sweeps
        REAL*8     elapsed_time, persite_time, scale_time    
        INTEGER  MAX_OP,MIN_OP,AVG_OP,NITEMS,LONG_TYPE,FLOAT_TYPE
        PARAMETER ( AVG_OP     = 1 )
        PARAMETER ( MIN_OP     = 3 )
        PARAMETER ( MAX_OP     = 4 )
        PARAMETER ( NITEMS     = 1 )
        PARAMETER ( LONG_TYPE  = 6 )
        PARAMETER ( FLOAT_TYPE = 9 )


C ----  Initialize some Express stuff.
        CALL KXINIT

C ----  Read in the parameters and
C ---   do domain decomposition of the lattice over the nodes.
        CALL  initialize(seed, start)

C ----  Initialize the random number generator.
	CALL rand_init(seed)
 
C ----  Initialize the spins.
	CALL init_spins(start)
 
C ----  Initialize the data.
	CALL init_measure


C ----  Thermalize.
        DO  i=1, therm_sweeps
          CALL wolff_update
        ENDDO


C ----  Do the update, with a measurement every 'sweeps' iterations.
        time = 0
        DO j=1, measurements 
           DO i=1, sweeps
              tstart = KXTIME()
              CALL wolff_update
              tstop  = KXTIME()
              temp = tstop - tstart
              time = time + temp
C ----------- Size
              d1 = KXCMOP(size, NITEMS, LONG_TYPE, ADD_OP)
              sum_size   = sum_size + size
              sum_sizesq = sum_sizesq + (size * size)              
           ENDDO

c           if(procnum .EQ. 0) then
c              call kasync(6)
c              write(6,*) 'measure=',j,'pnum=',procnum,'time=',time,
c     *                   'tstart=',tstart,'tstop',tstop,'temp',temp
c              call ksingl(6)
c              endif

           CALL measure
        ENDDO

        CALL output

C ---- Calculate and Print out time data
        max_time = time/1E6  !time is MICROseconds so change it to seconds
        min_time = time/1E6
        avg_time = time/1E6

        d1=KXCMOP(avg_time, NITEMS, FLOAT_TYPE, AVG_OP)
        d2=KXCMOP(min_time, NITEMS, FLOAT_TYPE, MIN_OP)
        d3=KXCMOP(max_time, NITEMS, FLOAT_TYPE, MAX_OP)

        total_sweeps = (sweeps*measurements)
        elapsed_time = (avg_time / total_sweeps)*1000
        persite_time = elapsed_time / sum_size
        scale_time   = (elapsed_time/sum_size) * (N*N)

        WRITE(6,10) '================================================='
        WRITE(6,*) ' Global Timing Data(Sweeps=', sweeps*measurements,
     &                                  'Width=', width, ')'
        WRITE(6,*) '================================================='
        WRITE(6,20) ' Max   Time =', max_time, 'sec'
        WRITE(6,20) ' Min   Time =', min_time, 'sec'
        WRITE(6,20) ' Aver. Time =', avg_time, 'sec'
        WRITE(6,*) '================================================='
        
        WRITE(6,10) '*************************************************'
        WRITE(6,*) '           Timing Data for One Sweep'
        WRITE(6,*) '*************************************************'
        WRITE(6,20) ' Sweep Time    =', elapsed_time, 'msec'
        WRITE(6,20) ' Time per site =', persite_time, 'msec'
        WRITE(6,20) ' Scale Time    =', scale_time,   'msec'
        WRITE(6,*) '*************************************************'   
 
 10     FORMAT(//,2X,A)
 20     FORMAT(4X,A,F12.4,2X,A) 

        CALL print_cluster(1)

        STOP
        END









