Back to home page

MITgcm

 
 

    


Warning, /eesupp/src/exch_rx_recv_get_y.template is written in an unsupported language. File is not indexed.

view on githubraw file Latest commit add29e06 on 2018-01-31 20:35:05 UTC
92f012330e Alis*0001 #include "CPP_EEOPTIONS.h"
4947bd1c5a Jean*0002 #undef EXCH_USE_SPINNING
92f012330e Alis*0003 
4c563c2ee9 Chri*0004 CBOP
                0005 C     !ROUTINE: EXCH_RX_RECV_GET_Y
                0006 
                0007 C     !INTERFACE:
92f012330e Alis*0008       SUBROUTINE EXCH_RX_RECV_GET_Y( array,
                0009      I            myOLw, myOLe, myOLs, myOLn, myNz,
                0010      I            exchWidthX, exchWidthY,
                0011      I            theSimulationMode, theCornerMode, myThid )
                0012       IMPLICIT NONE
                0013 
4c563c2ee9 Chri*0014 C     !DESCRIPTION:
                0015 C     *==========================================================*
4947bd1c5a Jean*0016 C     | SUBROUTINE RECV_GET_Y
                0017 C     | o "Send" or "put" Y edges for RX array.
4c563c2ee9 Chri*0018 C     *==========================================================*
4947bd1c5a Jean*0019 C     | Routine that invokes actual message passing send or
                0020 C     | direct "put" of data to update X faces of an XY[R] array.
4c563c2ee9 Chri*0021 C     *==========================================================*
                0022 
                0023 C     !USES:
92f012330e Alis*0024 C     == Global variables ==
                0025 #include "SIZE.h"
                0026 #include "EEPARAMS.h"
                0027 #include "EESUPPORT.h"
                0028 #include "EXCH.h"
                0029 
4c563c2ee9 Chri*0030 C     !INPUT/OUTPUT PARAMETERS:
92f012330e Alis*0031 C     == Routine arguments ==
4c563c2ee9 Chri*0032 C     array :: Array with edges to exchange.
                0033 C     myOLw :: West, East, North and South overlap region sizes.
92f012330e Alis*0034 C     myOLe
                0035 C     myOLn
                0036 C     myOLs
4c563c2ee9 Chri*0037 C     exchWidthX :: Width of data region exchanged.
92f012330e Alis*0038 C     exchWidthY
4c563c2ee9 Chri*0039 C     theSimulationMode :: Forward or reverse mode exchange ( provides
                0040 C                          support for adjoint integration of code. )
                0041 C     theCornerMode     :: Flag indicating whether corner updates are
                0042 C                          needed.
                0043 C     myThid            :: Thread number of this instance of S/R EXCH...
                0044 C     eBl               :: Edge buffer level
92f012330e Alis*0045       INTEGER myOLw
                0046       INTEGER myOLe
                0047       INTEGER myOLs
                0048       INTEGER myOLn
                0049       INTEGER myNz
                0050       _RX array(1-myOLw:sNx+myOLe,
                0051      &          1-myOLs:sNy+myOLn,
                0052      &          myNZ, nSx, nSy)
                0053       INTEGER exchWidthX
                0054       INTEGER exchWidthY
                0055       INTEGER theSimulationMode
                0056       INTEGER theCornerMode
                0057       INTEGER myThid
                0058 
4c563c2ee9 Chri*0059 C     !LOCAL VARIABLES:
92f012330e Alis*0060 C     == Local variables ==
4947bd1c5a Jean*0061 C     i, j, k, iMin, iMax, iB    :: Loop counters and extents
92f012330e Alis*0062 C     bi, bj
4c563c2ee9 Chri*0063 C     biS, bjS                   :: South tile indices
                0064 C     biN, bjN                   :: North tile indices
                0065 C     eBl                        :: Current exchange buffer level
                0066 C     theProc, theTag, theType,  :: Variables used in message building
92f012330e Alis*0067 C     theSize
4c563c2ee9 Chri*0068 C     southCommMode              :: Working variables holding type
                0069 C     northCommMode                 of communication a particular
                0070 C                                   tile face uses.
                0071 C     spinCount                  :: Exchange statistics counter
                0072 C     mpiStatus                  :: MPI error code
