Back to home page

MITgcm

 
 

    


Warning, /pkg/exch2/exch2_rx2_cube_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
40f5e5bc62 Patr*0001 #include "CPP_EEOPTIONS.h"
                0002 
                0003 CBOP
54d78f5995 Jean*0004 C     !ROUTINE: EXCH_RX2_CUBE_AD
40f5e5bc62 Patr*0005 
                0006 C     !INTERFACE:
10972e8712 Jean*0007       SUBROUTINE EXCH2_RX2_CUBE_AD(
54d78f5995 Jean*0008      U            array1, array2,
                0009      I            signOption, fieldCode,
3371b2be58 Jean*0010      I            myOLw, myOLe, myOLs, myOLn, myNz,
40f5e5bc62 Patr*0011      I            exchWidthX, exchWidthY,
8bc539472e Jean*0012      I            cornerMode, myThid )
40f5e5bc62 Patr*0013 
                0014 C     !DESCRIPTION:
54d78f5995 Jean*0015 C     Two components vector field AD-Exchange:
                0016 C     Tile-edge overlap-region of a 2 component vector field is added to
                0017 C     corresponding near-edge interior data point and then zero out.
40f5e5bc62 Patr*0018 
                0019 C     !USES:
54d78f5995 Jean*0020       IMPLICIT NONE
                0021 
40f5e5bc62 Patr*0022 C     == Global data ==
                0023 #include "SIZE.h"
                0024 #include "EEPARAMS.h"
                0025 #include "EESUPPORT.h"
90219e5912 Jean*0026 #include "W2_EXCH2_SIZE.h"
40f5e5bc62 Patr*0027 #include "W2_EXCH2_TOPOLOGY.h"
90219e5912 Jean*0028 #include "W2_EXCH2_BUFFER.h"
40f5e5bc62 Patr*0029 
                0030 C     !INPUT/OUTPUT PARAMETERS:
54d78f5995 Jean*0031 C     array1      :: 1rst component array with edges to exchange.
                0032 C     array2      :: 2nd  component array with edges to exchange.
                0033 C     signOption  :: Flag controlling whether vector is signed.
                0034 C     fieldCode   :: field code (position on staggered grid)
                0035 C     myOLw,myOLe :: West and East overlap region sizes.
3371b2be58 Jean*0036 C     myOLs,myOLn :: South and North overlap region sizes.
54d78f5995 Jean*0037 C     exchWidthX  :: Width of data region exchanged in X.
                0038 C     exchWidthY  :: Width of data region exchanged in Y.
                0039 C     cornerMode  :: halo-corner-region treatment: update/ignore corner region
                0040 C     myThid      :: Thread number of this instance of S/R EXCH...
                0041 
3371b2be58 Jean*0042       INTEGER myOLw, myOLe, myOLs, myOLn, myNz
54d78f5995 Jean*0043       _RX array1(1-myOLw:sNx+myOLe,
                0044      &           1-myOLs:sNy+myOLn,
                0045      &           myNz, nSx, nSy)
                0046       _RX array2(1-myOLw:sNx+myOLe,
                0047      &           1-myOLs:sNy+myOLn,
                0048      &           myNz, nSx, nSy)
                0049       LOGICAL signOption
40f5e5bc62 Patr*0050       CHARACTER*2 fieldCode
                0051       INTEGER exchWidthX
                0052       INTEGER exchWidthY
                0053       INTEGER cornerMode
                0054       INTEGER myThid
                0055 
                0056 C     !LOCAL VARIABLES:
54d78f5995 Jean*0057 C     e2_msgHandles :: Synchronization and coordination data structure used to
                0058 C                   :: coordinate access to e2Bufr1_RX or to regulate message
                0059 C                   :: buffering. In PUT communication sender will increment
                0060 C                   :: handle entry once data is ready in buffer. Receiver will
                0061 C                   :: decrement handle once data is consumed from buffer.
d6ea3164dc Jean*0062 C                   :: For MPI MSG communication MPI_Wait uses handle to check
54d78f5995 Jean*0063 C                   :: Isend has cleared. This is done in routine after receives.
                0064 C     note: a) current implementation does not use e2_msgHandles for communication
                0065 C              between threads: all-threads barriers are used (see CNH note below).
                0066 C              For a 2-threads synchro communication (future version),
                0067 C              e2_msgHandles should be shared (in common block, moved to BUFFER.h)
                0068       INTEGER bi, bj
