Back to home page

MITgcm

 
 

    


Warning, /eesupp/src/exch1_rx_ad.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
b56f9aa5e6 Jean*0001 #include "CPP_EEOPTIONS.h"
                0002 
                0003 CBOP
                0004 
                0005 C     !ROUTINE: EXCH1_RX_AD
                0006 
                0007 C     !INTERFACE:
                0008 #ifdef AUTODIFF_TAMC_COMPATIBILITY
                0009       SUBROUTINE EXCH1_RX_AD(
                0010      I                 myOLw, myOLe, myOLs, myOLn, myNz,
                0011      I                 exchWidthX, exchWidthY,
                0012      I                 cornerMode, myThid,
                0013      U                 array )
                0014 #else
                0015       SUBROUTINE EXCH1_RX_AD(
                0016      U                 array,
                0017      I                 myOLw, myOLe, myOLs, myOLn, myNz,
                0018      I                 exchWidthX, exchWidthY,
                0019      I                 cornerMode, myThid )
                0020 #endif
                0021 
                0022 C     !DESCRIPTION:
                0023 C     *==========================================================*
                0024 C     | SUBROUTINE EXCH1_RX_AD
                0025 C     | o Control reverse-mode edge exchanges for RX array.
                0026 C     *==========================================================*
                0027 C     | Controlling routine for exchange of XY edges of an array
                0028 C     | distributed in X and Y. The routine interfaces to
                0029 C     | communication routines that can use messages passing
                0030 C     | exchanges, put type exchanges or get type exchanges.
                0031 C     |  This allows anything from MPI to raw memory channel to
                0032 C     | memmap segments to be used as a inter-process and/or
                0033 C     | inter-thread communiation and synchronisation
                0034 C     | mechanism.
                0035 C     | Notes --
                0036 C     | 1. Some low-level mechanisms such as raw memory-channel
                0037 C     | or SGI/CRAY shmem put do not have direct Fortran bindings
                0038 C     | and are invoked through C stub routines.
                0039 C     | 2. Although this routine is fairly general but it does
                0040 C     | require nSx and nSy are the same for all innvocations.
                0041 C     | There are many common data structures ( myByLo,
                0042 C     | westCommunicationMode, mpiIdW etc... ) tied in with
                0043 C     | (nSx,nSy). To support arbitray nSx and nSy would require
                0044 C     | general forms of these.
                0045 C     | 3. RX arrays are used to generate code for both _RL and
                0046 C     | _RS forms.
                0047 C     *==========================================================*
                0048 
                0049 C     !USES:
                0050       IMPLICIT NONE
                0051 
                0052 C     == Global data ==
                0053 #include "SIZE.h"
                0054 #include "EEPARAMS.h"
                0055 #include "EXCH.h"
                0056 
                0057 C     !INPUT/OUTPUT PARAMETERS:
                0058 C     == Routine arguments ==
                0059 C     array       :: Array with edges to exchange.
                0060 C     myOLw,myOLe :: West  and East  overlap region sizes.
                0061 C     myOLs,myOLn :: South and North overlap region sizes.
                0062 C     exchWidthX  :: Width of data region exchanged in X.
                0063 C     exchWidthY  :: Width of data region exchanged in Y.
                0064 C                    Note --
                0065 C                    1. In theory one could have a send width and
                0066 C                    a receive width for each face of each tile. The only
                0067 C                    restriction would be that the send width of one
                0068 C                    face should equal the receive width of the sent to
                0069 C                    tile face. Dont know if this would be useful. I
                0070 C                    have left it out for now as it requires additional
                0071 C                    bookeeping.
                0072 C     cornerMode  :: Flag indicating whether corner updates are needed.
                0073 C     myThid      :: my Thread Id number
                0074 
                0075       INTEGER myOLw, myOLe, myOLs, myOLn, myNz
                0076       _RX     array( 1-myOLw:sNx+myOLe,
                0077      &               1-myOLs:sNy+myOLn,
                0078      &               myNz, nSx, nSy )
                0079       INTEGER exchWidthX
                0080       INTEGER exchWidthY
                0081       INTEGER cornerMode
                0082       INTEGER myThid
                0083 
                0084 C     !LOCAL VARIABLES:
                0085 C     == Local variables ==
                0086 C     theSimulationMode :: Holds working copy of simulation mode
                0087 C     theCornerMode     :: Holds working copy of corner mode
                0088 C     i,j,k,bi,bj       :: Loop counters
                0089       INTEGER theSimulationMode
                0090       INTEGER theCornerMode
                0091       INTEGER i,j,k,bi,bj
                0092 CEOP
                0093 
                0094       theSimulationMode = REVERSE_SIMULATION
                0095       theCornerMode     = cornerMode
                0096 
                0097 C--   Error checks
                0098       IF ( exchWidthX .GT. myOLw   )
                0099      &  STOP ' S/R EXCH1_RX_AD: exchWidthX .GT. myOLw'
                0100       IF ( exchWidthX .GT. myOLe   )
                0101      &  STOP ' S/R EXCH1_RX_AD: exchWidthX .GT. myOLe'
                0102       IF ( exchWidthY .GT. myOLs   )
                0103      &  STOP ' S/R EXCH1_RX_AD: exchWidthY .GT. myOLs'
                0104       IF ( exchWidthY .GT. myOLn   )
                0105      &  STOP ' S/R EXCH1_RX_AD: exchWidthY .GT. myOLn'
                0106       IF ( myOLw      .GT. MAX_OLX_EXCH )
                0107      &  STOP ' S/R EXCH1_RX_AD: myOLw .GT. MAX_OLX_EXCH'
                0108       IF ( myOLe      .GT. MAX_OLX_EXCH )
                0109      &  STOP ' S/R EXCH1_RX_AD: myOLe .GT. MAX_OLX_EXCH'
