/[MITgcm]/MITgcm/eesupp/src/exch_send_put_x.F
ViewVC logotype

Contents of /MITgcm/eesupp/src/exch_send_put_x.F

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


Revision 1.2 - (show annotations) (download)
Mon Mar 22 17:37:43 1999 UTC (25 years, 2 months ago) by adcroft
Branch: MAIN
CVS Tags: checkpoint23, checkpoint24, checkpoint26, branch-atmos-merge-start, checkpoint27, checkpoint33, checkpoint32, checkpoint31, checkpoint30, branch-atmos-merge-zonalfilt, branch-atmos-merge-shapiro, checkpoint28, checkpoint29, branch-atmos-merge-phase5, branch-atmos-merge-phase4, branch-atmos-merge-phase7, branch-atmos-merge-phase6, branch-atmos-merge-phase1, checkpoint25, branch-atmos-merge-phase3, branch-atmos-merge-phase2, checkpoint20, branch-atmos-merge-freeze, checkpoint21, checkpoint22
Branch point for: branch-atmos-merge
Changes since 1.1: +5 -5 lines
Modified MPI calls to allow use in "coupled" context.
 o created COMMON block to contain MPI communicator MPI_COMM_MODEL
 o globally replaced MPI_COMM_World with MPI_COMM_MODEL
 o set MPI_COMM_MODEL equal to MPI_COMM_World in eeboot_minimal.F