4947bd1c5a Jean*0073       INTEGER i, j, k, iMin, iMax, jMin, jMax, iB, iB0
92f012330e Alis*0074       INTEGER bi, bj, biS, bjS, biN, bjN
                0075       INTEGER eBl
                0076       INTEGER southCommMode
                0077       INTEGER northCommMode
4947bd1c5a Jean*0078 #ifdef EXCH_USE_SPINNING
92f012330e Alis*0079       INTEGER spinCount
4947bd1c5a Jean*0080 #endif
92f012330e Alis*0081 #ifdef ALLOW_USE_MPI
19765ceae9 Jean*0082       INTEGER theProc, theTag, theType, theSize
92f012330e Alis*0083       INTEGER mpiStatus(MPI_STATUS_SIZE,4), mpiRc
19765ceae9 Jean*0084 # ifdef ALLOW_AUTODIFF_OPENAD_AMPI
                0085       INTEGER pReqI
                0086 # endif
                0087 #endif /* ALLOW_USE_MPI */
4c563c2ee9 Chri*0088 CEOP
92f012330e Alis*0089 
4947bd1c5a Jean*0090 C--   Under a "put" scenario we
92f012330e Alis*0091 C--     i. set completetion signal for buffer we put into.
4947bd1c5a Jean*0092 C--    ii. wait for completetion signal indicating data has been put in
92f012330e Alis*0093 C--        our buffer.
                0094 C--   Under a messaging mode we "receive" the message.
                0095 C--   Under a "get" scenario we
                0096 C--     i. Check that the data is ready.
                0097 C--    ii. Read the data.
                0098 C--   iii. Set data read flag + memory sync.
                0099 
                0100 #ifdef ALLOW_USE_MPI
4947bd1c5a Jean*0101       IF ( usingMPI ) THEN
19765ceae9 Jean*0102 
4947bd1c5a Jean*0103 C--   Receive buffer data: Only Master Thread do proc communication
                0104       _BEGIN_MASTER(myThid)
                0105 
                0106       DO bj=1,nSy
                0107        DO bi=1,nSx
                0108         eBl = exchangeBufLevel(1,bi,bj)
                0109         southCommMode = _tileCommModeS(bi,bj)
                0110         northCommMode = _tileCommModeN(bi,bj)
                0111         biN = _tileBiN(bi,bj)
                0112         bjN = _tileBjN(bi,bj)
                0113         biS = _tileBiS(bi,bj)
                0114         bjS = _tileBjS(bi,bj)
                0115         theType = _MPI_TYPE_RX
                0116         theSize = sNx*exchWidthY*myNz
                0117         IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
                0118           theSize = (sNx+2*exchWidthX)*exchWidthY*myNz
                0119         ENDIF
                0120 
                0121         IF ( southCommMode .EQ. COMM_MSG ) THEN
92f012330e Alis*0122          theProc = tilePidS(bi,bj)
                0123          theTag  = _tileTagRecvS(bi,bj)
0eef504f9b Jean*0124 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
4947bd1c5a Jean*0125          CALL MPI_Recv( southRecvBuf_RX(1,eBl,bi,bj), theSize,
                0126      &                  theType, theProc, theTag, MPI_COMM_MODEL,
92f012330e Alis*0127      &                  mpiStatus, mpiRc )
4947bd1c5a Jean*0128 # else
83996e0652 Jean*0129          pReqI=exchNReqsY(1,bi,bj)+1
4947bd1c5a Jean*0130          CALL ampi_recv_RX(
                0131      &        southRecvBuf_RX(1,eBl,bi,bj) ,
                0132      &        theSize ,
                0133      &        theType ,
                0134      &        theProc ,
                0135      &        theTag ,
                0136      &        MPI_COMM_MODEL ,
                0137      &        exchReqIdY(pReqI,1,bi,bj),
                0138      &        exchNReqsY(1,bi,bj),
                0139      &        mpiStatus ,
                0140      &        mpiRc )
0eef504f9b Jean*0141 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
4947bd1c5a Jean*0142          southRecvAck(eBl,bi,bj) = 1
92f012330e Alis*0143         ENDIF
4947bd1c5a Jean*0144 
92f012330e Alis*0145         IF ( northCommMode .EQ. COMM_MSG ) THEN
                0146          theProc = tilePidN(bi,bj)
                0147          theTag  = _tileTagRecvN(bi,bj)