40f5e5bc62 Patr*0069 C     Variables for working through W2 topology
54d78f5995 Jean*0070       INTEGER e2_msgHandles( 2, W2_maxNeighbours, nSx, nSy )
40f5e5bc62 Patr*0071       INTEGER thisTile, farTile, N, nN, oN
10972e8712 Jean*0072       INTEGER tIlo1, tIhi1, tJlo1, tJhi1, oIs1, oJs1
                0073       INTEGER tIlo2, tIhi2, tJlo2, tJhi2, oIs2, oJs2
                0074       INTEGER tIStride, tJStride
                0075       INTEGER tKlo, tKhi, tKStride
40f5e5bc62 Patr*0076       INTEGER i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi
                0077       INTEGER i2Lo, i2Hi, j2Lo, j2Hi, k2Lo, k2Hi
b475142410 Jean*0078       LOGICAL updateCorners
40f5e5bc62 Patr*0079 
                0080 #ifdef ALLOW_USE_MPI
54d78f5995 Jean*0081       INTEGER iBufr1, iBufr2, nri, nrj
                0082 C     MPI stuff (should be in a routine call)
40f5e5bc62 Patr*0083       INTEGER mpiStatus(MPI_STATUS_SIZE)
                0084       INTEGER mpiRc
                0085       INTEGER wHandle
                0086 #endif
                0087 CEOP
                0088 
b475142410 Jean*0089       updateCorners = cornerMode .EQ. EXCH_UPDATE_CORNERS
54d78f5995 Jean*0090 C-    Tile size of arrays to exchange:
                0091       i1Lo  = 1-myOLw
                0092       i1Hi  = sNx+myOLe
                0093       j1Lo  = 1-myOLs
                0094       j1Hi  = sNy+myOLn
                0095       k1Lo  = 1
                0096       k1Hi  = myNz
                0097       i2Lo  = 1-myOLw
                0098       i2Hi  = sNx+myOLe
                0099       j2Lo  = 1-myOLs
                0100       j2Hi  = sNy+myOLn
                0101       k2Lo  = 1
                0102       k2Hi  = myNz
40f5e5bc62 Patr*0103 
54d78f5995 Jean*0104 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0105 
e79836c793 Jean*0106 C     Prevent anyone to access shared buffer while an other thread modifies it
                0107       CALL BAR2( myThid )
                0108 
54d78f5995 Jean*0109 C--   Extract from buffer (either from level 1 if local exch,
                0110 C                     or level 2 if coming from an other Proc)
                0111 C  AD: = fill buffer from my-tile-edge overlap-region, level 1 or 2 depending
                0112 C  AD:   on local (to this Proc) or remote Proc tile destination
                0113       DO bj=myByLo(myThid), myByHi(myThid)
                0114        DO bi=myBxLo(myThid), myBxHi(myThid)
8adbfea2f8 Jean*0115         thisTile=W2_myTileList(bi,bj)
54d78f5995 Jean*0116         nN=exch2_nNeighbours(thisTile)
                0117         DO N=1,nN
                0118           CALL EXCH2_GET_UV_BOUNDS(
b475142410 Jean*0119      I               fieldCode, exchWidthX, updateCorners,
54d78f5995 Jean*0120      I               thisTile, N,
                0121      O               tIlo1, tIhi1, tJlo1, tJhi1,
                0122      O               tIlo2, tIhi2, tJlo2, tJhi2,
                0123      O               tiStride, tjStride,
                0124      O               oIs1, oJs1, oIs2, oJs2,
                0125      I               myThid )
                0126           tKLo=1
                0127           tKHi=myNz
                0128           tKStride=1
                0129 
                0130 C     From buffer, get my points
                0131 C     (tIlo:tIhi:tiStride,tJlo:tJhi,tJStride,tKlo:tKhi,tKStride) in "array1,2":
                0132 C     Note: when transferring data within a process:
                0133 C      o e2Bufr entry to read is entry associated with opposing send record
                0134 C      o e2_msgHandle entry to read is entry associated with opposing send record.
                0135           CALL EXCH2_AD_GET_RX2(
                0136      I               tIlo1, tIhi1, tIlo2, tIhi2, tiStride,
                0137      I               tJlo1, tJhi1, tJlo2, tJhi2, tjStride,
                0138      I               tKlo, tKhi, tkStride,
                0139      I               thisTile, N, bi, bj,
                0140      I               e2BufrRecSize, W2_maxNeighbours, nSx, nSy,
8adbfea2f8 Jean*0141      O               iBuf1Filled(N,bi,bj), iBuf2Filled(N,bi,bj),
54d78f5995 Jean*0142      O               e2Bufr1_RX, e2Bufr2_RX,
                0143      U               array1(1-myOLw,1-myOLs,1,bi,bj),
                0144      U               array2(1-myOLw,1-myOLs,1,bi,bj),
                0145      I               i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi,
                0146      I               i2Lo, i2Hi, j2Lo, j2Hi, k2Lo, k2Hi,
                0147      U               e2_msgHandles,
8adbfea2f8 Jean*0148      I               W2_myCommFlag(N,bi,bj), myThid )
54d78f5995 Jean*0149         ENDDO
40f5e5bc62 Patr*0150        ENDDO
                0151       ENDDO
                0152 
