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

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

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


Revision 1.6 - (show annotations) (download)
Sun Feb 4 14:38:43 2001 UTC (23 years, 4 months ago) by cnh
Branch: MAIN
CVS Tags: checkpoint38, checkpoint37, checkpoint36, checkpoint35, c37_adj
Branch point for: pre38
Changes since 1.5: +2 -1 lines
Made sure each .F and .h file had
the CVS keywords Header and Name at its start.
Most had header but very few currently have Name, so
lots of changes!

1 C $Header: /u/gcmpack/models/MITgcmUV/eesupp/src/exch_control.F,v 1.5 2001/01/29 20:00:14 heimbach Exp $
2 C $Name: $
3
4 C MITgcmUV Exchange routine
5 C -------------------------
6 C These routines include support for arrays with different
7 C overlap extents and a mechanism to allow reverse mode
8 C exchanges for adjoint based minimisation experiments.
9 C Differing extents for array overlap regions allows for example
10 C the conjugate gradient solver to be optimised for edge
11 C exchages of width one whilst for Shapiro filtered
12 C atmospheric fileds overlap regions of 8 or more can
13 C be defined.
14 C Another important new feature is a tile by tile definition
15 C of the class of exchange operation used to update the
16 C tile. This provides support for partially tiled regular
17 C domains where land-filled tiles are eliminated.
18 C Communication between tiles
19 C can be based on any of
20 C 1. message passing.
21 C 2. writes to remote memory.
22 C 3. direct reads from remote tiles.
23 C The class of communication utilised is specified on a
24 C tile by tile basis. So that one face of a tile can
25 C exchange via MPI, another via UMP, another via shared
26 C memory and another not at all. The only requirement is that
27 C of symmetry i.e. if one tile sends its data to another tile via
28 C some mechanism the "sent to" tile must receive the data by the
29 C same mechanism. There is no support for multiple communication
30 C channels for a single tile face.
31 C To support this a tile has the following attributes associated
32 C with it:
33 C tileNo - A unique number identifying the tile
34 C tileNoW - tileNo for the tile to my west
35 C tileNoN - tileNo for the tile to my north
36 C tileNoS - tileNo for the tile to my south
37 C tileNoE - tileNo for the tile to my east
38 C tilePid - Process id for this tile
39 C tilePidW - Process id for tile to west
40 C tilePidE - Process id for tile to east
41 C tilePidN - Process id for tile to north
42 C tilePidS - Process id for tile to south
43 C tileCommModeW - Style of communication used to west
44 C tileCommModeE - Style of communication used to east
45 C tileCommModeN - Style of communication used to north
46 C tileCommModeS - Style of communication used to south
47 C tileTagSendW - Tag for identifying send from tiles west
48 C communication "channel".
49 C tileTagSendE - Tag for identifying send from tiles east
50 C communication "channel".
51 C tileTagSendN - Tag for identifying send from tiles north
52 C communication "channel".
53 C tileTagSendS - Tag for identifying send from tiles south
54 C communication "channel".
55 C tileTagRecvW - Tag for identifying send from tiles west
56 C communication "channel".
57 C tileTagRecvE - Tag for identifying send from tiles east
58 C communication "channel".
59 C tileTagRecvN - Tag for identifying send from tiles north
60 C communication "channel".
61 C tileTagRecvS - Tag for identifying send from tiles south
62 C communication "channel".
63 C tileB[ij]W - bi and bj index for tile to west
64 C tileB[ij]E - bi and bj index for tile to east
65 C tileB[ij]N - bi and bj index for tile to north
66 C tileB[ij]S - bi and bj index for tile to south
67 C The code in here although intricate is fairly
68 C straightforward. There are four routines, one
69 C for each of the data patterns we wish to do overlap
70 C updates on - as listed below. Each routine has two
71 C parts. The first part does overlap updates to and from
72 C remote "processes", that is processes who do not truly
73 C share the address space of this process. This part
74 C requires a facility like MPI, CRAY shmem, Memory Channel UMP,
75 C VMMC VIA. In the case of a simple
76 C serial execution nothing happens in this part.
77 C The second part of each routine does the true shared memory
78 C overlap copying i.e. copying from one part of array phi
79 C to another part. This part is always active, in the case
80 C of a single threaded messaging code, however, this part
81 C will not do any copies as all edges will be flagged as using
82 C for example MPI.
83 C
84
85
86 CStartOfInterface
87 SUBROUTINE EXCH_RL(
88 U array,
89 I myOLw, myOLe, myOLs, myOLn, myNz,
90 I exchWidthX, exchWidthY,
91 I simulationMode, cornerMode, myThid )
92 C /==========================================================\
93 C | SUBROUTINE EXCH_RL |
94 C | o Control edge exchanges for RL array. |
95 C |==========================================================|
96 C | |
97 C | Controlling routine for exchange of XY edges of an array |
98 C | distributed in X and Y. The routine interfaces to |
99 C | communication routines that can use messages passing |
100 C | exchanges, put type exchanges or get type exchanges. |
101 C | This allows anything from MPI to raw memory channel to |
102 C | memmap segments to be used as a inter-process and/or |
103 C | inter-thread communiation and synchronisation |
104 C | mechanism. |
105 C | Notes -- |
106 C | 1. Some low-level mechanisms such as raw memory-channel |
107 C | or SGI/CRAY shmem put do not have direct Fortran bindings|
108 C | and are invoked through C stub routines. |
109 C | 2. Although this routine is fairly general but it does |
110 C | require nSx and nSy are the same for all innvocations. |
111 C | There are many common data structures ( myByLo, |
112 C | westCommunicationMode, mpiIdW etc... ) tied in with |
113 C | (nSx,nSy). To support arbitray nSx and nSy would require |
114 C | general forms of these. |
115 C | |
116 C \==========================================================/
117 IMPLICIT NONE
118
119 C == Global data ==
120 #include "SIZE.h"
121 #include "EEPARAMS.h"
122 #include "EESUPPORT.h"
123 #include "EXCH.h"
124
125 C == Routine arguments ==
126 C array - Array with edges to exchange.
127 C myOLw - West, East, North and South overlap region sizes.
128 C myOLe
129 C myOLn
130 C myOLs
131 C exchWidthX - Width of data region exchanged in X.
132 C exchWidthY - Width of data region exchanged in Y.
133 C Note --
134 C 1. In theory one could have a send width and
135 C a receive width for each face of each tile. The only
136 C restriction woul be that the send width of one
137 C face should equal the receive width of the sent to
138 C tile face. Dont know if this would be useful. I
139 C have left it out for now as it requires additional
140 C bookeeping.
141 C simulationMode - Forward or reverse mode exchange ( provides
142 C support for adjoint integration of code. )
143 C cornerMode - Flag indicating whether corner updates are
144 C needed.
145 C myThid - Thread number of this instance of S/R EXCH...
146 INTEGER myOLw
147 INTEGER myOLe
148 INTEGER myOLs
149 INTEGER myOLn
150 INTEGER myNz
151 INTEGER exchWidthX
152 INTEGER exchWidthY
153 INTEGER simulationMode
154 INTEGER cornerMode
155 INTEGER myThid
156 _RL array(1-myOLw:sNx+myOLe,
157 & 1-myOLs:sNy+myOLn,
158 & myNZ, nSx, nSy)
159 CEndOfInterface
160
161 C == Local variables ==
162 C theSimulationMode - Holds working copy of simulation mode
163 C theCornerMode - Holds working copy of corner mode
164 INTEGER theSimulationMode
165 INTEGER theCornerMode
166 INTEGER I,J,K,bi,bj
167
168 theSimulationMode = simulationMode
169 theCornerMode = cornerMode
170
171 C-- Error checks
172 IF ( exchWidthX .GT. myOLw )
173 & STOP ' S/R EXCH_RL: exchWidthX .GT. myOLw'
174 IF ( exchWidthX .GT. myOLe )
175 & STOP ' S/R EXCH_RL: exchWidthX .GT. myOLe'
176 IF ( exchWidthY .GT. myOLs )
177 & STOP ' S/R EXCH_RL: exchWidthY .GT. myOLs'
178 IF ( exchWidthY .GT. myOLn )
179 & STOP ' S/R EXCH_RL: exchWidthY .GT. myOLn'
180 IF ( myOLw .GT. MAX_OLX_EXCH )
181 & STOP ' S/R EXCH_RL: myOLw .GT. MAX_OLX_EXCH'
182 IF ( myOLe .GT. MAX_OLX_EXCH )
183 & STOP ' S/R EXCH_RL: myOLe .GT. MAX_OLX_EXCH'
184 IF ( myOLn .GT. MAX_OLX_EXCH )
185 & STOP ' S/R EXCH_RL: myOLn .GT. MAX_OLY_EXCH'
186 IF ( myOLs .GT. MAX_OLY_EXCH )
187 & STOP ' S/R EXCH_RL: myOLs .GT. MAX_OLY_EXCH'
188 IF ( myNZ .GT. MAX_NR_EXCH )
189 & STOP ' S/R EXCH_RL: myNZ .GT. MAX_NR_EXCH '
190 IF ( theSimulationMode .NE. FORWARD_SIMULATION
191 & .AND. theSimulationMode .NE. REVERSE_SIMULATION
192 & ) STOP ' S/R EXCH_RL: Unrecognised simulationMode '
193 IF ( theCornerMode .NE. EXCH_IGNORE_CORNERS
194 & .AND. theCornerMode .NE. EXCH_UPDATE_CORNERS
195 & ) STOP ' S/R EXCH_RL: Unrecognised cornerMode '
196
197 C-- Cycle edge buffer level
198 CALL EXCH_CYCLE_EBL( myThid )
199
200 IF ( theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
201 C-- "Put" east and west edges.
202 CALL EXCH_RL_SEND_PUT_X( array,
203 I myOLw, myOLe, myOLs, myOLn, myNz,
204 I exchWidthX, exchWidthY,
205 I theSimulationMode, theCornerMode, myThid )
206
207 C-- If corners are important then sync and update east and west edges
208 C-- before doing north and south exchanges.
209 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
210 CALL EXCH_RL_RECV_GET_X( array,
211 I myOLw, myOLe, myOLs, myOLn, myNz,
212 I exchWidthX, exchWidthY,
213 I theSimulationMode, theCornerMode, myThid )
214 ENDIF
215
216 C "Put" north and south edges.
217 CALL EXCH_RL_SEND_PUT_Y( array,
218 I myOLw, myOLe, myOLs, myOLn, myNz,
219 I exchWidthX, exchWidthY,
220 I theSimulationMode, theCornerMode, myThid )
221
222
223 C-- Sync and update north, south (and east, west if corner updating
224 C-- not active).
225 IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
226 CALL EXCH_RL_RECV_GET_X( array,
227 I myOLw, myOLe, myOLs, myOLn, myNz,
228 I exchWidthX, exchWidthY,
229 I theSimulationMode, theCornerMode, myThid )
230 ENDIF
231 CALL EXCH_RL_RECV_GET_Y( array,
232 I myOLw, myOLe, myOLs, myOLn, myNz,
233 I exchWidthX, exchWidthY,
234 I theSimulationMode, theCornerMode, myThid )
235 ENDIF
236
237 IF ( theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
238 C "Put" north and south edges.
239 CALL EXCH_RL_SEND_PUT_Y( array,
240 I myOLw, myOLe, myOLs, myOLn, myNz,
241 I exchWidthX, exchWidthY,
242 I theSimulationMode, theCornerMode, myThid )
243 C-- If corners are important then sync and update east and west edges
244 C-- before doing north and south exchanges.
245 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
246 CALL EXCH_RL_RECV_GET_Y( array,
247 I myOLw, myOLe, myOLs, myOLn, myNz,
248 I exchWidthX, exchWidthY,
249 I theSimulationMode, theCornerMode, myThid )
250 ENDIF
251 C-- "Put" east and west edges.
252 CALL EXCH_RL_SEND_PUT_X( array,
253 I myOLw, myOLe, myOLs, myOLn, myNz,
254 I exchWidthX, exchWidthY,
255 I theSimulationMode, theCornerMode, myThid )
256 C-- Sync and update east, west (and north, south if corner updating
257 C-- not active).
258 IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
259 CALL EXCH_RL_RECV_GET_Y( array,
260 I myOLw, myOLe, myOLs, myOLn, myNz,
261 I exchWidthX, exchWidthY,
262 I theSimulationMode, theCornerMode, myThid )
263 ENDIF
264 CALL EXCH_RL_RECV_GET_X( array,
265 I myOLw, myOLe, myOLs, myOLn, myNz,
266 I exchWidthX, exchWidthY,
267 I theSimulationMode, theCornerMode, myThid )
268 ENDIF
269
270
271
272
273 C Special case for zonal average model i.e. case where sNx == 1
274 C In this case a forward mode exchange simply sets array to
275 C the i=1 value for all i.
276 IF ( sNx .EQ. 1 ) THEN
277 DO bj=myByLo(myThid),myByHi(myThid)
278 DO bi=myBxLo(myThid),myBxHi(myThid)
279 DO K = 1,myNz
280 DO J = 1-myOLs,sNy+myOLn
281 DO I = 1-myOLw,sNx+myOLe
282 array(I,J,K,bi,bj) = array(sNx,J,K,bi,bj)
283 ENDDO
284 ENDDO
285 ENDDO
286 ENDDO
287 ENDDO
288 ENDIF
289
290 RETURN
291 END
292
293 CStartOfInterface
294 SUBROUTINE EXCH_RS(
295 U array,
296 I myOLw, myOLe, myOLs, myOLn, myNz,
297 I exchWidthX, exchWidthY,
298 I simulationMode, cornerMode, myThid )
299 C /==========================================================\
300 C | SUBROUTINE EXCH_RS |
301 C | o Control edge exchanges for RS array. |
302 C |==========================================================|
303 C | |
304 C | Controlling routine for exchange of XY edges of an array |
305 C | distributed in X and Y. The routine interfaces to |
306 C | communication routines that can use messages passing |
307 C | exchanges, put type exchanges or get type exchanges. |
308 C | This allows anything from MPI to raw memory channel to |
309 C | memmap segments to be used as a inter-process and/or |
310 C | inter-thread communiation and synchronisation |
311 C | mechanism. |
312 C | Notes -- |
313 C | 1. Some low-level mechanisms such as raw memory-channel |
314 C | or SGI/CRAY shmem put do not have direct Fortran bindings|
315 C | and are invoked through C stub routines. |
316 C | 2. Although this routine is fairly general but it does |
317 C | require nSx and nSy are the same for all innvocations. |
318 C | There are many common data structures ( myByLo, |
319 C | westCommunicationMode, mpiIdW etc... ) tied in with |
320 C | (nSx,nSy). To support arbitray nSx and nSy would require |
321 C | general forms of these. |
322 C | |
323 C \==========================================================/
324 IMPLICIT NONE
325
326 C == Global data ==
327 #include "SIZE.h"
328 #include "EEPARAMS.h"
329 #include "EESUPPORT.h"
330 #include "EXCH.h"
331
332 C == Routine arguments ==
333 C array - Array with edges to exchange.
334 C myOLw - West, East, North and South overlap region sizes.
335 C myOLe
336 C myOLn
337 C myOLs
338 C exchWidthX - Width of data region exchanged in X.
339 C exchWidthY - Width of data region exchanged in Y.
340 C Note --
341 C 1. In theory one could have a send width and
342 C a receive width for each face of each tile. The only
343 C restriction woul be that the send width of one
344 C face should equal the receive width of the sent to
345 C tile face. Dont know if this would be useful. I
346 C have left it out for now as it requires additional
347 C bookeeping.
348 C simulationMode - Forward or reverse mode exchange ( provides
349 C support for adjoint integration of code. )
350 C cornerMode - Flag indicating whether corner updates are
351 C needed.
352 C myThid - Thread number of this instance of S/R EXCH...
353 INTEGER myOLw
354 INTEGER myOLe
355 INTEGER myOLs
356 INTEGER myOLn
357 INTEGER myNz
358 INTEGER exchWidthX
359 INTEGER exchWidthY
360 INTEGER simulationMode
361 INTEGER cornerMode
362 INTEGER myThid
363 _RS array(1-myOLw:sNx+myOLe,
364 & 1-myOLs:sNy+myOLn,
365 & myNZ, nSx, nSy)
366 CEndOfInterface
367
368 C == Local variables ==
369 C theSimulationMode - Holds working copy of simulation mode
370 C theCornerMode - Holds working copy of corner mode
371 INTEGER theSimulationMode
372 INTEGER theCornerMode
373 INTEGER I,J,K,bi,bj
374
375 theSimulationMode = simulationMode
376 theCornerMode = cornerMode
377
378 C-- Error checks
379 IF ( exchWidthX .GT. myOLw )
380 & STOP ' S/R EXCH_RS: exchWidthX .GT. myOLw'
381 IF ( exchWidthX .GT. myOLe )
382 & STOP ' S/R EXCH_RS: exchWidthX .GT. myOLe'
383 IF ( exchWidthY .GT. myOLs )
384 & STOP ' S/R EXCH_RS: exchWidthY .GT. myOLs'
385 IF ( exchWidthY .GT. myOLn )
386 & STOP ' S/R EXCH_RS: exchWidthY .GT. myOLn'
387 IF ( myOLw .GT. MAX_OLX_EXCH )
388 & STOP ' S/R EXCH_RS: myOLw .GT. MAX_OLX_EXCH'
389 IF ( myOLe .GT. MAX_OLX_EXCH )
390 & STOP ' S/R EXCH_RS: myOLe .GT. MAX_OLX_EXCH'
391 IF ( myOLn .GT. MAX_OLX_EXCH )
392 & STOP ' S/R EXCH_RS: myOLn .GT. MAX_OLY_EXCH'
393 IF ( myOLs .GT. MAX_OLY_EXCH )
394 & STOP ' S/R EXCH_RS: myOLs .GT. MAX_OLY_EXCH'
395 IF ( myNZ .GT. MAX_NR_EXCH )
396 & STOP ' S/R EXCH_RS: myNZ .GT. MAX_NR_EXCH '
397 IF ( theSimulationMode .NE. FORWARD_SIMULATION
398 & .AND. theSimulationMode .NE. REVERSE_SIMULATION
399 & ) STOP ' S/R EXCH_RS: Unrecognised simulationMode '
400 IF ( theCornerMode .NE. EXCH_IGNORE_CORNERS
401 & .AND. theCornerMode .NE. EXCH_UPDATE_CORNERS
402 & ) STOP ' S/R EXCH_RS: Unrecognised cornerMode '
403
404 C-- Cycle edge buffer level
405 CALL EXCH_CYCLE_EBL( myThid )
406
407 IF ( theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
408 C-- "Put" east and west edges.
409 CALL EXCH_RS_SEND_PUT_X( array,
410 I myOLw, myOLe, myOLs, myOLn, myNz,
411 I exchWidthX, exchWidthY,
412 I theSimulationMode, theCornerMode, myThid )
413 C-- If corners are important then sync and update east and west edges
414 C-- before doing north and south exchanges.
415 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
416 CALL EXCH_RS_RECV_GET_X( array,
417 I myOLw, myOLe, myOLs, myOLn, myNz,
418 I exchWidthX, exchWidthY,
419 I theSimulationMode, theCornerMode, myThid )
420 ENDIF
421 C "Put" north and south edges.
422 CALL EXCH_RS_SEND_PUT_Y( array,
423 I myOLw, myOLe, myOLs, myOLn, myNz,
424 I exchWidthX, exchWidthY,
425 I theSimulationMode, theCornerMode, myThid )
426 C-- Sync and update north, south (and east, west if corner updating
427 C-- not active).
428 IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
429 CALL EXCH_RS_RECV_GET_X( array,
430 I myOLw, myOLe, myOLs, myOLn, myNz,
431 I exchWidthX, exchWidthY,
432 I theSimulationMode, theCornerMode, myThid )
433 ENDIF
434 CALL EXCH_RS_RECV_GET_Y( array,
435 I myOLw, myOLe, myOLs, myOLn, myNz,
436 I exchWidthX, exchWidthY,
437 I theSimulationMode, theCornerMode, myThid )
438 ENDIF
439
440 IF ( theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
441 C "Put" north and south edges.
442 CALL EXCH_RS_SEND_PUT_Y( array,
443 I myOLw, myOLe, myOLs, myOLn, myNz,
444 I exchWidthX, exchWidthY,
445 I theSimulationMode, theCornerMode, myThid )
446 C-- If corners are important then sync and update east and west edges
447 C-- before doing north and south exchanges.
448 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
449 CALL EXCH_RS_RECV_GET_Y( array,
450 I myOLw, myOLe, myOLs, myOLn, myNz,
451 I exchWidthX, exchWidthY,
452 I theSimulationMode, theCornerMode, myThid )
453 ENDIF
454 C-- "Put" east and west edges.
455 CALL EXCH_RS_SEND_PUT_X( array,
456 I myOLw, myOLe, myOLs, myOLn, myNz,
457 I exchWidthX, exchWidthY,
458 I theSimulationMode, theCornerMode, myThid )
459 C-- Sync and update east, west (and north, south if corner updating
460 C-- not active).
461 IF ( theCornerMode .NE. EXCH_UPDATE_CORNERS ) THEN
462 CALL EXCH_RS_RECV_GET_Y( array,
463 I myOLw, myOLe, myOLs, myOLn, myNz,
464 I exchWidthX, exchWidthY,
465 I theSimulationMode, theCornerMode, myThid )
466 ENDIF
467 CALL EXCH_RS_RECV_GET_X( array,
468 I myOLw, myOLe, myOLs, myOLn, myNz,
469 I exchWidthX, exchWidthY,
470 I theSimulationMode, theCornerMode, myThid )
471 ENDIF
472 C Special case for zonal average model i.e. case where sNx == 1
473 C In this case a forward mode exchange simply sets array to
474 C the i=1 value for all i.
475 IF ( sNx .EQ. 1 ) THEN
476 DO bj=myByLo(myThid),myByHi(myThid)
477 DO bi=myBxLo(myThid),myBxHi(myThid)
478 DO K = 1,myNz
479 DO J = 1-myOLs,sNy+myOLn
480 DO I = 1-myOLw,sNx+myOLe
481 array(I,J,K,bi,bj) = array(sNx,J,K,bi,bj)
482 ENDDO
483 ENDDO
484 ENDDO
485 ENDDO
486 ENDDO
487 ENDIF
488
489 RETURN
490 END

  ViewVC Help
Powered by ViewVC 1.1.22