1 C $Header: /u/gcmpack/models/MITgcmUV/eesupp/src/exch_send_put_x.F,v 1.1 1998/09/29 18:53:45 cnh Exp $
2 #include "CPP_EEOPTIONS.h"
3
4 SUBROUTINE EXCH_RL_SEND_PUT_X( array,
5 I myOLw, myOLe, myOLs, myOLn, myNz,
6 I exchWidthX, exchWidthY,
7 I thesimulationMode, thecornerMode, myThid )
8 C /==========================================================\
9 C | SUBROUTINE EXCH_RL_SEND_PUT_X |
10 C | o "Send" or "put" X edges for RL array. |
11 C |==========================================================|
12 C | Routine that invokes actual message passing send or |
13 C | direct "put" of data to update X faces of an XY[R] array.|
14 C \==========================================================/
15 IMPLICIT NONE
16
17 C == Global variables ==
18 #include "SIZE.h"
19 #include "EEPARAMS.h"
20 #include "EESUPPORT.h"
21 #include "EXCH.h"
22 C == Routine arguments ==
23 C array - Array with edges to exchange.
24 C myOLw - West, East, North and South overlap region sizes.
25 C myOLe
26 C myOLn
27 C myOLs
28 C exchWidthX - Width of data region exchanged.
29 C exchWidthY
30 C theSimulationMode - Forward or reverse mode exchange ( provides
31 C support for adjoint integration of code. )
32 C theCornerMode - Flag indicating whether corner updates are
33 C needed.
34 C myThid - Thread number of this instance of S/R EXCH...
35 C eBl - Edge buffer level
36 INTEGER myOLw
37 INTEGER myOLe
38 INTEGER myOLs
39 INTEGER myOLn
40 INTEGER myNz
41 _RL array(1-myOLw:sNx+myOLe,
42 & 1-myOLs:sNy+myOLn,
43 & myNZ, nSx, nSy)
44 INTEGER exchWidthX
45 INTEGER exchWidthY
46 INTEGER theSimulationMode
47 INTEGER theCornerMode
48 INTEGER myThid
49 CEndOfInterface
50
51 C == Local variables ==
52 C I, J, K, iMin, iMax, iB - Loop counters and extents
53 C bi, bj
54 C biW, bjW - West tile indices
55 C biE, bjE - East tile indices
56 C eBl - Current exchange buffer level
57 C theProc, theTag, theType, - Variables used in message building
58 C theSize
59 C westCommMode - Working variables holding type
60 C eastCommMode of communication a particular
61 C tile face uses.
62 INTEGER I, J, K, iMin, iMax, iB
63 INTEGER bi, bj, biW, bjW, biE, bjE
64 INTEGER eBl
65 INTEGER westCommMode
66 INTEGER eastCommMode
67
68 #ifdef ALLOW_USE_MPI
69 INTEGER theProc, theTag, theType, theSize, mpiRc
70 #endif
71 C-- Write data to exchange buffer
72 C Various actions are possible depending on the communication mode
73 C as follows:
74 C Mode Action
75 C -------- ---------------------------
76 C COMM_NONE Do nothing
77 C
78 C COMM_MSG Message passing communication ( e.g. MPI )
79 C Fill west send buffer from this tile.
80 C Send data with tag identifying tile and direction.
81 C Fill east send buffer from this tile.
82 C Send data with tag identifying tile and direction.
83 C
84 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
85 C Fill east receive buffer of west-neighbor tile
86 C Fill west receive buffer of east-neighbor tile
87 C Sync. memory
88 C Write data-ready Ack for east edge of west-neighbor
89 C tile
90 C Write data-ready Ack for west edge of east-neighbor
91 C tile
92 C Sync. memory
93 C
94 DO bj=myByLo(myThid),myByHi(myThid)
95 DO bi=myBxLo(myThid),myBxHi(myThid)
96
97 ebL = exchangeBufLevel(1,bi,bj)
98 westCommMode = _tileCommModeW(bi,bj)
99 eastCommMode = _tileCommModeE(bi,bj)
100 biE = _tileBiE(bi,bj)
101 bjE = _tileBjE(bi,bj)
102 biW = _tileBiW(bi,bj)
103 bjW = _tileBjW(bi,bj)
104
105 C o Send or Put west edge
106 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
107 iMin = 1
108 iMax = 1+exchWidthX-1
109 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
110 iMin = 1-exchWidthX
111 iMax = 0
112 ENDIF
113 IF ( westCommMode .EQ. COMM_MSG ) THEN
114 iB = 0
115 DO K=1,myNz
116 DO J=1,sNy
117 DO I=iMin,iMax
118 iB = iB + 1
119 westSendBuf_RL(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
120 ENDDO
121 ENDDO
122 ENDDO
123 C Send the data
124 #ifdef ALLOW_USE_MPI
125 #ifndef ALWAYS_USE_MPI
126 IF ( usingMPI ) THEN
127 #endif
128 theProc = tilePidW(bi,bj)
129 theTag = _tileTagSendW(bi,bj)
130 theSize = iB
131 theType = MPI_DOUBLE_PRECISION
132 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
133 CALL MPI_Isend(westSendBuf_RL(1,eBl,bi,bj), theSize, theType,
134 & theProc, theTag, MPI_COMM_MODEL,
135 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
136 #ifndef ALWAYS_USE_MPI
137 ENDIF
138 #endif
139 #endif /* ALLOW_USE_MPI */
140 eastRecvAck(eBl,biW,bjW) = 1.
141 ELSEIF ( westCommMode .EQ. COMM_PUT ) THEN
142 iB = 0
143 DO K=1,myNz
144 DO J=1,sNy
145 DO I=iMin,iMax
146 iB = iB + 1
147 eastRecvBuf_RL(iB,eBl,biW,bjW) = array(I,J,K,bi,bj)
148 ENDDO
149 ENDDO
150 ENDDO
151 ELSEIF ( westCommMode .NE. COMM_NONE
152 & .AND. westCommMode .NE. COMM_GET ) THEN
153 STOP ' S/R EXCH: Invalid commW mode.'
154 ENDIF
155
156 C o Send or Put east edge
157 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
158 iMin = sNx-exchWidthX+1
159 iMax = sNx
160 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
161 iMin = sNx+1
162 iMax = sNx+exchWidthX
163 ENDIF
164 IF ( eastCommMode .EQ. COMM_MSG ) THEN
165 iB = 0
166 DO K=1,myNz
167 DO J=1,sNy
168 DO I=iMin,iMax
169 iB = iB + 1
170 eastSendBuf_RL(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
171 ENDDO
172 ENDDO
173 ENDDO
174 C Send the data
175 #ifdef ALLOW_USE_MPI
176 #ifndef ALWAYS_USE_MPI
177 IF ( usingMPI ) THEN
178 #endif
179 theProc = tilePidE(bi,bj)
180 theTag = _tileTagSendE(bi,bj)
181 theSize = iB
182 theType = MPI_DOUBLE_PRECISION
183 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
184 CALL MPI_Isend(eastSendBuf_RL(1,eBl,bi,bj), theSize, theType,
185 & theProc, theTag, MPI_COMM_MODEL,
186 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
187 #ifndef ALWAYS_USE_MPI
188 ENDIF
189 #endif
190 #endif /* ALLOW_USE_MPI */
191 westRecvAck(eBl,biE,bjE) = 1.
192 ELSEIF ( eastCommMode .EQ. COMM_PUT ) THEN
193 iB = 0
194 DO K=1,myNz
195 DO J=1,sNy
196 DO I=iMin,iMax
197 iB = iB + 1
198 westRecvBuf_RL(iB,eBl,biE,bjE) = array(I,J,K,bi,bj)
199 ENDDO
200 ENDDO
201 ENDDO
202 ELSEIF ( eastCommMode .NE. COMM_NONE
203 & .AND. eastCommMode .NE. COMM_GET ) THEN
204 STOP ' S/R EXCH: Invalid commE mode.'
205 ENDIF
206
207 ENDDO
208 ENDDO
209
210 C-- Signal completetion ( making sure system-wide memory state is
211 C-- consistent ).
212
213 C ** NOTE ** We are relying on being able to produce strong-ordered
214 C memory semantics here. In other words we assume that there is a
215 C mechanism which can ensure that by the time the Ack is seen the
216 C overlap region data that will be exchanged is up to date.
217 IF ( exchNeedsMemSync ) CALL MEMSYNC
218
219 DO bj=myByLo(myThid),myByHi(myThid)
220 DO bi=myBxLo(myThid),myBxHi(myThid)
221 ebL = exchangeBufLevel(1,bi,bj)
222 biE = _tileBiE(bi,bj)
223 bjE = _tileBjE(bi,bj)
224 biW = _tileBiW(bi,bj)
225 bjW = _tileBjW(bi,bj)
226 westCommMode = _tileCommModeW(bi,bj)
227 eastCommMode = _tileCommModeE(bi,bj)
228 IF ( westCommMode .EQ. COMM_PUT ) eastRecvAck(eBl,biW,bjW) = 1.
229 IF ( eastCommMode .EQ. COMM_PUT ) westRecvAck(eBl,biE,bjE) = 1.
230 IF ( westCommMode .EQ. COMM_GET ) eastRecvAck(eBl,biW,bjW) = 1.
231 IF ( eastCommMode .EQ. COMM_GET ) westRecvAck(eBl,biE,bjE) = 1.
232 ENDDO
233 ENDDO
234
235 C-- Make sure "ack" setting is seen system-wide.
236 C Here strong-ordering is not an issue but we want to make
237 C sure that processes that might spin on the above Ack settings
238 C will see the setting.
239 C ** NOTE ** On some machines we wont spin on the Ack setting
240 C ( particularly the T90 ), instead we will use s system barrier.
241 C On the T90 the system barrier is very fast and switches out the
242 C thread while it waits. On most machines the system barrier
243 C is much too slow and if we own the machine and have one thread
244 C per process preemption is not a problem.
245 IF ( exchNeedsMemSync ) CALL MEMSYNC
246
247 RETURN
248 END
249
250 SUBROUTINE EXCH_RS_SEND_PUT_X( array,
251 I myOLw, myOLe, myOLs, myOLn, myNz,
252 I exchWidthX, exchWidthY,
253 I thesimulationMode, thecornerMode, myThid )
254 C /==========================================================\
255 C | SUBROUTINE EXCH_RS_SEND_PUT_X |
256 C | o "Send" or "put" X edges for RS array. |
257 C |==========================================================|
258 C | Routine that invokes actual message passing send or |
259 C | direct "put" of data to update X faces of an XY[R] array.|
260 C \==========================================================/
261 IMPLICIT NONE
262
263 C == Global variables ==
264 #include "SIZE.h"
265 #include "EEPARAMS.h"
266 #include "EESUPPORT.h"
267 #include "EXCH.h"
268 C == Routine arguments ==
269 C array - Array with edges to exchange.
270 C myOLw - West, East, North and South overlap region sizes.
271 C myOLe
272 C myOLn
273 C myOLs
274 C exchWidthX - Width of data region exchanged.
275 C exchWidthY
276 C theSimulationMode - Forward or reverse mode exchange ( provides
277 C support for adjoint integration of code. )
278 C theCornerMode - Flag indicating whether corner updates are
279 C needed.
280 C myThid - Thread number of this instance of S/R EXCH...
281 C eBl - Edge buffer level
282 INTEGER myOLw
283 INTEGER myOLe
284 INTEGER myOLs
285 INTEGER myOLn
286 INTEGER myNz
287 _RS array(1-myOLw:sNx+myOLe,
288 & 1-myOLs:sNy+myOLn,
289 & myNZ, nSx, nSy)
290 INTEGER exchWidthX
291 INTEGER exchWidthY
292 INTEGER theSimulationMode
293 INTEGER theCornerMode
294 INTEGER myThid
295 CEndOfInterface
296
297 C == Local variables ==
298 C I, J, K, iMin, iMax, iB - Loop counters and extents
299 C bi, bj
300 C biW, bjW - West tile indices
301 C biE, bjE - East tile indices
302 C eBl - Current exchange buffer level
303 C theProc, theTag, theType, - Variables used in message building
304 C theSize
305 C westCommMode - Working variables holding type
306 C eastCommMode of communication a particular
307 C tile face uses.
308 INTEGER I, J, K, iMin, iMax, iB
309 INTEGER bi, bj, biW, bjW, biE, bjE
310 INTEGER eBl
311 INTEGER westCommMode
312 INTEGER eastCommMode
313
314 #ifdef ALLOW_USE_MPI
315 INTEGER theProc, theTag, theType, theSize, mpiRc
316 #endif
317 C-- Write data to exchange buffer
318 C Various actions are possible depending on the communication mode
319 C as follows:
320 C Mode Action
321 C -------- ---------------------------
322 C COMM_NONE Do nothing
323 C
324 C COMM_MSG Message passing communication ( e.g. MPI )
325 C Fill west send buffer from this tile.
326 C Send data with tag identifying tile and direction.
327 C Fill east send buffer from this tile.
328 C Send data with tag identifying tile and direction.
329 C
330 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
331 C Fill east receive buffer of west-neighbor tile
332 C Fill west receive buffer of east-neighbor tile
333 C Sync. memory
334 C Write data-ready Ack for east edge of west-neighbor
335 C tile
336 C Write data-ready Ack for west edge of east-neighbor
337 C tile
338 C Sync. memory
339 C
340 DO bj=myByLo(myThid),myByHi(myThid)
341 DO bi=myBxLo(myThid),myBxHi(myThid)
342
343 ebL = exchangeBufLevel(1,bi,bj)
344 westCommMode = _tileCommModeW(bi,bj)
345 eastCommMode = _tileCommModeE(bi,bj)
346 biE = _tileBiE(bi,bj)
347 bjE = _tileBjE(bi,bj)
348 biW = _tileBiW(bi,bj)
349 bjW = _tileBjW(bi,bj)
350
351 C o Send or Put west edge
352 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
353 iMin = 1
354 iMax = 1+exchWidthX-1
355 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
356 iMin = 1-exchWidthX
357 iMax = 0
358 ENDIF
359 IF ( westCommMode .EQ. COMM_MSG ) THEN
360 iB = 0
361 DO K=1,myNz
362 DO J=1,sNy
363 DO I=iMin,iMax
364 iB = iB + 1
365 westSendBuf_RS(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
366 ENDDO
367 ENDDO
368 ENDDO
369 C Send the data
370 #ifdef ALLOW_USE_MPI
371 #ifndef ALWAYS_USE_MPI
372 IF ( usingMPI ) THEN
373 #endif
374 theProc = tilePidW(bi,bj)
375 theTag = _tileTagSendW(bi,bj)
376 theSize = iB
377 theType = MPI_DOUBLE_PRECISION
378 #ifdef RS_IS_REAL4
379 theType = MPI_REAL4
380 #endif
381 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
382 CALL MPI_Isend(westSendBuf_RS(1,eBl,bi,bj), theSize, theType,
383 & theProc, theTag, MPI_COMM_MODEL,
384 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
385 #ifndef ALWAYS_USE_MPI
386 ENDIF
387 #endif
388 #endif /* ALLOW_USE_MPI */
389 eastRecvAck(eBl,biW,bjW) = 1.
390 ELSEIF ( westCommMode .EQ. COMM_PUT ) THEN
391 iB = 0
392 DO K=1,myNz
393 DO J=1,sNy
394 DO I=iMin,iMax
395 iB = iB + 1
396 eastRecvBuf_RS(iB,eBl,biW,bjW) = array(I,J,K,bi,bj)
397 ENDDO
398 ENDDO
399 ENDDO
400 ELSEIF ( westCommMode .NE. COMM_NONE
401 & .AND. westCommMode .NE. COMM_GET ) THEN
402 STOP ' S/R EXCH: Invalid commW mode.'
403 ENDIF
404
405 C o Send or Put east edge
406 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
407 iMin = sNx-exchWidthX+1
408 iMax = sNx
409 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
410 iMin = sNx+1
411 iMax = sNx+exchWidthX
412 ENDIF
413 IF ( eastCommMode .EQ. COMM_MSG ) THEN
414 iB = 0
415 DO K=1,myNz
416 DO J=1,sNy
417 DO I=iMin,iMax
418 iB = iB + 1
419 eastSendBuf_RS(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
420 ENDDO
421 ENDDO
422 ENDDO
423 C Send the data
424 #ifdef ALLOW_USE_MPI
425 #ifndef ALWAYS_USE_MPI
426 IF ( usingMPI ) THEN
427 #endif
428 theProc = tilePidE(bi,bj)
429 theTag = _tileTagSendE(bi,bj)
430 theSize = iB
431 theType = MPI_DOUBLE_PRECISION
432 #ifdef RS_IS_REAL4
433 theType = MPI_REAL4
434 #endif
435 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
436 CALL MPI_Isend(eastSendBuf_RS(1,eBl,bi,bj), theSize, theType,
437 & theProc, theTag, MPI_COMM_MODEL,
438 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
439 #ifndef ALWAYS_USE_MPI
440 ENDIF
441 #endif
442 #endif /* ALLOW_USE_MPI */
443 westRecvAck(eBl,biE,bjE) = 1.
444 ELSEIF ( eastCommMode .EQ. COMM_PUT ) THEN
445 iB = 0
446 DO K=1,myNz
447 DO J=1,sNy
448 DO I=iMin,iMax
449 iB = iB + 1
450 westRecvBuf_RS(iB,eBl,biE,bjE) = array(I,J,K,bi,bj)
451 ENDDO
452 ENDDO
453 ENDDO
454 ELSEIF ( eastCommMode .NE. COMM_NONE
455 & .AND. eastCommMode .NE. COMM_GET ) THEN
456 STOP ' S/R EXCH: Invalid commE mode.'
457 ENDIF
458
459 ENDDO
460 ENDDO
461
462 C-- Signal completetion ( making sure system-wide memory state is
463 C-- consistent ).
464
465 C ** NOTE ** We are relying on being able to produce strong-ordered
466 C memory semantics here. In other words we assume that there is a
467 C mechanism which can ensure that by the time the Ack is seen the
468 C overlap region data that will be exchanged is up to date.
469 IF ( exchNeedsMemSync ) CALL MEMSYNC
470
471 DO bj=myByLo(myThid),myByHi(myThid)
472 DO bi=myBxLo(myThid),myBxHi(myThid)
473 ebL = exchangeBufLevel(1,bi,bj)
474 biE = _tileBiE(bi,bj)
475 bjE = _tileBjE(bi,bj)
476 biW = _tileBiW(bi,bj)
477 bjW = _tileBjW(bi,bj)
478 westCommMode = _tileCommModeW(bi,bj)
479 eastCommMode = _tileCommModeE(bi,bj)
480 IF ( westCommMode .EQ. COMM_PUT ) eastRecvAck(eBl,biW,bjW) = 1.
481 IF ( eastCommMode .EQ. COMM_PUT ) westRecvAck(eBl,biE,bjE) = 1.
482 IF ( westCommMode .EQ. COMM_GET ) eastRecvAck(eBl,biW,bjW) = 1.
483 IF ( eastCommMode .EQ. COMM_GET ) westRecvAck(eBl,biE,bjE) = 1.
484 ENDDO
485 ENDDO
486
487 C-- Make sure "ack" setting is seen system-wide.
488 C Here strong-ordering is not an issue but we want to make
489 C sure that processes that might spin on the above Ack settings
490 C will see the setting.
491 C ** NOTE ** On some machines we wont spin on the Ack setting
492 C ( particularly the T90 ), instead we will use s system barrier.
493 C On the T90 the system barrier is very fast and switches out the
494 C thread while it waits. On most machines the system barrier
495 C is much too slow and if we own the machine and have one thread
496 C per process preemption is not a problem.
497 IF ( exchNeedsMemSync ) CALL MEMSYNC
498
499 RETURN
500 END

  ViewVC Help
Powered by ViewVC 1.1.22