0eef504f9b Jean*0148 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
4947bd1c5a Jean*0149          CALL MPI_Recv( northRecvBuf_RX(1,eBl,bi,bj), theSize,
                0150      &                  theType, theProc, theTag, MPI_COMM_MODEL,
92f012330e Alis*0151      &                  mpiStatus, mpiRc )
033dc5d283 Jean*0152 # else
4d40368441 Jean*0153          pReqI=exchNReqsY(1,bi,bj)+1
4947bd1c5a Jean*0154          CALL ampi_recv_RX(
                0155      &        northRecvBuf_RX(1,eBl,bi,bj) ,
                0156      &        theSize ,
                0157      &        theType ,
                0158      &        theProc ,
                0159      &        theTag ,
                0160      &        MPI_COMM_MODEL ,
                0161      &        exchReqIdY(pReqI,1,bi,bj),
                0162      &        exchNReqsY(1,bi,bj),
                0163      &        mpiStatus ,
                0164      &        mpiRc )
0eef504f9b Jean*0165 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
4947bd1c5a Jean*0166          northRecvAck(eBl,bi,bj) = 1
92f012330e Alis*0167         ENDIF
                0168        ENDDO
                0169       ENDDO
                0170 
4947bd1c5a Jean*0171 C--   Processes wait for buffers I am going to read to be ready.
                0172       IF ( .NOT.exchUsesBarrier  ) THEN
                0173        DO bj=1,nSy
                0174         DO bi=1,nSx
                0175          IF ( exchNReqsY(1,bi,bj) .GT. 0 ) THEN
                0176 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
                0177           CALL MPI_Waitall( exchNReqsY(1,bi,bj), exchReqIdY(1,1,bi,bj),
                0178      &                      mpiStatus, mpiRC )
                0179 # else
                0180           CALL ampi_waitall(
                0181      &         exchNReqsY(1,bi,bj),
                0182      &         exchReqIdY(1,1,bi,bj),
                0183      &         mpiStatus,
                0184      &         mpiRC )
                0185 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
                0186          ENDIF
                0187 C        Clear outstanding requests counter
                0188          exchNReqsY(1,bi,bj) = 0
                0189         ENDDO
                0190        ENDDO
                0191       ENDIF
                0192 
                0193       _END_MASTER(myThid)
                0194 C--   need to sync threads after master has received data ;
                0195 C     (done after mpi waitall in case waitall is really needed)
                0196       _BARRIER
                0197 
                0198       ENDIF
                0199 #endif /* ALLOW_USE_MPI */
                0200 
                0201 C--   Threads wait for buffers I am going to read to be ready.
                0202 C     note: added BARRIER in exch_send_put S/R and here above (message mode)
                0203 C           so that we no longer needs this (undef EXCH_USE_SPINNING)
                0204 #ifdef EXCH_USE_SPINNING
92f012330e Alis*0205       IF ( exchUsesBarrier  ) THEN
                0206 C      o On some machines ( T90 ) use system barrier rather than spinning.
                0207        CALL BARRIER( myThid )
                0208       ELSE
                0209 C      o Spin waiting for completetion flag. This avoids a global-lock
                0210 C        i.e. we only lock waiting for data that we need.
                0211        DO bj=myByLo(myThid),myByHi(myThid)
                0212         DO bi=myBxLo(myThid),myBxHi(myThid)
4947bd1c5a Jean*0213 
                0214          spinCount = 0
                0215          eBl = exchangeBufLevel(1,bi,bj)
92f012330e Alis*0216          southCommMode = _tileCommModeS(bi,bj)
                0217          northCommMode = _tileCommModeN(bi,bj)
0eef504f9b Jean*0218 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
92f012330e Alis*0219    10    CONTINUE
e78c04eec8 Jean*0220           CALL FOOL_THE_COMPILER( spinCount )
92f012330e Alis*0221           spinCount = spinCount+1
                0222 C         IF ( myThid .EQ. 1 .AND. spinCount .GT. _EXCH_SPIN_LIMIT ) THEN
                0223 C          STOP ' S/R EXCH_RECV_GET_Y: spinCount .GT. _EXCH_SPIN_LIMIT'
                0224 C         ENDIF