e79836c793 Jean*0153 C     Wait until all threads finish filling buffer
                0154       CALL BAR2( myThid )
                0155 
54d78f5995 Jean*0156 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0157 
                0158 #ifdef ALLOW_USE_MPI
21a61ba58f Jean*0159       IF ( usingMPI ) THEN
54d78f5995 Jean*0160 C  AD: all MPI part is acting on buffer and is identical to forward code,
                0161 C  AD: except a) the buffer level: send from lev.2, receive into lev.1
d6ea3164dc Jean*0162 C  AD:        b) the length of transferred buffer (<- match the ad_put/ad_get)
54d78f5995 Jean*0163 
                0164       _BEGIN_MASTER( myThid )
40f5e5bc62 Patr*0165 
54d78f5995 Jean*0166 C--   Send my data (in buffer, level 1) to target Process
                0167       DO bj=1,nSy
                0168        DO bi=1,nSx
8adbfea2f8 Jean*0169         thisTile=W2_myTileList(bi,bj)
54d78f5995 Jean*0170         nN=exch2_nNeighbours(thisTile)
                0171         DO N=1,nN
                0172 C-    Skip the call if this is an internal exchange
8adbfea2f8 Jean*0173          IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
54d78f5995 Jean*0174           CALL EXCH2_SEND_RX2(
                0175      I               thisTile, N,
                0176      I               e2BufrRecSize,
8adbfea2f8 Jean*0177      I               iBuf1Filled(N,bi,bj),    iBuf2Filled(N,bi,bj),
                0178      I               e2Bufr1_RX(1,N,bi,bj,2), e2Bufr2_RX(1,N,bi,bj,2),
54d78f5995 Jean*0179      O               e2_msgHandles(1,N,bi,bj),
8adbfea2f8 Jean*0180      I               W2_myCommFlag(N,bi,bj), myThid )
54d78f5995 Jean*0181          ENDIF
                0182         ENDDO
40f5e5bc62 Patr*0183        ENDDO
                0184       ENDDO
                0185 
54d78f5995 Jean*0186 C--   Receive data (in buffer, level 1) from source Process
                0187       DO bj=1,nSy
                0188        DO bi=1,nSx
8adbfea2f8 Jean*0189         thisTile=W2_myTileList(bi,bj)
54d78f5995 Jean*0190         nN=exch2_nNeighbours(thisTile)
                0191         DO N=1,nN
                0192 C-    Skip the call if this is an internal exchange
8adbfea2f8 Jean*0193          IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
54d78f5995 Jean*0194           farTile=exch2_neighbourId(N,thisTile)
                0195           oN = exch2_opposingSend(N,thisTile)
                0196           CALL EXCH2_GET_UV_BOUNDS(
b475142410 Jean*0197      I               fieldCode, exchWidthX, updateCorners,
54d78f5995 Jean*0198      I               farTile, oN,
                0199      O               tIlo1, tIhi1, tJlo1, tJhi1,
                0200      O               tIlo2, tIhi2, tJlo2, tJhi2,
                0201      O               tiStride, tjStride,
                0202      O               oIs1, oJs1, oIs2, oJs2,
                0203      I               myThid )
                0204           nri = 1 + (tIhi1-tIlo1)/tiStride
                0205           nrj = 1 + (tJhi1-tJlo1)/tjStride
                0206           iBufr1 = nri*nrj*myNz
                0207           nri = 1 + (tIhi2-tIlo2)/tiStride
                0208           nrj = 1 + (tJhi2-tJlo2)/tjStride
                0209           iBufr2 = nri*nrj*myNz
                0210 C       Receive from neighbour N to fill buffer and later on the array
                0211           CALL EXCH2_RECV_RX2(
                0212      I               thisTile, N,
                0213      I               e2BufrRecSize,
                0214      I               iBufr1, iBufr2,
8adbfea2f8 Jean*0215      I               e2Bufr1_RX(1,N,bi,bj,1), e2Bufr2_RX(1,N,bi,bj,1),
                0216      I               W2_myCommFlag(N,bi,bj), myThid )
54d78f5995 Jean*0217          ENDIF
                0218         ENDDO
                0219        ENDDO
                0220       ENDDO
                0221 
                0222 C--   Clear message handles/locks
                0223       DO bj=1,nSy
                0224        DO bi=1,nSx