f603e2d124 Jean*0110       IF ( myOLn      .GT. MAX_OLY_EXCH )
b56f9aa5e6 Jean*0111      &  STOP ' S/R EXCH1_RX_AD: myOLn .GT. MAX_OLY_EXCH'
                0112       IF ( myOLs      .GT. MAX_OLY_EXCH )
                0113      &  STOP ' S/R EXCH1_RX_AD: myOLs .GT. MAX_OLY_EXCH'
                0114       IF ( myNz       .GT. MAX_NR_EXCH  )
                0115      &  STOP ' S/R EXCH1_RX_AD: myNz  .GT. MAX_NR_EXCH '
                0116       IF (       theCornerMode .NE. EXCH_IGNORE_CORNERS
                0117      &     .AND. theCornerMode .NE. EXCH_UPDATE_CORNERS
                0118      &   ) STOP ' S/R EXCH1_RX_AD: Unrecognised cornerMode '
                0119 
                0120 C--   Cycle edge buffer level
                0121       CALL EXCH_CYCLE_EBL( myThid )
                0122 
                0123       IF ( theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
                0124 
                0125        IF ( Nx .EQ. 1 ) THEN
                0126 C      Special case for zonal average model i.e. case where Nx == 1
                0127 C      In this case a reverse mode exchange simply add values from all i <> 1
                0128 C      to i=1 element and reset to zero.
                0129          DO bj=myByLo(myThid),myByHi(myThid)
                0130           DO bi=myBxLo(myThid),myBxHi(myThid)
                0131            DO k = 1,myNz
                0132             DO j = 1-myOLs,sNy+myOLn
                0133              DO i = 1-myOLw,0
                0134               array(1,j,k,bi,bj) = array(1,j,k,bi,bj)
                0135      &                           + array(i,j,k,bi,bj)
                0136               array(i,j,k,bi,bj) = 0.
                0137              ENDDO
                0138              DO i = sNx+1,sNx+myOLe
                0139               array(1,j,k,bi,bj) = array(1,j,k,bi,bj)
                0140      &                           + array(i,j,k,bi,bj)
                0141               array(i,j,k,bi,bj) = 0.
                0142              ENDDO
                0143             ENDDO
                0144            ENDDO
                0145           ENDDO
                0146          ENDDO
                0147        ENDIF
                0148 
                0149        IF ( Ny .EQ. 1 ) THEN
                0150 C      Special case for X-slice domain i.e. case where Ny == 1
                0151 C      In this case a reverse mode exchange simply add values from all j <> 1
                0152 C      to j=1 element and reset to zero.
                0153          DO bj=myByLo(myThid),myByHi(myThid)
                0154           DO bi=myBxLo(myThid),myBxHi(myThid)
                0155            DO k = 1,myNz
                0156             DO j = 1-myOLs,0
                0157              DO i = 1-myOLw,sNx+myOLe
                0158               array(i,1,k,bi,bj) = array(i,1,k,bi,bj)
                0159      &                           + array(i,j,k,bi,bj)
                0160               array(i,j,k,bi,bj) = 0.
                0161              ENDDO
                0162             ENDDO
                0163             DO j = sNy+1,sNy+myOLn
                0164              DO i = 1-myOLw,sNx+myOLe
                0165               array(i,1,k,bi,bj) = array(i,1,k,bi,bj)
                0166      &                           + array(i,j,k,bi,bj)
                0167               array(i,j,k,bi,bj) = 0.
                0168              ENDDO
                0169             ENDDO
                0170            ENDDO
                0171           ENDDO
                0172          ENDDO
                0173        ENDIF
                0174 
                0175 C--   end of special cases of forward exch
                0176       ENDIF
                0177 
                0178       IF ( theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
                0179 C--     "Put" east and west edges.
                0180         CALL EXCH_RX_SEND_PUT_X( array,
                0181      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0182      I              exchWidthX, exchWidthY,
                0183      I              theSimulationMode, theCornerMode, myThid )
                0184 C--     If corners are important then sync and update east and west edges
                0185 C--     before doing north and south exchanges.
                0186         IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
                0187          CALL EXCH_RX_RECV_GET_X( array,
                0188      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0189      I              exchWidthX, exchWidthY,
                0190      I              theSimulationMode, theCornerMode, myThid )
                0191         ENDIF
                0192 C       "Put" north and south edges.
                0193         CALL EXCH_RX_SEND_PUT_Y( array,
                0194      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0195      I              exchWidthX, exchWidthY,
                0196      I              theSimulationMode, theCornerMode, myThid )
                0197 C--     Sync and update north, south (and east, west if corner updating
                0198 C--     not active).
                0199         IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
                0200          CALL EXCH_RX_RECV_GET_X( array,
                0201      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0202      I              exchWidthX, exchWidthY,
                0203      I              theSimulationMode, theCornerMode, myThid )
                0204         ENDIF
                0205         CALL EXCH_RX_RECV_GET_Y( array,
                0206      I             myOLw, myOLe, myOLs, myOLn, myNz,
                0207      I             exchWidthX, exchWidthY,
                0208      I             theSimulationMode, theCornerMode, myThid )
                0209       ENDIF
                0210 
                0211       IF ( theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
                0212 C       "Put" north and south edges.
                0213         CALL EXCH_RX_SEND_PUT_Y( array,
                0214      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0215      I              exchWidthX, exchWidthY,
                0216      I              theSimulationMode, theCornerMode, myThid )
                0217 C--     If corners are important then sync and update east and west edges
                0218 C--     before doing north and south exchanges.
                0219         IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
                0220          CALL EXCH_RX_RECV_GET_Y( array,
                0221      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0222      I              exchWidthX, exchWidthY,
                0223      I              theSimulationMode, theCornerMode, myThid )
                0224         ENDIF
                0225 C--     "Put" east and west edges.
                0226         CALL EXCH_RX_SEND_PUT_X( array,
                0227      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0228      I              exchWidthX, exchWidthY,
                0229      I              theSimulationMode, theCornerMode, myThid )
                0230 C--     Sync and update east, west (and north, south if corner updating
                0231 C--     not active).
                0232         IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
                0233          CALL EXCH_RX_RECV_GET_Y( array,
                0234      I              myOLw, myOLe, myOLs, myOLn, myNz,
                0235      I              exchWidthX, exchWidthY,
                0236      I              theSimulationMode, theCornerMode, myThid )
                0237         ENDIF
                0238         CALL EXCH_RX_RECV_GET_X( array,
                0239      I             myOLw, myOLe, myOLs, myOLn, myNz,
                0240      I             exchWidthX, exchWidthY,
                0241      I             theSimulationMode, theCornerMode, myThid )
                0242       ENDIF
                0243 
                0244       IF ( theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
                0245 
                0246        IF ( Nx .EQ. 1 ) THEN
                0247 C      Special case for zonal average model i.e. case where Nx == 1
                0248 C      In this case a forward mode exchange simply sets array to
                0249 C      the i=1 value for all i.
                0250          DO bj=myByLo(myThid),myByHi(myThid)
                0251           DO bi=myBxLo(myThid),myBxHi(myThid)
                0252            DO k = 1,myNz
                0253             DO j = 1-myOLs,sNy+myOLn
                0254              DO i = 1-myOLw,sNx+myOLe
                0255               array(i,j,k,bi,bj) = array(1,j,k,bi,bj)
                0256              ENDDO
                0257             ENDDO
                0258            ENDDO
                0259           ENDDO
                0260          ENDDO
                0261        ENDIF
                0262 
                0263        IF ( Ny .EQ. 1 ) THEN
                0264 C      Special case for X-slice domain i.e. case where Ny == 1
                0265 C      In this case a forward mode exchange simply sets array to
                0266 C      the j=1 value for all j.
                0267          DO bj=myByLo(myThid),myByHi(myThid)
                0268           DO bi=myBxLo(myThid),myBxHi(myThid)
                0269            DO k = 1,myNz
                0270             DO j = 1-myOLs,sNy+myOLn
                0271              DO i = 1-myOLw,sNx+myOLe
                0272               array(i,j,k,bi,bj) = array(i,1,k,bi,bj)
                0273              ENDDO
                0274             ENDDO
                0275            ENDDO
                0276           ENDDO
                0277          ENDDO
                0278        ENDIF
                0279 
                0280 C--    end of special cases of forward exch
                0281       ENDIF
                0282 
                0283       RETURN
                0284       END