Warning, /eesupp/src/exch_rx_send_put_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"
0002
4c563c2ee9 Chri*0003 CBOP
0004 C !ROUTINE: EXCH_RX_SEND_PUT_Y
0005
0006 C !INTERFACE:
92f012330e Alis*0007 SUBROUTINE EXCH_RX_SEND_PUT_Y( array,
0008 I myOLw, myOLe, myOLs, myOLn, myNz,
0009 I exchWidthX, exchWidthY,
0010 I thesimulationMode, thecornerMode, myThid )
0011 IMPLICIT NONE
4c563c2ee9 Chri*0012 C !DESCRIPTION:
0013 C *==========================================================*
4947bd1c5a Jean*0014 C | SUBROUTINE SEND_PUT_Y
0015 C | o "Send" or "put" Y edges for RX array.
4c563c2ee9 Chri*0016 C *==========================================================*
4947bd1c5a Jean*0017 C | Routine that invokes actual message passing send or
0018 C | direct "put" of data to update Y faces of an XY[R] array.
4c563c2ee9 Chri*0019 C *==========================================================*
92f012330e Alis*0020
4c563c2ee9 Chri*0021 C !USES:
92f012330e Alis*0022 C == Global variables ==
0023 #include "SIZE.h"
0024 #include "EEPARAMS.h"
0025 #include "EESUPPORT.h"
0026 #include "EXCH.h"
4c563c2ee9 Chri*0027
0028 C !INPUT/OUTPUT PARAMETERS:
92f012330e Alis*0029 C == Routine arguments ==
4c563c2ee9 Chri*0030 C array :: Array with edges to exchange.
0031 C myOLw :: West, East, North and South overlap region sizes.
92f012330e Alis*0032 C myOLe
0033 C myOLn
0034 C myOLs
4c563c2ee9 Chri*0035 C exchWidthX :: Width of data region exchanged.
92f012330e Alis*0036 C exchWidthY
4947bd1c5a Jean*0037 C theSimulationMode :: Forward or reverse mode exchange ( provides
4c563c2ee9 Chri*0038 C support for adjoint integration of code. )
4947bd1c5a Jean*0039 C Note - the reverse mode for an assignment
0040 C is an accumulation. This means that
4c563c2ee9 Chri*0041 C put implementations that do leary things
4947bd1c5a Jean*0042 C like writing to overlap regions in a
4c563c2ee9 Chri*0043 C remote process need to be even more
0044 C careful. You need to be pretty careful
0045 C in forward mode too!
4947bd1c5a Jean*0046 C theCornerMode :: Flag indicating whether corner updates are
4c563c2ee9 Chri*0047 C needed.
0048 C myThid :: Thread number of this instance of S/R EXCH...
0049 C eBl :: Edge buffer level
92f012330e Alis*0050 INTEGER myOLw
0051 INTEGER myOLe
0052 INTEGER myOLs
0053 INTEGER myOLn
0054 INTEGER myNz
0055 _RX array(1-myOLw:sNx+myOLe,
4947bd1c5a Jean*0056 & 1-myOLs:sNy+myOLn,
92f012330e Alis*0057 & myNZ, nSx, nSy)
0058 INTEGER exchWidthX
0059 INTEGER exchWidthY
0060 INTEGER theSimulationMode
0061 INTEGER theCornerMode
0062 INTEGER myThid
0063
4c563c2ee9 Chri*0064 C !LOCAL VARIABLES:
92f012330e Alis*0065 C == Local variables ==
4947bd1c5a Jean*0066 C i, j, k, jMin, jMax, iB - Loop counters and extents
0067 C bi, bj
92f012330e Alis*0068 C biS, bjS - South tile indices
0069 C biN, bjN - North tile indices
0070 C eBl - Current exchange buffer level
0071 C theProc, theTag, theType, - Variables used in message building
0072 C theSize
0073 C southCommMode - Working variables holding type
0074 C northCommMode of communication a particular
0075 C tile face uses.
4947bd1c5a Jean*0076 INTEGER i, j, k, jMin, jMax, iMin, iMax, iB
92f012330e Alis*0077 INTEGER bi, bj, biS, bjS, biN, bjN
0078 INTEGER eBl
0079 INTEGER northCommMode
0080 INTEGER southCommMode
0081 #ifdef ALLOW_USE_MPI
0082 INTEGER theProc, theTag, theType, theSize, mpiRc
0eef504f9b Jean*0083 # ifdef ALLOW_AUTODIFF_OPENAD_AMPI
033dc5d283 Jean*0084 INTEGER mpiStatus(MPI_STATUS_SIZE)
83996e0652 Jean*0085 INTEGER pReqI
033dc5d283 Jean*0086 # endif
92f012330e Alis*0087 #endif
0088
0089 C-- Write data to exchange buffer
4947bd1c5a Jean*0090 C Various actions are possible depending on the communication mode
92f012330e Alis*0091 C as follows:
0092 C Mode Action
0093 C -------- ---------------------------
0094 C COMM_NONE Do nothing
0095 C
0096 C COMM_MSG Message passing communication ( e.g. MPI )
0097 C Fill south send buffer from this tile.
0098 C Send data with tag identifying tile and direction.
0099 C Fill north send buffer from this tile.
0100 C Send data with tag identifying tile and direction.
0101 C
0102 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
0103 C Fill south receive buffer of south-neighbor tile
0104 C Fill north receive buffer of north-neighbor tile
0105 C Sync. memory
0106 C Write data-ready Ack for north edge of south-neighbor
0107 C tile
0108 C Write data-ready Ack for south edge of north-neighbor
0109 C tile
0110 C Sync. memory
4c563c2ee9 Chri*0111 CEOP
0112
0eef504f9b Jean*0113 #ifdef ALLOW_AUTODIFF_OPENAD_AMPI
033dc5d283 Jean*0114 # ifdef ALLOW_USE_MPI
4947bd1c5a Jean*0115 IF ( usingMPI ) THEN
0116 _BEGIN_MASTER(myThid)
0117 DO bj=1,nSy
0118 DO bi=1,nSx
0119 CALL ampi_awaitall (
0120 & exchNReqsY(1,bi,bj) ,
0121 & exchReqIdY(1,1,bi,bj) ,
0122 & mpiStatus ,
0123 & mpiRC )
0124 ENDDO
0125 ENDDO
0126 _END_MASTER(myThid)
0127 ENDIF
033dc5d283 Jean*0128 # endif
0129 #endif
0130
4947bd1c5a Jean*0131 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
0132
0133 C Prevent anyone to access shared buffer while an other thread modifies it
0134 _BARRIER
0135
0136 C Fill shared buffers from array values
92f012330e Alis*0137 DO bj=myByLo(myThid),myByHi(myThid)
0138 DO bi=myBxLo(myThid),myBxHi(myThid)
0139
4947bd1c5a Jean*0140 eBl = exchangeBufLevel(1,bi,bj)
0141 southCommMode = _tileCommModeS(bi,bj)
0142 northCommMode = _tileCommModeN(bi,bj)
0143 biS = _tileBiS(bi,bj)
0144 bjS = _tileBjS(bi,bj)
0145 biN = _tileBiN(bi,bj)
0146 bjN = _tileBjN(bi,bj)
92f012330e Alis*0147 iMin = 1
0148 iMax = sNx
0149 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
0150 iMin = 1-exchWidthX
0151 iMax = sNx+exchWidthX
0152 ENDIF
0153
4947bd1c5a Jean*0154 C >>>>>>>>>>>>>>>>>>> FORWARD RUN <<<<<<<<<<<<<<<<<<<
92f012330e Alis*0155
4947bd1c5a Jean*0156 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
92f012330e Alis*0157
0158 C o Send or Put south edge
0159 jMin = 1
0160 jMax = 1+exchWidthY-1
4947bd1c5a Jean*0161 IF ( southCommMode .EQ. COMM_MSG ) THEN
0162 iB = 0
0163 DO k=1,myNz
0164 DO j=jMin,jMax
0165 DO i=iMin,iMax
0166 iB = iB + 1
0167 southSendBuf_RX(iB,eBl,bi,bj) = array(i,j,k,bi,bj)
0168 ENDDO
92f012330e Alis*0169 ENDDO
0170 ENDDO
4947bd1c5a Jean*0171 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
0172 iB = 0
0173 DO k=1,myNz
0174 DO j=jMin,jMax
0175 DO i=iMin,iMax
0176 iB = iB + 1
0177 northRecvBuf_RX(iB,eBl,biS,bjS) = array(i,j,k,bi,bj)
0178 ENDDO
92f012330e Alis*0179 ENDDO
0180 ENDDO
4947bd1c5a Jean*0181 ELSEIF ( southCommMode .NE. COMM_NONE
0182 & .AND. southCommMode .NE. COMM_GET ) THEN
0183 STOP ' S/R EXCH: Invalid commS mode.'
0184 ENDIF
92f012330e Alis*0185
0186 C o Send or Put north edge
0187 jMin = sNy-exchWidthY+1
0188 jMax = sNy
4947bd1c5a Jean*0189 IF ( northCommMode .EQ. COMM_MSG ) THEN
0190 iB = 0
0191 DO k=1,myNz
0192 DO j=jMin,jMax
0193 DO i=iMin,iMax
0194 iB = iB + 1
0195 northSendBuf_RX(iB,eBl,bi,bj) = array(i,j,k,bi,bj)
0196 ENDDO
92f012330e Alis*0197 ENDDO
0198 ENDDO
0199 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
0200 iB = 0
4947bd1c5a Jean*0201 DO k=1,myNz
0202 DO j=jMin,jMax
0203 DO i=iMin,iMax
92f012330e Alis*0204 iB = iB + 1
4947bd1c5a Jean*0205 southRecvBuf_RX(iB,eBl,biN,bjN) = array(i,j,k,bi,bj)
92f012330e Alis*0206 ENDDO
0207 ENDDO
0208 ENDDO
0209 ELSEIF ( northCommMode .NE. COMM_NONE
0210 & .AND. northCommMode .NE. COMM_GET ) THEN
0211 STOP ' S/R EXCH: Invalid commN mode.'
0212 ENDIF
0213
4947bd1c5a Jean*0214 C >>>>>>>>>>>>>>>>>>> ADJOINT RUN <<<<<<<<<<<<<<<<<<<
92f012330e Alis*0215
0216 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
4947bd1c5a Jean*0217
0218 C o Send or Put south edge
92f012330e Alis*0219 jMin = 1-exchWidthY
0220 jMax = 0
4947bd1c5a Jean*0221 IF ( southCommMode .EQ. COMM_MSG ) THEN
0222 iB = 0
0223 DO k=1,myNz
0224 DO j=jMin,jMax
0225 DO i=iMin,iMax
0226 iB = iB + 1
0227 southSendBuf_RX(iB,eBl,bi,bj) = array(i,j,k,bi,bj)
0228 array(i,j,k,bi,bj) = 0.0
0229 ENDDO
92f012330e Alis*0230 ENDDO
0231 ENDDO
4947bd1c5a Jean*0232 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
0233 iB = 0
0234 DO k=1,myNz
0235 DO j=jMin,jMax
0236 DO i=iMin,iMax
0237 iB = iB + 1
0238 northRecvBuf_RX(iB,eBl,biS,bjS) = array(i,j,k,bi,bj)
0239 array(i,j,k,bi,bj) = 0.0
0240 ENDDO
92f012330e Alis*0241 ENDDO
0242 ENDDO
4947bd1c5a Jean*0243 ELSEIF ( southCommMode .NE. COMM_NONE
0244 & .AND. southCommMode .NE. COMM_GET ) THEN
0245 STOP ' S/R EXCH: Invalid commS mode.'
0246 ENDIF
92f012330e Alis*0247
0248 C o Send or Put north edge
0249 jMin = sNy+1
0250 jMax = sNy+exchWidthY
4947bd1c5a Jean*0251 IF ( northCommMode .EQ. COMM_MSG ) THEN
0252 iB = 0
0253 DO k=1,myNz
0254 DO j=jMin,jMax
0255 DO i=iMin,iMax
0256 iB = iB + 1
0257 northSendBuf_RX(iB,eBl,bi,bj) = array(i,j,k,bi,bj)
0258 array(i,j,k,bi,bj) = 0.0
0259 ENDDO
92f012330e Alis*0260 ENDDO
0261 ENDDO
4947bd1c5a Jean*0262 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
0263 iB = 0
0264 DO k=1,myNz
0265 DO j=jMin,jMax
0266 DO i=iMin,iMax
0267 iB = iB + 1
0268 southRecvBuf_RX(iB,eBl,biN,bjN) = array(i,j,k,bi,bj)
0269 array(i,j,k,bi,bj) = 0.0
0270 ENDDO
92f012330e Alis*0271 ENDDO
0272 ENDDO
4947bd1c5a Jean*0273 ELSEIF ( northCommMode .NE. COMM_NONE
0274 & .AND. northCommMode .NE. COMM_GET ) THEN
0275 STOP ' S/R EXCH: Invalid commN mode.'
0276 ENDIF
0277
92f012330e Alis*0278 ENDIF
4947bd1c5a Jean*0279
92f012330e Alis*0280 ENDDO
0281 ENDDO
0282
4947bd1c5a Jean*0283 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
92f012330e Alis*0284 C-- Signal completetion ( making sure system-wide memory state is
0285 C-- consistent ).
0286
0287 C ** NOTE ** We are relying on being able to produce strong-ordered
0288 C memory semantics here. In other words we assume that there is a
0289 C mechanism which can ensure that by the time the Ack is seen the
0290 C overlap region data that will be exchanged is up to date.
0291 IF ( exchNeedsMemSync ) CALL MEMSYNC
0292
0293 DO bj=myByLo(myThid),myByHi(myThid)
0294 DO bi=myBxLo(myThid),myBxHi(myThid)
4947bd1c5a Jean*0295 eBl = exchangeBufLevel(1,bi,bj)
92f012330e Alis*0296 biS = _tileBiS(bi,bj)
0297 bjS = _tileBjS(bi,bj)
0298 biN = _tileBiN(bi,bj)
0299 bjN = _tileBjN(bi,bj)
0300 southCommMode = _tileCommModeS(bi,bj)
0301 northCommMode = _tileCommModeN(bi,bj)
01f26df47c Jean*0302 IF ( southCommMode.EQ.COMM_PUT ) northRecvAck(eBl,biS,bjS) = 1
0303 IF ( northCommMode.EQ.COMM_PUT ) southRecvAck(eBl,biN,bjN) = 1
0304 IF ( southCommMode.EQ.COMM_GET ) northRecvAck(eBl,biS,bjS) = 1
0305 IF ( northCommMode.EQ.COMM_GET ) southRecvAck(eBl,biN,bjN) = 1
92f012330e Alis*0306 ENDDO
0307 ENDDO
0308
0309 C-- Make sure "ack" setting is seen system-wide.
0310 C Here strong-ordering is not an issue but we want to make
0311 C sure that processes that might spin on the above Ack settings
0312 C will see the setting.
0313 C ** NOTE ** On some machines we wont spin on the Ack setting
0314 C ( particularly the T90 ), instead we will use s system barrier.
4947bd1c5a Jean*0315 C On the T90 the system barrier is very fast and switches out the
92f012330e Alis*0316 C thread while it waits. On most machines the system barrier
0317 C is much too slow and if we own the machine and have one thread
0318 C per process preemption is not a problem.
0319 IF ( exchNeedsMemSync ) CALL MEMSYNC
0320
4947bd1c5a Jean*0321 C Wait until all threads finish filling buffer
8e7b8dcb06 Chri*0322 _BARRIER
05c61d4346 Chri*0323
4947bd1c5a Jean*0324 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
0325
0326 #ifdef ALLOW_USE_MPI
0327 IF ( usingMPI ) THEN
0328 C-- Send buffer data: Only Master Thread do proc communication
0329 _BEGIN_MASTER(myThid)
0330
0331 DO bj=1,nSy
0332 DO bi=1,nSx
0333
0334 eBl = exchangeBufLevel(1,bi,bj)
0335 southCommMode = _tileCommModeS(bi,bj)
0336 northCommMode = _tileCommModeN(bi,bj)
0337 biS = _tileBiS(bi,bj)
0338 bjS = _tileBjS(bi,bj)
0339 biN = _tileBiN(bi,bj)
0340 bjN = _tileBjN(bi,bj)
0341 theType = _MPI_TYPE_RX
0342 theSize = sNx*exchWidthY*myNz
0343 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
0344 theSize = (sNx+2*exchWidthX)*exchWidthY*myNz
0345 ENDIF
0346
0347 IF ( southCommMode .EQ. COMM_MSG ) THEN
0348 C Send buffer data (copied from south edge)
0349 theProc = tilePidS(bi,bj)
0350 theTag = _tileTagSendS(bi,bj)
0351 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
0352 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
0353 CALL MPI_Isend( southSendBuf_RX(1,eBl,bi,bj), theSize,
0354 & theType, theProc, theTag, MPI_COMM_MODEL,
0355 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj),
0356 & mpiRc )
0357 # else
0358 pReqI=exchNReqsY(1,bi,bj)+1
0359 CALL ampi_isend_RX(
0360 & southSendBuf_RX(1,eBl,bi,bj),
0361 & theSize,
0362 & theType,
0363 & theProc,
0364 & theTag,
0365 & MPI_COMM_MODEL,
0366 & exchReqIdY(pReqI,1,bi,bj),
0367 & exchNReqsY(1,bi,bj),
0368 & mpiStatus,
0369 & mpiRc )
0370 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
0371 c northRecvAck(eBl,biS,bjS) = 1
0372 ENDIF
0373
0374 IF ( northCommMode .EQ. COMM_MSG ) THEN
0375 C Send buffer data (copied from north edge)
0376 theProc = tilePidN(bi,bj)
0377 theTag = _tileTagSendN(bi,bj)
0378 #ifndef ALLOW_AUTODIFF_OPENAD_AMPI
0379 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
0380 CALL MPI_Isend( northSendBuf_RX(1,eBl,bi,bj), theSize,
0381 & theType, theProc, theTag, MPI_COMM_MODEL,
0382 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj),
0383 & mpiRc )
0384 # else
0385 pReqI=exchNReqsY(1,bi,bj)+1
0386 CALL ampi_isend_RX(
0387 & northSendBuf_RX(1,eBl,bi,bj) ,
0388 & theSize ,
0389 & theType ,
0390 & theProc ,
0391 & theTag ,
0392 & MPI_COMM_MODEL ,
0393 & exchReqIdY(pReqI,1,bi,bj) ,
0394 & exchNReqsY(1,bi,bj) ,
0395 & mpiStatus ,
0396 & mpiRc )
0397 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
0398 c southRecvAck(eBl,biN,bjN) = 1
0399 ENDIF
0400
0401 ENDDO
0402 ENDDO
0403
0404 _END_MASTER(myThid)
0405
0406 ENDIF
0407 #endif /* ALLOW_USE_MPI */
0408
0409 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
0410
0411 RETURN
92f012330e Alis*0412 END