/[MITgcm]/MITgcm/eesupp/src/exch_rx_send_put_y.template
ViewVC logotype

Contents of /MITgcm/eesupp/src/exch_rx_send_put_y.template

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Tue May 29 14:06:38 2001 UTC (22 years, 11 months ago) by adcroft
Branch: MAIN
CVS Tags: checkpoint40pre3, checkpoint40pre1, checkpoint40pre7, checkpoint40pre6, checkpoint40pre9, checkpoint40pre8, checkpoint40pre2, checkpoint40pre4, checkpoint40pre5, checkpoint40
Merge from branch pre38 :
 o Templating of exch* routines.

1 C $Header: $
2 C $Name: $
3 #include "CPP_EEOPTIONS.h"
4
5 SUBROUTINE EXCH_RX_SEND_PUT_Y( array,
6 I myOLw, myOLe, myOLs, myOLn, myNz,
7 I exchWidthX, exchWidthY,
8 I thesimulationMode, thecornerMode, myThid )
9 C /==========================================================\
10 C | SUBROUTINE SEND_PUT_Y |
11 C | o "Send" or "put" Y edges for RX array. |
12 C |==========================================================|
13 C | Routine that invokes actual message passing send or |
14 C | direct "put" of data to update Y faces of an XY[R] array.|
15 C \==========================================================/
16 IMPLICIT NONE
17
18 C == Global variables ==
19 #include "SIZE.h"
20 #include "EEPARAMS.h"
21 #include "EESUPPORT.h"
22 #include "EXCH.h"
23 C == Routine arguments ==
24 C array - Array with edges to exchange.
25 C myOLw - West, East, North and South overlap region sizes.
26 C myOLe
27 C myOLn
28 C myOLs
29 C exchWidthX - Width of data region exchanged.
30 C exchWidthY
31 C theSimulationMode - Forward or reverse mode exchange ( provides
32 C support for adjoint integration of code. )
33 C Note - the reverse mode for an assignment
34 C is an accumulation. This means that
35 C put implementations that do leary things
36 C like writing to overlap regions in a
37 C remote process need to be even more
38 C careful. You need to be pretty careful
39 C in forward mode too!
40 C theCornerMode - Flag indicating whether corner updates are
41 C needed.
42 C myThid - Thread number of this instance of S/R EXCH...
43 C eBl - Edge buffer level
44 INTEGER myOLw
45 INTEGER myOLe
46 INTEGER myOLs
47 INTEGER myOLn
48 INTEGER myNz
49 _RX array(1-myOLw:sNx+myOLe,
50 & 1-myOLs:sNy+myOLn,
51 & myNZ, nSx, nSy)
52 INTEGER exchWidthX
53 INTEGER exchWidthY
54 INTEGER theSimulationMode
55 INTEGER theCornerMode
56 INTEGER myThid
57 CEndOfInterface
58
59 C == Local variables ==
60 C I, J, K, jMin, jMax, iB - Loop counters and extents
61 C bi, bj
62 C biS, bjS - South tile indices
63 C biN, bjN - North tile indices
64 C eBl - Current exchange buffer level
65 C theProc, theTag, theType, - Variables used in message building
66 C theSize
67 C southCommMode - Working variables holding type
68 C northCommMode of communication a particular
69 C tile face uses.
70 INTEGER I, J, K, jMin, jMax, iMin, iMax, iB
71 INTEGER bi, bj, biS, bjS, biN, bjN
72 INTEGER eBl
73 INTEGER northCommMode
74 INTEGER southCommMode
75
76 #ifdef ALLOW_USE_MPI
77 INTEGER theProc, theTag, theType, theSize, mpiRc
78 #endif
79
80 C-- Write data to exchange buffer
81 C Various actions are possible depending on the communication mode
82 C as follows:
83 C Mode Action
84 C -------- ---------------------------
85 C COMM_NONE Do nothing
86 C
87 C COMM_MSG Message passing communication ( e.g. MPI )
88 C Fill south send buffer from this tile.
89 C Send data with tag identifying tile and direction.
90 C Fill north send buffer from this tile.
91 C Send data with tag identifying tile and direction.
92 C
93 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
94 C Fill south receive buffer of south-neighbor tile
95 C Fill north receive buffer of north-neighbor tile
96 C Sync. memory
97 C Write data-ready Ack for north edge of south-neighbor
98 C tile
99 C Write data-ready Ack for south edge of north-neighbor
100 C tile
101 C Sync. memory
102 C
103 DO bj=myByLo(myThid),myByHi(myThid)
104 DO bi=myBxLo(myThid),myBxHi(myThid)
105
106 ebL = exchangeBufLevel(1,bi,bj)
107 southCommMode = _tileCommModeS(bi,bj)
108 northCommMode = _tileCommModeN(bi,bj)
109 biS = _tileBiS(bi,bj)
110 bjS = _tileBjS(bi,bj)
111 biN = _tileBiN(bi,bj)
112 bjN = _tileBjN(bi,bj)
113 iMin = 1
114 iMax = sNx
115 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
116 iMin = 1-exchWidthX
117 iMax = sNx+exchWidthX
118 ENDIF
119
120
121 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
122 c >>>>>>>>>>>>>>>>>>> FORWARD RUN <<<<<<<<<<<<<<<<<<<
123 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
124
125 C o Send or Put south edge
126 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
127 jMin = 1
128 jMax = 1+exchWidthY-1
129 IF ( southCommMode .EQ. COMM_MSG ) THEN
130 iB = 0
131 DO K=1,myNz
132 DO J=jMin,jMax
133 DO I=iMin,iMax
134 iB = iB + 1
135 southSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
136 ENDDO
137 ENDDO
138 ENDDO
139 C Send the data
140 #ifdef ALLOW_USE_MPI
141 #ifndef ALWAYS_USE_MPI
142 IF ( usingMPI ) THEN
143 #endif
144 theProc = tilePidS(bi,bj)
145 theTag = _tileTagSendS(bi,bj)
146 theSize = iB
147 theType = MPI_DOUBLE_PRECISION
148 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
149 CALL MPI_Isend(southSendBuf_RX(1,eBl,bi,bj), theSize, theType,
150 & theProc, theTag, MPI_COMM_MODEL,
151 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc)
152 #ifndef ALWAYS_USE_MPI
153 ENDIF
154 #endif
155 #endif /* ALLOW_USE_MPI */
156 northRecvAck(eBl,biS,bjS) = 1.
157 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
158 iB = 0
159 DO K=1,myNz
160 DO J=jMin,jMax
161 DO I=iMin,iMax
162 iB = iB + 1
163 northRecvBuf_RX(iB,eBl,biS,bjS) = array(I,J,K,bi,bj)
164 ENDDO
165 ENDDO
166 ENDDO
167 ELSEIF ( southCommMode .NE. COMM_NONE
168 & .AND. southCommMode .NE. COMM_GET ) THEN
169 STOP ' S/R EXCH: Invalid commS mode.'
170 ENDIF
171
172 C o Send or Put north edge
173 jMin = sNy-exchWidthY+1
174 jMax = sNy
175 IF ( northCommMode .EQ. COMM_MSG ) THEN
176 iB = 0
177 DO K=1,myNz
178 DO J=jMin,jMax
179 DO I=iMin,iMax
180 iB = iB + 1
181 northSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
182 ENDDO
183 ENDDO
184 ENDDO
185 C Send the data
186 #ifdef ALLOW_USE_MPI
187 #ifndef ALWAYS_USE_MPI
188 IF ( usingMPI ) THEN
189 #endif
190 theProc = tilePidN(bi,bj)
191 theTag = _tileTagSendN(bi,bj)
192 theSize = iB
193 theType = MPI_DOUBLE_PRECISION
194 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
195 CALL MPI_Isend(northSendBuf_RX(1,eBl,bi,bj), theSize, theType,
196 & theProc, theTag, MPI_COMM_MODEL,
197 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc )
198 #ifndef ALWAYS_USE_MPI
199 ENDIF
200 #endif
201 #endif /* ALLOW_USE_MPI */
202 southRecvAck(eBl,biN,bjN) = 1.
203 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
204 iB = 0
205 DO K=1,myNz
206 DO J=jMin,jMax
207 DO I=iMin,iMax
208 iB = iB + 1
209 southRecvBuf_RX(iB,eBl,biN,bjN) = array(I,J,K,bi,bj)
210 ENDDO
211 ENDDO
212 ENDDO
213 ELSEIF ( northCommMode .NE. COMM_NONE
214 & .AND. northCommMode .NE. COMM_GET ) THEN
215 STOP ' S/R EXCH: Invalid commN mode.'
216 ENDIF
217
218 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
219 c >>>>>>>>>>>>>>>>>>> ADJOINT RUN <<<<<<<<<<<<<<<<<<<
220 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
221
222 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
223 jMin = 1-exchWidthY
224 jMax = 0
225 IF ( southCommMode .EQ. COMM_MSG ) THEN
226 iB = 0
227 DO K=1,myNz
228 DO J=jMin,jMax
229 DO I=iMin,iMax
230 iB = iB + 1
231 southSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
232 array(I,J,K,bi,bj) = 0.0
233 ENDDO
234 ENDDO
235 ENDDO
236 C Send the data
237 #ifdef ALLOW_USE_MPI
238 #ifndef ALWAYS_USE_MPI
239 IF ( usingMPI ) THEN
240 #endif
241 theProc = tilePidS(bi,bj)
242 theTag = _tileTagSendS(bi,bj)
243 theSize = iB
244 theType = MPI_DOUBLE_PRECISION
245 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
246 CALL MPI_Isend(southSendBuf_RX(1,eBl,bi,bj), theSize, theType,
247 & theProc, theTag, MPI_COMM_MODEL,
248 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc)
249 #ifndef ALWAYS_USE_MPI
250 ENDIF
251 #endif
252 #endif /* ALLOW_USE_MPI */
253 northRecvAck(eBl,biS,bjS) = 1.
254 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
255 iB = 0
256 DO K=1,myNz
257 DO J=jMin,jMax
258 DO I=iMin,iMax
259 iB = iB + 1
260 northRecvBuf_RX(iB,eBl,biS,bjS) = array(I,J,K,bi,bj)
261 array(I,J,K,bi,bj) = 0.0
262 ENDDO
263 ENDDO
264 ENDDO
265 ELSEIF ( southCommMode .NE. COMM_NONE
266 & .AND. southCommMode .NE. COMM_GET ) THEN
267 STOP ' S/R EXCH: Invalid commS mode.'
268 ENDIF
269
270 C o Send or Put north edge
271 jMin = sNy+1
272 jMax = sNy+exchWidthY
273 IF ( northCommMode .EQ. COMM_MSG ) THEN
274 iB = 0
275 DO K=1,myNz
276 DO J=jMin,jMax
277 DO I=iMin,iMax
278 iB = iB + 1
279 northSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
280 array(I,J,K,bi,bj) = 0.0
281 ENDDO
282 ENDDO
283 ENDDO
284 C Send the data
285 #ifdef ALLOW_USE_MPI
286 #ifndef ALWAYS_USE_MPI
287 IF ( usingMPI ) THEN
288 #endif
289 theProc = tilePidN(bi,bj)
290 theTag = _tileTagSendN(bi,bj)
291 theSize = iB
292 theType = MPI_DOUBLE_PRECISION
293 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
294 CALL MPI_Isend(northSendBuf_RX(1,eBl,bi,bj), theSize, theType,
295 & theProc, theTag, MPI_COMM_MODEL,
296 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc )
297 #ifndef ALWAYS_USE_MPI
298 ENDIF
299 #endif
300 #endif /* ALLOW_USE_MPI */
301 southRecvAck(eBl,biN,bjN) = 1.
302 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
303 iB = 0
304 DO K=1,myNz
305 DO J=jMin,jMax
306 DO I=iMin,iMax
307 iB = iB + 1
308 southRecvBuf_RX(iB,eBl,biN,bjN) = array(I,J,K,bi,bj)
309 array(I,J,K,bi,bj) = 0.0
310 ENDDO
311 ENDDO
312 ENDDO
313 ELSEIF ( northCommMode .NE. COMM_NONE
314 & .AND. northCommMode .NE. COMM_GET ) THEN
315 STOP ' S/R EXCH: Invalid commN mode.'
316 ENDIF
317 endif
318 ENDDO
319 ENDDO
320
321 C-- Signal completetion ( making sure system-wide memory state is
322 C-- consistent ).
323
324 C ** NOTE ** We are relying on being able to produce strong-ordered
325 C memory semantics here. In other words we assume that there is a
326 C mechanism which can ensure that by the time the Ack is seen the
327 C overlap region data that will be exchanged is up to date.
328 IF ( exchNeedsMemSync ) CALL MEMSYNC
329
330 DO bj=myByLo(myThid),myByHi(myThid)
331 DO bi=myBxLo(myThid),myBxHi(myThid)
332 ebL = exchangeBufLevel(1,bi,bj)
333 biS = _tileBiS(bi,bj)
334 bjS = _tileBjS(bi,bj)
335 biN = _tileBiN(bi,bj)
336 bjN = _tileBjN(bi,bj)
337 southCommMode = _tileCommModeS(bi,bj)
338 northCommMode = _tileCommModeN(bi,bj)
339 IF ( southCommMode .EQ. COMM_PUT ) northRecvAck(eBl,biS,bjS) = 1.
340 IF ( northCommMode .EQ. COMM_PUT ) southRecvAck(eBl,biN,bjN) = 1.
341 IF ( southCommMode .EQ. COMM_GET ) northRecvAck(eBl,biS,bjS) = 1.
342 IF ( northCommMode .EQ. COMM_GET ) southRecvAck(eBl,biN,bjN) = 1.
343 ENDDO
344 ENDDO
345
346 C-- Make sure "ack" setting is seen system-wide.
347 C Here strong-ordering is not an issue but we want to make
348 C sure that processes that might spin on the above Ack settings
349 C will see the setting.
350 C ** NOTE ** On some machines we wont spin on the Ack setting
351 C ( particularly the T90 ), instead we will use s system barrier.
352 C On the T90 the system barrier is very fast and switches out the
353 C thread while it waits. On most machines the system barrier
354 C is much too slow and if we own the machine and have one thread
355 C per process preemption is not a problem.
356 IF ( exchNeedsMemSync ) CALL MEMSYNC
357
358 RETURN
359 END

  ViewVC Help
Powered by ViewVC 1.1.22