C $Header: /u/gcmpack/MITgcm/eesupp/src/gsum.F,v 1.9 2012/09/06 15:25:01 jmc Exp $ C $Name: $ #include "CPP_EEOPTIONS.h" CBOP C !ROUTINE: GSUM_R8_INIT C !INTERFACE: SUBROUTINE GSUM_R8_INIT( myThid ) IMPLICIT NONE C !DESCRIPTION: C *==========================================================* C | SUBROUTINE GSUM\_R8\_INIT C | o Setup data structures for global sum. C *==========================================================* C | Fast true shared memory form for global sum operation. C *==========================================================* C !USES: #include "SIZE.h" #include "EEPARAMS.h" #include "EESUPPORT.h" C GSR8_value :: Global data for accumulating sum elements. C GSR8_level :: Cyclic buffer index into global data sum elements. COMMON /GS_R8_BUFFER_R/ & GSR8_value Real*8 GSR8_value(lShare8,MAX_NO_THREADS) #define _NOT_SET_ 1.23456D12 COMMON /GS_R8_BUFFER_I/ & GSR8_level INTEGER GSR8_level C !INPUT PARAMETERS: C myThid :: Thread number of this instance. INTEGER myThid C !LOCAL VARIABLES: C I :: Loop counter. INTEGER I CEOP GSR8_level = 1 DO I = 1, lShare8 GSR8_value(I,myThid) = _NOT_SET_ ENDDO RETURN END
CBOP C !ROUTINE: GSUM_R8 C !INTERFACE: SUBROUTINE GSUM_R8( myPhi, answer, myThid ) IMPLICIT NONE C !DESCRIPTION: C *==========================================================* C | SUBROUTINE GSUM\_R8 C | o Perform global sum. C *==========================================================* C | Fast true shared memory form for global sum operation. C *==========================================================* C !USES: #include "SIZE.h" #include "EEPARAMS.h" #include "EESUPPORT.h" C GSR8_value :: Global data for accumulating sum elements. C GSR8_level :: Cyclic buffer index into global data sum elements. COMMON /GS_R8_BUFFER_R/ & GSR8_value Real*8 GSR8_value(lShare8,MAX_NO_THREADS) #define _NOT_SET_ 1.23456D12 COMMON /GS_R8_BUFFER_I/ & GSR8_level INTEGER GSR8_level C !INPUT/OUTPUT PARAMETERS: C myPhi :: This threads contribution C answer :: Result of sum over all threads C myThid :: This threads id number Real*8 myPhi Real*8 answer INTEGER myThid #ifdef ALLOW_USE_MPI Real*8 tmp, sumPhi INTEGER mpiRc #endif C C !LOCAL VARIABLES: C nDone :: Counter for number of threads completed. C I :: Loop counter. C curLev :: Cyclic global sum buffer levels. C prevLev INTEGER nDone INTEGER I INTEGER curLev, prevLev CEOP C answer = 1. C CALL BAR2(myThid) C CALL BAR2(myThid) C CALL BAR2(myThid) C RETURN C IF ( myThid .NE. 1 ) THEN curLev = GSR8_level GSR8_value(curLev,myThid) = myPhi 10 CONTINUE IF ( GSR8_value(curLev,1) .NE. _NOT_SET_ ) GOTO 11 CALL FOOL_THE_COMPILER_R8( GSR8_value(1,1) ) GOTO 10 11 CONTINUE GSR8_value(curLev,myThid) = _NOT_SET_ answer = GSR8_value(curLev,1) ELSE curLev = GSR8_level prevLev = curLev+1 IF ( prevLev .GT. 2 ) prevLev = 1 12 CONTINUE CALL FOOL_THE_COMPILER_R8( GSR8_value(1,1) ) nDone = 1 DO I = 2, nThreads IF ( GSR8_value(curLev,I) .NE. _NOT_SET_ ) nDone = nDone+1 ENDDO IF ( nDone .LT. nThreads ) GOTO 12 GSR8_level = prevLev CALL FOOL_THE_COMPILER_R8( GSR8_value(1,1) ) GSR8_value(prevLev,1) = _NOT_SET_ answer = myPhi DO I = 2,nThreads answer = answer+GSR8_value(curLev,I) ENDDO #ifdef ALLOW_USE_MPI IF ( usingMPI ) THEN tmp = answer CALL MPI_ALLREDUCE(tmp,sumPhi,1,MPI_DOUBLE_PRECISION,MPI_SUM, & MPI_COMM_MODEL,mpiRC) answer = sumPhi ENDIF #endif /* ALLOW_USE_MPI */ GSR8_value(curLev,1) = answer ENDIF RETURN END