061bed00a3 Jean*0225           IF ( southRecvAck(eBl,bi,bj) .EQ. 0 ) GOTO 10
                0226           IF ( northRecvAck(eBl,bi,bj) .EQ. 0 ) GOTO 10
033dc5d283 Jean*0227 # else
4947bd1c5a Jean*0228          DO WHILE ((southRecvAck(eBl,bi,bj) .EQ. 0
                0229      &             .OR.
                0230      &              northRecvAck(eBl,bi,bj) .EQ. 0 ))
033dc5d283 Jean*0231           CALL FOOL_THE_COMPILER( spinCount )
                0232           spinCount = spinCount+1
4947bd1c5a Jean*0233          ENDDO
0eef504f9b Jean*0234 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
92f012330e Alis*0235 C        Clear requests
061bed00a3 Jean*0236          southRecvAck(eBl,bi,bj) = 0
                0237          northRecvAck(eBl,bi,bj) = 0
92f012330e Alis*0238 C        Update statistics
                0239          IF ( exchCollectStatistics ) THEN
                0240           exchRecvYExchCount(1,bi,bj) = exchRecvYExchCount(1,bi,bj)+1
4947bd1c5a Jean*0241           exchRecvYSpinCount(1,bi,bj) =
92f012330e Alis*0242      &    exchRecvYSpinCount(1,bi,bj)+spinCount
4947bd1c5a Jean*0243           exchRecvYSpinMax(1,bi,bj) =
92f012330e Alis*0244      &    MAX(exchRecvYSpinMax(1,bi,bj),spinCount)
4947bd1c5a Jean*0245           exchRecvYSpinMin(1,bi,bj) =
92f012330e Alis*0246      &    MIN(exchRecvYSpinMin(1,bi,bj),spinCount)
                0247          ENDIF
                0248 
                0249         ENDDO
                0250        ENDDO
                0251       ENDIF
4947bd1c5a Jean*0252 #endif /* EXCH_USE_SPINNING */
                0253 
                0254 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
92f012330e Alis*0255 
                0256 C--   Read from the buffers
                0257       DO bj=myByLo(myThid),myByHi(myThid)
                0258        DO bi=myBxLo(myThid),myBxHi(myThid)
                0259 
4947bd1c5a Jean*0260         eBl = exchangeBufLevel(1,bi,bj)
                0261         biN = _tileBiN(bi,bj)
                0262         bjN = _tileBjN(bi,bj)
                0263         biS = _tileBiS(bi,bj)
                0264         bjS = _tileBjS(bi,bj)
92f012330e Alis*0265         southCommMode = _tileCommModeS(bi,bj)
                0266         northCommMode = _tileCommModeN(bi,bj)
                0267         IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
                0268          iMin =   1-exchWidthX
                0269          iMax = sNx+exchWidthX
                0270         ELSE
                0271          iMin = 1
                0272          iMax = sNx
                0273         ENDIF
                0274         IF     ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
                0275          jMin = sNy+1
                0276          jMax = sNy+exchWidthY
                0277          iB0  = 0
4947bd1c5a Jean*0278          IF (     northCommMode .EQ. COMM_PUT
                0279      &       .OR. northCommMode .EQ. COMM_MSG  ) THEN
92f012330e Alis*0280           iB  = 0
4947bd1c5a Jean*0281           DO k=1,myNz
                0282            DO j=jMin,jMax
                0283             DO i=iMin,iMax
