Warning, /eesupp/src/exch_rx_recv_get_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"
4947bd1c5a Jean*0002 #undef EXCH_USE_SPINNING
92f012330e Alis*0003
4c563c2ee9 Chri*0004 CBOP
0005 C !ROUTINE: EXCH_RX_RECV_GET_X
0006
0007 C !INTERFACE:
92f012330e Alis*0008 SUBROUTINE EXCH_RX_RECV_GET_X( 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_RX_GET_X
0017 C | o "Send" or "put" X 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
92f012330e Alis*0040 C support for adjoint integration of code. )
4c563c2ee9 Chri*0041 C theCornerMode :: Flag indicating whether corner updates are
92f012330e Alis*0042 C needed.
4c563c2ee9 Chri*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 biW, bjW :: West tile indices
0064 C biE, bjE :: East 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 westCommMode :: Working variables holding type
0069 C eastCommMode of communication a particular
0070 C tile face uses.
4947bd1c5a Jean*0071 INTEGER i, j, k, iMin, iMax, iB, iB0
92f012330e Alis*0072 INTEGER bi, bj, biW, bjW, biE, bjE
0073 INTEGER eBl
0074 INTEGER westCommMode
0075 INTEGER eastCommMode
4947bd1c5a Jean*0076 #ifdef EXCH_USE_SPINNING
92f012330e Alis*0077 INTEGER spinCount
4947bd1c5a Jean*0078 #endif
92f012330e Alis*0079 #ifdef ALLOW_USE_MPI
19765ceae9 Jean*0080 INTEGER theProc, theTag, theType, theSize
92f012330e Alis*0081 INTEGER mpiStatus(MPI_STATUS_SIZE,4), mpiRc
19765ceae9 Jean*0082 # ifdef ALLOW_AUTODIFF_OPENAD_AMPI
0083 INTEGER pReqI
0084 # endif
0085 #endif /* ALLOW_USE_MPI */
4c563c2ee9 Chri*0086 CEOP
92f012330e Alis*0087
4947bd1c5a Jean*0088 C-- Under a "put" scenario we
92f012330e Alis*0089 C-- i. set completetion signal for buffer we put into.
4947bd1c5a Jean*0090 C-- ii. wait for completetion signal indicating data has been put in
92f012330e Alis*0091 C-- our buffer.
0092 C-- Under a messaging mode we "receive" the message.
0093 C-- Under a "get" scenario we
0094 C-- i. Check that the data is ready.
0095 C-- ii. Read the data.
0096 C-- iii. Set data read flag + memory sync.
0097
0098 #ifdef ALLOW_USE_MPI
4947bd1c5a Jean*0099 IF ( usingMPI ) THEN
19765ceae9 Jean*0100
4947bd1c5a Jean*0101 C-- Receive buffer data: Only Master Thread do proc communication
0102 _BEGIN_MASTER(myThid)
0103
0104 DO bj=1,nSy
0105 DO bi=1,nSx
0106 eBl = exchangeBufLevel(1,bi,bj)
0107 westCommMode = _tileCommModeW(bi,bj)
0108 eastCommMode = _tileCommModeE(bi,bj)
0109 biE = _tileBiE(bi,bj)
0110 bjE = _tileBjE(bi,bj)
0111 biW = _tileBiW(bi,bj)
0112 bjW = _tileBjW(bi,bj)
0113 theType = _MPI_TYPE_RX
0114 theSize = sNy*exchWidthX*myNz
0115
0116 IF ( westCommMode .EQ. COMM_MSG ) THEN
92f012330e Alis*0117 theProc = tilePidW(bi,bj)
0118 theTag = _tileTagRecvW(bi,bj)
0eef504f9b Jean*0119 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
4947bd1c5a Jean*0120 CALL MPI_Recv( westRecvBuf_RX(1,eBl,bi,bj), theSize,
0121 & theType, theProc, theTag, MPI_COMM_MODEL,
92f012330e Alis*0122 & mpiStatus, mpiRc )
033dc5d283 Jean*0123 # else
4d40368441 Jean*0124 pReqI=exchNReqsX(1,bi,bj)+1
4947bd1c5a Jean*0125 CALL ampi_recv_RX(
0126 & westRecvBuf_RX(1,eBl,bi,bj) ,
0127 & theSize ,
0128 & theType ,
0129 & theProc ,
0130 & theTag ,
0131 & MPI_COMM_MODEL ,
0132 & exchReqIdX(pReqI,1,bi,bj),
0133 & exchNReqsX(1,bi,bj),
0134 & mpiStatus ,
0135 & mpiRc )
0eef504f9b Jean*0136 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
4947bd1c5a Jean*0137 westRecvAck(eBl,bi,bj) = 1
92f012330e Alis*0138 ENDIF
4947bd1c5a Jean*0139
92f012330e Alis*0140 IF ( eastCommMode .EQ. COMM_MSG ) THEN
0141 theProc = tilePidE(bi,bj)
0142 theTag = _tileTagRecvE(bi,bj)
0eef504f9b Jean*0143 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
4947bd1c5a Jean*0144 CALL MPI_Recv( eastRecvBuf_RX(1,eBl,bi,bj), theSize,
0145 & theType, theProc, theTag, MPI_COMM_MODEL,
92f012330e Alis*0146 & mpiStatus, mpiRc )
033dc5d283 Jean*0147 # else
4d40368441 Jean*0148 pReqI=exchNReqsX(1,bi,bj)+1
4947bd1c5a Jean*0149 CALL ampi_recv_RX(
0150 & eastRecvBuf_RX(1,eBl,bi,bj) ,
0151 & theSize ,
0152 & theType ,
0153 & theProc ,
0154 & theTag ,
0155 & MPI_COMM_MODEL ,
0156 & exchReqIdX(pReqI,1,bi,bj),
0157 & exchNReqsX(1,bi,bj),
0158 & mpiStatus ,
0159 & mpiRc )
0eef504f9b Jean*0160 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
4947bd1c5a Jean*0161 eastRecvAck(eBl,bi,bj) = 1
92f012330e Alis*0162 ENDIF
0163 ENDDO
0164 ENDDO
0165
4947bd1c5a Jean*0166 C-- Processes wait for buffers I am going to read to be ready.
0167 IF ( .NOT.exchUsesBarrier ) THEN
0168 DO bj=1,nSy
0169 DO bi=1,nSx
0170 IF ( exchNReqsX(1,bi,bj) .GT. 0 ) THEN
0171 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
0172 CALL MPI_Waitall( exchNReqsX(1,bi,bj), exchReqIdX(1,1,bi,bj),
0173 & mpiStatus, mpiRC )
0174 # else
0175 CALL ampi_waitall(
0176 & exchNReqsX(1,bi,bj),
0177 & exchReqIdX(1,1,bi,bj),
0178 & mpiStatus,
0179 & mpiRC )
0180 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
0181 ENDIF
0182 C Clear outstanding requests counter
0183 exchNReqsX(1,bi,bj) = 0
0184 ENDDO
0185 ENDDO
0186 ENDIF
0187
0188 _END_MASTER(myThid)
0189 C-- need to sync threads after master has received data ;
0190 C (done after mpi waitall in case waitall is really needed)
0191 _BARRIER
0192
0193 ENDIF
0194 #endif /* ALLOW_USE_MPI */
19765ceae9 Jean*0195
4947bd1c5a Jean*0196 C-- Threads wait for buffers I am going to read to be ready.
0197 C note: added BARRIER in exch_send_put S/R and here above (message mode)
0198 C so that we no longer needs this (undef EXCH_USE_SPINNING)
0199 #ifdef EXCH_USE_SPINNING
92f012330e Alis*0200 IF ( exchUsesBarrier ) THEN
0201 C o On some machines ( T90 ) use system barrier rather than spinning.
0202 CALL BARRIER( myThid )
0203 ELSE
0204 C o Spin waiting for completetion flag. This avoids a global-lock
0205 C i.e. we only lock waiting for data that we need.
0206 DO bj=myByLo(myThid),myByHi(myThid)
0207 DO bi=myBxLo(myThid),myBxHi(myThid)
4947bd1c5a Jean*0208
92f012330e Alis*0209 spinCount = 0
4947bd1c5a Jean*0210 eBl = exchangeBufLevel(1,bi,bj)
92f012330e Alis*0211 westCommMode = _tileCommModeW(bi,bj)
0212 eastCommMode = _tileCommModeE(bi,bj)
0eef504f9b Jean*0213 # ifndef ALLOW_AUTODIFF_OPENAD_AMPI
92f012330e Alis*0214 10 CONTINUE
e78c04eec8 Jean*0215 CALL FOOL_THE_COMPILER( spinCount )
92f012330e Alis*0216 spinCount = spinCount+1
0217 C IF ( myThid .EQ. 1 .AND. spinCount .GT. _EXCH_SPIN_LIMIT ) THEN
0218 C WRITE(*,*) ' eBl = ', ebl
0219 C STOP ' S/R EXCH_RECV_GET_X: spinCount .GT. _EXCH_SPIN_LIMIT'
0220 C ENDIF
061bed00a3 Jean*0221 IF ( westRecvAck(eBl,bi,bj) .EQ. 0 ) GOTO 10
0222 IF ( eastRecvAck(eBl,bi,bj) .EQ. 0 ) GOTO 10
4947bd1c5a Jean*0223 # else
0224 DO WHILE ((westRecvAck(eBl,bi,bj) .EQ. 0
0225 & .OR.
0226 & eastRecvAck(eBl,bi,bj) .EQ. 0 ))
033dc5d283 Jean*0227 CALL FOOL_THE_COMPILER( spinCount )
0228 spinCount = spinCount+1
4947bd1c5a Jean*0229 ENDDO
0eef504f9b Jean*0230 # endif /* ALLOW_AUTODIFF_OPENAD_AMPI */
92f012330e Alis*0231 C Clear outstanding requests
061bed00a3 Jean*0232 westRecvAck(eBl,bi,bj) = 0
0233 eastRecvAck(eBl,bi,bj) = 0
92f012330e Alis*0234 C Update statistics
0235 IF ( exchCollectStatistics ) THEN
0236 exchRecvXExchCount(1,bi,bj) = exchRecvXExchCount(1,bi,bj)+1
4947bd1c5a Jean*0237 exchRecvXSpinCount(1,bi,bj) =
92f012330e Alis*0238 & exchRecvXSpinCount(1,bi,bj)+spinCount
4947bd1c5a Jean*0239 exchRecvXSpinMax(1,bi,bj) =
92f012330e Alis*0240 & MAX(exchRecvXSpinMax(1,bi,bj),spinCount)
4947bd1c5a Jean*0241 exchRecvXSpinMin(1,bi,bj) =
92f012330e Alis*0242 & MIN(exchRecvXSpinMin(1,bi,bj),spinCount)
0243 ENDIF
4947bd1c5a Jean*0244
92f012330e Alis*0245 ENDDO
0246 ENDDO
0247 ENDIF
4947bd1c5a Jean*0248 #endif /* EXCH_USE_SPINNING */
0249
0250 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
92f012330e Alis*0251
0252 C-- Read from the buffers
0253 DO bj=myByLo(myThid),myByHi(myThid)
0254 DO bi=myBxLo(myThid),myBxHi(myThid)
0255
4947bd1c5a Jean*0256 eBl = exchangeBufLevel(1,bi,bj)
0257 biE = _tileBiE(bi,bj)
0258 bjE = _tileBjE(bi,bj)
0259 biW = _tileBiW(bi,bj)
0260 bjW = _tileBjW(bi,bj)
92f012330e Alis*0261 westCommMode = _tileCommModeW(bi,bj)
0262 eastCommMode = _tileCommModeE(bi,bj)
4947bd1c5a Jean*0263
92f012330e Alis*0264 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
0265 iMin = sNx+1
0266 iMax = sNx+exchWidthX
0267 iB0 = 0
0268 IF ( eastCommMode .EQ. COMM_PUT
0269 & .OR. eastCommMode .EQ. COMM_MSG ) THEN
0270 iB = 0
4947bd1c5a Jean*0271 DO k=1,myNz
0272 DO j=1,sNy
0273 DO i=iMin,iMax
92f012330e Alis*0274 iB = iB + 1
4947bd1c5a Jean*0275 array(i,j,k,bi,bj) = eastRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0276 ENDDO
0277 ENDDO
0278 ENDDO
0279 ELSEIF ( eastCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0280 DO k=1,myNz
0281 DO j=1,sNy
92f012330e Alis*0282 iB = iB0
4947bd1c5a Jean*0283 DO i=iMin,iMax
92f012330e Alis*0284 iB = iB+1
4947bd1c5a Jean*0285 array(i,j,k,bi,bj) = array(iB,j,k,biE,bjE)
92f012330e Alis*0286 ENDDO
0287 ENDDO
0288 ENDDO
0289 ENDIF
0290 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
0291 iMin = sNx-exchWidthX+1
0292 iMax = sNx
0293 iB0 = 1-exchWidthX-1
4947bd1c5a Jean*0294 IF ( eastCommMode .EQ. COMM_PUT
92f012330e Alis*0295 & .OR. eastCommMode .EQ. COMM_MSG ) THEN
0296 iB = 0
4947bd1c5a Jean*0297 DO k=1,myNz
0298 DO j=1,sNy
0299 DO i=iMin,iMax
92f012330e Alis*0300 iB = iB + 1
4947bd1c5a Jean*0301 array(i,j,k,bi,bj) =
0302 & array(i,j,k,bi,bj) + eastRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0303 ENDDO
0304 ENDDO
0305 ENDDO
0306 ELSEIF ( eastCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0307 DO k=1,myNz
0308 DO j=1,sNy
92f012330e Alis*0309 iB = iB0
4947bd1c5a Jean*0310 DO i=iMin,iMax
92f012330e Alis*0311 iB = iB+1
4947bd1c5a Jean*0312 array(i,j,k,bi,bj) =
0313 & array(i,j,k,bi,bj) + array(iB,j,k,biE,bjE)
0314 array(iB,j,k,biE,bjE) = 0.0
92f012330e Alis*0315 ENDDO
0316 ENDDO
0317 ENDDO
0318 ENDIF
0319 ENDIF
4947bd1c5a Jean*0320
92f012330e Alis*0321 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
0322 iMin = 1-exchWidthX
0323 iMax = 0
0324 iB0 = sNx-exchWidthX
0325 IF ( westCommMode .EQ. COMM_PUT
0326 & .OR. westCommMode .EQ. COMM_MSG ) THEN
0327 iB = 0
4947bd1c5a Jean*0328 DO k=1,myNz
0329 DO j=1,sNy
0330 DO i=iMin,iMax
92f012330e Alis*0331 iB = iB + 1
4947bd1c5a Jean*0332 array(i,j,k,bi,bj) = westRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0333 ENDDO
0334 ENDDO
0335 ENDDO
0336 ELSEIF ( westCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0337 DO k=1,myNz
0338 DO j=1,sNy
92f012330e Alis*0339 iB = iB0
4947bd1c5a Jean*0340 DO i=iMin,iMax
92f012330e Alis*0341 iB = iB+1
4947bd1c5a Jean*0342 array(i,j,k,bi,bj) = array(iB,j,k,biW,bjW)
92f012330e Alis*0343 ENDDO
0344 ENDDO
0345 ENDDO
0346 ENDIF
0347 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
0348 iMin = 1
0349 iMax = 1+exchWidthX-1
0350 iB0 = sNx
4947bd1c5a Jean*0351 IF ( westCommMode .EQ. COMM_PUT
0352 & .OR. westCommMode .EQ. COMM_MSG ) THEN
92f012330e Alis*0353 iB = 0
4947bd1c5a Jean*0354 DO k=1,myNz
0355 DO j=1,sNy
0356 DO i=iMin,iMax
92f012330e Alis*0357 iB = iB + 1
4947bd1c5a Jean*0358 array(i,j,k,bi,bj) =
0359 & array(i,j,k,bi,bj) + westRecvBuf_RX(iB,eBl,bi,bj)
92f012330e Alis*0360 ENDDO
0361 ENDDO
0362 ENDDO
0363 ELSEIF ( westCommMode .EQ. COMM_GET ) THEN
4947bd1c5a Jean*0364 DO k=1,myNz
0365 DO j=1,sNy
92f012330e Alis*0366 iB = iB0
4947bd1c5a Jean*0367 DO i=iMin,iMax
92f012330e Alis*0368 iB = iB+1
4947bd1c5a Jean*0369 array(i,j,k,bi,bj) =
0370 & array(i,j,k,bi,bj) + array(iB,j,k,biW,bjW)
0371 array(iB,j,k,biW,bjW) = 0.0
92f012330e Alis*0372 ENDDO
0373 ENDDO
0374 ENDDO
0375 ENDIF
0376 ENDIF
0377
0378 ENDDO
0379 ENDDO
0380
0381 RETURN
0382 END