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