92f012330e Alis*0284              iB = iB + 1
4947bd1c5a Jean*0285              array(i,j,k,bi,bj) = northRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0286             ENDDO
                0287            ENDDO
                0288           ENDDO
                0289          ELSEIF ( northCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0290           DO k=1,myNz
92f012330e Alis*0291            iB = iB0
4947bd1c5a Jean*0292            DO j=jMin,jMax
92f012330e Alis*0293             iB = iB+1
4947bd1c5a Jean*0294             DO i=iMin,iMax
                0295              array(i,j,k,bi,bj) = array(i,iB,k,biN,bjN)
92f012330e Alis*0296             ENDDO
                0297            ENDDO
                0298           ENDDO
                0299          ENDIF
                0300         ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
                0301          jMin = sNy-exchWidthY+1
                0302          jMax = sNy
                0303          iB0  = 1-exchWidthY-1
4947bd1c5a Jean*0304          IF (     northCommMode .EQ. COMM_PUT
                0305      &       .OR. northCommMode .EQ. COMM_MSG  ) THEN
92f012330e Alis*0306           iB  = 0
4947bd1c5a Jean*0307           DO k=1,myNz
                0308            DO j=jMin,jMax
                0309             DO i=iMin,iMax
92f012330e Alis*0310              iB = iB + 1
4947bd1c5a Jean*0311              array(i,j,k,bi,bj) =
                0312      &       array(i,j,k,bi,bj) + northRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0313             ENDDO
                0314            ENDDO
                0315           ENDDO
                0316          ELSEIF ( northCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0317           DO k=1,myNz
92f012330e Alis*0318            iB = iB0
4947bd1c5a Jean*0319            DO j=jMin,jMax
92f012330e Alis*0320             iB = iB+1
4947bd1c5a Jean*0321             DO i=iMin,iMax
                0322              array(i,j,k,bi,bj) =
                0323      &       array(i,j,k,bi,bj) + array(i,iB,k,biN,bjN)
                0324              array(i,iB,k,biN,bjN) = 0.0
92f012330e Alis*0325             ENDDO
                0326            ENDDO
                0327           ENDDO
                0328          ENDIF
                0329         ENDIF
                0330 
                0331         IF     ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
                0332          jMin = 1-exchWidthY
                0333          jMax = 0
                0334          iB0  = sNy-exchWidthY
4947bd1c5a Jean*0335          IF (     southCommMode .EQ. COMM_PUT
                0336      &       .OR. southCommMode .EQ. COMM_MSG ) THEN
92f012330e Alis*0337           iB  = 0
4947bd1c5a Jean*0338           DO k=1,myNz
                0339            DO j=jMin,jMax
                0340             DO i=iMin,iMax
92f012330e Alis*0341              iB = iB + 1
4947bd1c5a Jean*0342              array(i,j,k,bi,bj) = southRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0343             ENDDO
                0344            ENDDO
                0345           ENDDO
                0346          ELSEIF ( southCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0347           DO k=1,myNz
92f012330e Alis*0348            iB = iB0
4947bd1c5a Jean*0349            DO j=jMin,jMax
92f012330e Alis*0350             iB = iB+1
4947bd1c5a Jean*0351             DO i=iMin,iMax
                0352              array(i,j,k,bi,bj) = array(i,iB,k,biS,bjS)
92f012330e Alis*0353             ENDDO
                0354            ENDDO
                0355           ENDDO
                0356          ENDIF
                0357         ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
                0358          jMin = 1
                0359          jMax = 1+exchWidthY-1
                0360          iB0  = sNy
4947bd1c5a Jean*0361          IF (     southCommMode .EQ. COMM_PUT
                0362      &       .OR. southCommMode .EQ. COMM_MSG ) THEN
92f012330e Alis*0363           iB  = 0
4947bd1c5a Jean*0364           DO k=1,myNz
                0365            DO j=jMin,jMax
                0366             DO i=iMin,iMax
92f012330e Alis*0367              iB = iB + 1
4947bd1c5a Jean*0368              array(i,j,k,bi,bj) =
                0369      &       array(i,j,k,bi,bj) + southRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0370             ENDDO
                0371            ENDDO
                0372           ENDDO
                0373          ELSEIF ( southCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0374           DO k=1,myNz
92f012330e Alis*0375            iB = iB0
4947bd1c5a Jean*0376            DO j=jMin,jMax
92f012330e Alis*0377             iB = iB+1
4947bd1c5a Jean*0378             DO i=iMin,iMax
                0379              array(i,j,k,bi,bj) =
                0380      &       array(i,j,k,bi,bj) + array(i,iB,k,biS,bjS)
                0381              array(i,iB,k,biS,bjS) = 0.0
92f012330e Alis*0382             ENDDO
                0383            ENDDO
                0384           ENDDO
                0385          ENDIF
                0386         ENDIF
4947bd1c5a Jean*0387 
92f012330e Alis*0388        ENDDO
                0389       ENDDO
                0390 
                0391       RETURN
                0392       END