8adbfea2f8 Jean*0225         thisTile=W2_myTileList(bi,bj)
54d78f5995 Jean*0226         nN=exch2_nNeighbours(thisTile)
                0227         DO N=1,nN
                0228 C     Note: In a between process tile-tile data transport using
                0229 C           MPI the sender needs to clear an Isend wait handle here.
                0230 C           In a within process tile-tile data transport using true
                0231 C           shared address space/or direct transfer through commonly
                0232 C           addressable memory blocks the receiver needs to assert
                0233 C           that he has consumed the buffer the sender filled here.
                0234          farTile=exch2_neighbourId(N,thisTile)
8adbfea2f8 Jean*0235          IF     ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
54d78f5995 Jean*0236           wHandle = e2_msgHandles(1,N,bi,bj)
                0237           CALL MPI_Wait( wHandle, mpiStatus, mpiRc )
                0238           wHandle = e2_msgHandles(2,N,bi,bj)
                0239           CALL MPI_Wait( wHandle, mpiStatus, mpiRc )
8adbfea2f8 Jean*0240          ELSEIF ( W2_myCommFlag(N,bi,bj) .EQ. 'P' ) THEN
54d78f5995 Jean*0241          ELSE
                0242          ENDIF
                0243         ENDDO
                0244        ENDDO
                0245       ENDDO
                0246 
                0247       _END_MASTER( myThid )
e79836c793 Jean*0248 C     Everyone waits until master-thread finishes receiving
                0249       CALL BAR2( myThid )
                0250 
21a61ba58f Jean*0251       ENDIF
54d78f5995 Jean*0252 #endif /* ALLOW_USE_MPI */
                0253 
                0254 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0255 
                0256 C--   Post sends into buffer (buffer level 1):
                0257       DO bj=myByLo(myThid), myByHi(myThid)
                0258        DO bi=myBxLo(myThid), myBxHi(myThid)
8adbfea2f8 Jean*0259         thisTile=W2_myTileList(bi,bj)
54d78f5995 Jean*0260         nN=exch2_nNeighbours(thisTile)
                0261         DO N=1,nN
                0262           farTile=exch2_neighbourId(N,thisTile)
                0263           oN = exch2_opposingSend(N,thisTile)
                0264           CALL EXCH2_GET_UV_BOUNDS(
b475142410 Jean*0265      I               fieldCode, exchWidthX, updateCorners,
54d78f5995 Jean*0266      I               farTile, oN,
                0267      O               tIlo1, tIhi1, tJlo1, tJhi1,
                0268      O               tIlo2, tIhi2, tJlo2, tJhi2,
                0269      O               tiStride, tjStride,
                0270      O               oIs1, oJs1, oIs2, oJs2,
                0271      I               myThid )
                0272           tKLo=1
                0273           tKHi=myNz
                0274           tKStride=1
                0275 C-    Put my points in buffer for neighbour N to fill points
                0276 C     (tIlo:tIhi:tiStride,tJlo:tJhi,tJStride,tKlo:tKhi,tKStride)
                0277 C     in its copy of "array1" & "array2".
                0278           CALL EXCH2_AD_PUT_RX2(
                0279      I               tIlo1, tIhi1, tIlo2, tIhi2, tiStride,
                0280      I               tJlo1, tJhi1, tJlo2, tJhi2, tjStride,
                0281      I               tKlo, tKhi, tkStride,
                0282      I               oIs1, oJs1, oIs2, oJs2,
                0283      I               thisTile, N,
                0284      I               e2BufrRecSize,
8adbfea2f8 Jean*0285      O               e2Bufr1_RX(1,N,bi,bj,1), e2Bufr2_RX(1,N,bi,bj,1),
54d78f5995 Jean*0286      I               array1(1-myOLw,1-myOLs,1,bi,bj),
                0287      I               array2(1-myOLw,1-myOLs,1,bi,bj),
                0288      I               i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi,
                0289      I               i2Lo, i2Hi, j2Lo, j2Hi, k2Lo, k2Hi,
                0290      O               e2_msgHandles(1,N,bi,bj),
8adbfea2f8 Jean*0291      I               W2_myCommFlag(N,bi,bj), signOption, myThid )
54d78f5995 Jean*0292         ENDDO
40f5e5bc62 Patr*0293        ENDDO
                0294       ENDDO
                0295 
                0296       RETURN
                0297       END
                0298 
                0299 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0300 
                0301 CEH3 ;;; Local Variables: ***
                0302 CEH3 ;;; mode:fortran ***
                0303 CEH3 ;;; End: ***