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

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

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


Revision 1.7 - (show annotations) (download)
Tue May 29 14:06:38 2001 UTC (22 years, 11 months ago) by adcroft
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +2 -2 lines
FILE REMOVED
Merge from branch pre38 :
 o Templating of exch* routines.

1 C $Header: /u/gcmpack/models/MITgcmUV/eesupp/src/exch_send_put_y.F,v 1.6 2001/05/14 21:31:42 heimbach Exp $
2 C $Name: $
3 #include "CPP_EEOPTIONS.h"
4
5 SUBROUTINE EXCH_RL_SEND_PUT_Y( array,
6 I myOLw, myOLe, myOLs, myOLn, mysNx, mysNy, 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 RL 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 mysNx
49 INTEGER mysNy
50 INTEGER myNz
51 _RL array(1-myOLw:mysNx+myOLe,
52 & 1-myOLs:mysNy+myOLn,
53 & myNZ, nSx, nSy)
54 INTEGER exchWidthX
55 INTEGER exchWidthY
56 INTEGER theSimulationMode
57 INTEGER theCornerMode
58 INTEGER myThid
59 CEndOfInterface
60
61 C == Local variables ==
62 C I, J, K, jMin, jMax, iB - Loop counters and extents
63 C bi, bj
64 C biS, bjS - South tile indices
65 C biN, bjN - North tile indices
66 C eBl - Current exchange buffer level
67 C theProc, theTag, theType, - Variables used in message building
68 C theSize
69 C southCommMode - Working variables holding type
70 C northCommMode of communication a particular
71 C tile face uses.
72 INTEGER I, J, K, jMin, jMax, iMin, iMax, iB
73 INTEGER bi, bj, biS, bjS, biN, bjN
74 INTEGER eBl
75 INTEGER northCommMode
76 INTEGER southCommMode
77
78 #ifdef ALLOW_USE_MPI
79 INTEGER theProc, theTag, theType, theSize, mpiRc
80 #endif
81
82 C-- Write data to exchange buffer
83 C Various actions are possible depending on the communication mode
84 C as follows:
85 C Mode Action
86 C -------- ---------------------------
87 C COMM_NONE Do nothing
88 C
89 C COMM_MSG Message passing communication ( e.g. MPI )
90 C Fill south send buffer from this tile.
91 C Send data with tag identifying tile and direction.
92 C Fill north send buffer from this tile.
93 C Send data with tag identifying tile and direction.
94 C
95 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
96 C Fill south receive buffer of south-neighbor tile
97 C Fill north receive buffer of north-neighbor tile
98 C Sync. memory
99 C Write data-ready Ack for north edge of south-neighbor
100 C tile
101 C Write data-ready Ack for south edge of north-neighbor
102 C tile
103 C Sync. memory
104 C
105 DO bj=myByLo(myThid),myByHi(myThid)
106 DO bi=myBxLo(myThid),myBxHi(myThid)
107
108 ebL = exchangeBufLevel(1,bi,bj)
109 southCommMode = _tileCommModeS(bi,bj)
110 northCommMode = _tileCommModeN(bi,bj)
111 biS = _tileBiS(bi,bj)
112 bjS = _tileBjS(bi,bj)
113 biN = _tileBiN(bi,bj)
114 bjN = _tileBjN(bi,bj)
115 iMin = 1
116 iMax = mysNx
117 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
118 iMin = 1-exchWidthX
119 iMax = mysNx+exchWidthX
120 ENDIF
121
122
123 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
124 c >>>>>>>>>>>>>>>>>>> FORWARD RUN <<<<<<<<<<<<<<<<<<<
125 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
126
127 C o Send or Put south edge
128 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
129 jMin = 1
130 jMax = 1+exchWidthY-1
131 IF ( southCommMode .EQ. COMM_MSG ) THEN
132 iB = 0
133 DO K=1,myNz
134 DO J=jMin,jMax
135 DO I=iMin,iMax
136 iB = iB + 1
137 southSendBuf_RL(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
138 ENDDO
139 ENDDO
140 ENDDO
141 C Send the data
142 #ifdef ALLOW_USE_MPI
143 #ifndef ALWAYS_USE_MPI
144 IF ( usingMPI ) THEN
145 #endif
146 theProc = tilePidS(bi,bj)
147 theTag = _tileTagSendS(bi,bj)
148 theSize = iB
149 theType = MPI_DOUBLE_PRECISION
150 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
151 CALL MPI_Isend(southSendBuf_RL(1,eBl,bi,bj), theSize, theType,
152 & theProc, theTag, MPI_COMM_MODEL,
153 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc)
154 #ifndef ALWAYS_USE_MPI
155 ENDIF
156 #endif
157 #endif /* ALLOW_USE_MPI */
158 northRecvAck(eBl,biS,bjS) = 1.
159 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
160 iB = 0
161 DO K=1,myNz
162 DO J=jMin,jMax
163 DO I=iMin,iMax
164 iB = iB + 1
165 northRecvBuf_RL(iB,eBl,biS,bjS) = array(I,J,K,bi,bj)
166 ENDDO
167 ENDDO
168 ENDDO
169 ELSEIF ( southCommMode .NE. COMM_NONE
170 & .AND. southCommMode .NE. COMM_GET ) THEN
171 STOP ' S/R EXCH: Invalid commS mode.'
172 ENDIF
173
174 C o Send or Put north edge
175 jMin = mysNy-exchWidthY+1
176 jMax = mysNy
177 IF ( northCommMode .EQ. COMM_MSG ) THEN
178 iB = 0
179 DO K=1,myNz
180 DO J=jMin,jMax
181 DO I=iMin,iMax
182 iB = iB + 1
183 northSendBuf_RL(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
184 ENDDO
185 ENDDO
186 ENDDO
187 C Send the data
188 #ifdef ALLOW_USE_MPI
189 #ifndef ALWAYS_USE_MPI
190 IF ( usingMPI ) THEN
191 #endif
192 theProc = tilePidN(bi,bj)
193 theTag = _tileTagSendN(bi,bj)
194 theSize = iB
195 theType = MPI_DOUBLE_PRECISION
196 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
197 CALL MPI_Isend(northSendBuf_RL(1,eBl,bi,bj), theSize, theType,
198 & theProc, theTag, MPI_COMM_MODEL,
199 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc )
200 #ifndef ALWAYS_USE_MPI
201 ENDIF
202 #endif
203 #endif /* ALLOW_USE_MPI */
204 southRecvAck(eBl,biN,bjN) = 1.
205 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
206 iB = 0
207 DO K=1,myNz
208 DO J=jMin,jMax
209 DO I=iMin,iMax
210 iB = iB + 1
211 southRecvBuf_RL(iB,eBl,biN,bjN) = array(I,J,K,bi,bj)
212 ENDDO
213 ENDDO
214 ENDDO
215 ELSEIF ( northCommMode .NE. COMM_NONE
216 & .AND. northCommMode .NE. COMM_GET ) THEN
217 STOP ' S/R EXCH: Invalid commN mode.'
218 ENDIF
219
220 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
221 c >>>>>>>>>>>>>>>>>>> ADJOINT RUN <<<<<<<<<<<<<<<<<<<
222 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
223
224 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
225 jMin = 1-exchWidthY
226 jMax = 0
227 IF ( southCommMode .EQ. COMM_MSG ) THEN
228 iB = 0
229 DO K=1,myNz
230 DO J=jMin,jMax
231 DO I=iMin,iMax
232 iB = iB + 1
233 southSendBuf_RL(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
234 array(I,J,K,bi,bj) = 0.0
235 ENDDO
236 ENDDO
237 ENDDO
238 C Send the data
239 #ifdef ALLOW_USE_MPI
240 #ifndef ALWAYS_USE_MPI
241 IF ( usingMPI ) THEN
242 #endif
243 theProc = tilePidS(bi,bj)
244 theTag = _tileTagSendS(bi,bj)
245 theSize = iB
246 theType = MPI_DOUBLE_PRECISION
247 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
248 CALL MPI_Isend(southSendBuf_RL(1,eBl,bi,bj), theSize, theType,
249 & theProc, theTag, MPI_COMM_MODEL,
250 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc)
251 #ifndef ALWAYS_USE_MPI
252 ENDIF
253 #endif
254 #endif /* ALLOW_USE_MPI */
255 northRecvAck(eBl,biS,bjS) = 1.
256 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
257 iB = 0
258 DO K=1,myNz
259 DO J=jMin,jMax
260 DO I=iMin,iMax
261 iB = iB + 1
262 northRecvBuf_RL(iB,eBl,biS,bjS) = array(I,J,K,bi,bj)
263 array(I,J,K,bi,bj) = 0.0
264 ENDDO
265 ENDDO
266 ENDDO
267 ELSEIF ( southCommMode .NE. COMM_NONE
268 & .AND. southCommMode .NE. COMM_GET ) THEN
269 STOP ' S/R EXCH: Invalid commS mode.'
270 ENDIF
271
272 C o Send or Put north edge
273 jMin = mysNy+1
274 jMax = mysNy+exchWidthY
275 IF ( northCommMode .EQ. COMM_MSG ) THEN
276 iB = 0
277 DO K=1,myNz
278 DO J=jMin,jMax
279 DO I=iMin,iMax
280 iB = iB + 1
281 northSendBuf_RL(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
282 array(I,J,K,bi,bj) = 0.0
283 ENDDO
284 ENDDO
285 ENDDO
286 C Send the data
287 #ifdef ALLOW_USE_MPI
288 #ifndef ALWAYS_USE_MPI
289 IF ( usingMPI ) THEN
290 #endif
291 theProc = tilePidN(bi,bj)
292 theTag = _tileTagSendN(bi,bj)
293 theSize = iB
294 theType = MPI_DOUBLE_PRECISION
295 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
296 CALL MPI_Isend(northSendBuf_RL(1,eBl,bi,bj), theSize, theType,
297 & theProc, theTag, MPI_COMM_MODEL,
298 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc )
299 #ifndef ALWAYS_USE_MPI
300 ENDIF
301 #endif
302 #endif /* ALLOW_USE_MPI */
303 southRecvAck(eBl,biN,bjN) = 1.
304 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
305 iB = 0
306 DO K=1,myNz
307 DO J=jMin,jMax
308 DO I=iMin,iMax
309 iB = iB + 1
310 southRecvBuf_RL(iB,eBl,biN,bjN) = array(I,J,K,bi,bj)
311 array(I,J,K,bi,bj) = 0.0
312 ENDDO
313 ENDDO
314 ENDDO
315 ELSEIF ( northCommMode .NE. COMM_NONE
316 & .AND. northCommMode .NE. COMM_GET ) THEN
317 STOP ' S/R EXCH: Invalid commN mode.'
318 ENDIF
319 endif
320 ENDDO
321 ENDDO
322
323 C-- Signal completetion ( making sure system-wide memory state is
324 C-- consistent ).
325
326 C ** NOTE ** We are relying on being able to produce strong-ordered
327 C memory semantics here. In other words we assume that there is a
328 C mechanism which can ensure that by the time the Ack is seen the
329 C overlap region data that will be exchanged is up to date.
330 IF ( exchNeedsMemSync ) CALL MEMSYNC
331
332 DO bj=myByLo(myThid),myByHi(myThid)
333 DO bi=myBxLo(myThid),myBxHi(myThid)
334 ebL = exchangeBufLevel(1,bi,bj)
335 biS = _tileBiS(bi,bj)
336 bjS = _tileBjS(bi,bj)
337 biN = _tileBiN(bi,bj)
338 bjN = _tileBjN(bi,bj)
339 southCommMode = _tileCommModeS(bi,bj)
340 northCommMode = _tileCommModeN(bi,bj)
341 IF ( southCommMode .EQ. COMM_PUT ) northRecvAck(eBl,biS,bjS) = 1.
342 IF ( northCommMode .EQ. COMM_PUT ) southRecvAck(eBl,biN,bjN) = 1.
343 IF ( southCommMode .EQ. COMM_GET ) northRecvAck(eBl,biS,bjS) = 1.
344 IF ( northCommMode .EQ. COMM_GET ) southRecvAck(eBl,biN,bjN) = 1.
345 ENDDO
346 ENDDO
347
348 C-- Make sure "ack" setting is seen system-wide.
349 C Here strong-ordering is not an issue but we want to make
350 C sure that processes that might spin on the above Ack settings
351 C will see the setting.
352 C ** NOTE ** On some machines we wont spin on the Ack setting
353 C ( particularly the T90 ), instead we will use s system barrier.
354 C On the T90 the system barrier is very fast and switches out the
355 C thread while it waits. On most machines the system barrier
356 C is much too slow and if we own the machine and have one thread
357 C per process preemption is not a problem.
358 IF ( exchNeedsMemSync ) CALL MEMSYNC
359
360 RETURN
361 END
362
363 SUBROUTINE EXCH_RS_SEND_PUT_Y( array,
364 I myOLw, myOLe, myOLs, myOLn, mysNx, mysNy, myNz,
365 I exchWidthX, exchWidthY,
366 I thesimulationMode, thecornerMode, myThid )
367 C /==========================================================\
368 C | SUBROUTINE SEND_PUT_Y |
369 C | o "Send" or "put" Y edges for RS array. |
370 C |==========================================================|
371 C | Routine that invokes actual message passing send or |
372 C | direct "put" of data to update Y faces of an XY[R] array.|
373 C \==========================================================/
374 IMPLICIT NONE
375
376 C == Global variables ==
377 #include "SIZE.h"
378 #include "EEPARAMS.h"
379 #include "EESUPPORT.h"
380 #include "EXCH.h"
381 C == Routine arguments ==
382 C array - Array with edges to exchange.
383 C myOLw - West, East, North and South overlap region sizes.
384 C myOLe
385 C myOLn
386 C myOLs
387 C exchWidthX - Width of data region exchanged.
388 C exchWidthY
389 C theSimulationMode - Forward or reverse mode exchange ( provides
390 C support for adjoint integration of code. )
391 C theCornerMode - Flag indicating whether corner updates are
392 C needed.
393 C myThid - Thread number of this instance of S/R EXCH...
394 C eBl - Edge buffer level
395 INTEGER myOLw
396 INTEGER myOLe
397 INTEGER myOLs
398 INTEGER myOLn
399 INTEGER mysNx
400 INTEGER mysNy
401 INTEGER myNz
402 _RS array(1-myOLw:mysNx+myOLe,
403 & 1-myOLs:mysNy+myOLn,
404 & myNZ, nSx, nSy)
405 INTEGER exchWidthX
406 INTEGER exchWidthY
407 INTEGER theSimulationMode
408 INTEGER theCornerMode
409 INTEGER myThid
410 CEndOfInterface
411
412 C == Local variables ==
413 C I, J, K, jMin, jMax, iB - Loop counters and extents
414 C bi, bj
415 C biS, bjS - South tile indices
416 C biN, bjN - North tile indices
417 C eBl - Current exchange buffer level
418 C theProc, theTag, theType, - Variables used in message building
419 C theSize
420 C southCommMode - Working variables holding type
421 C northCommMode of communication a particular
422 C tile face uses.
423 INTEGER I, J, K, jMin, jMax, iMin, iMax, iB
424 INTEGER bi, bj, biS, bjS, biN, bjN
425 INTEGER eBl
426 INTEGER northCommMode
427 INTEGER southCommMode
428
429 #ifdef ALLOW_USE_MPI
430 INTEGER theProc, theTag, theType, theSize, mpiRc
431 #endif
432
433 C-- Write data to exchange buffer
434 C Various actions are possible depending on the communication mode
435 C as follows:
436 C Mode Action
437 C -------- ---------------------------
438 C COMM_NONE Do nothing
439 C
440 C COMM_MSG Message passing communication ( e.g. MPI )
441 C Fill south send buffer from this tile.
442 C Send data with tag identifying tile and direction.
443 C Fill north send buffer from this tile.
444 C Send data with tag identifying tile and direction.
445 C
446 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
447 C Fill south receive buffer of south-neighbor tile
448 C Fill north receive buffer of north-neighbor tile
449 C Sync. memory
450 C Write data-ready Ack for north edge of south-neighbor
451 C tile
452 C Write data-ready Ack for south edge of north-neighbor
453 C tile
454 C Sync. memory
455 C
456 DO bj=myByLo(myThid),myByHi(myThid)
457 DO bi=myBxLo(myThid),myBxHi(myThid)
458
459 ebL = exchangeBufLevel(1,bi,bj)
460 southCommMode = _tileCommModeS(bi,bj)
461 northCommMode = _tileCommModeN(bi,bj)
462 biS = _tileBiS(bi,bj)
463 bjS = _tileBjS(bi,bj)
464 biN = _tileBiN(bi,bj)
465 bjN = _tileBjN(bi,bj)
466 iMin = 1
467 iMax = mysNx
468 IF ( theCornerMode .EQ. EXCH_UPDATE_CORNERS ) THEN
469 iMin = 1-exchWidthX
470 iMax = mysNx+exchWidthX
471 ENDIF
472
473 C o Send or Put south edge
474 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
475 c >>>>>>>>>>>>>>>>>>> FORWARD RUN <<<<<<<<<<<<<<<<<<<
476 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
477
478 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
479 jMin = 1
480 jMax = 1+exchWidthY-1
481 IF ( southCommMode .EQ. COMM_MSG ) THEN
482 iB = 0
483 DO K=1,myNz
484 DO J=jMin,jMax
485 DO I=iMin,iMax
486 iB = iB + 1
487 southSendBuf_RS(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
488 ENDDO
489 ENDDO
490 ENDDO
491 C Send the data
492 #ifdef ALLOW_USE_MPI
493 #ifndef ALWAYS_USE_MPI
494 IF ( usingMPI ) THEN
495 #endif
496 theProc = tilePidS(bi,bj)
497 theTag = _tileTagSendS(bi,bj)
498 theSize = iB
499 theType = MPI_DOUBLE_PRECISION
500 #ifdef RS_IS_REAL4
501 theType = MPI_REAL4
502 #endif
503 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
504 CALL MPI_Isend(southSendBuf_RS(1,eBl,bi,bj), theSize, theType,
505 & theProc, theTag, MPI_COMM_MODEL,
506 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc)
507 #ifndef ALWAYS_USE_MPI
508 ENDIF
509 #endif
510 #endif /* ALLOW_USE_MPI */
511 northRecvAck(eBl,biS,bjS) = 1.
512 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
513 iB = 0
514 DO K=1,myNz
515 DO J=jMin,jMax
516 DO I=iMin,iMax
517 iB = iB + 1
518 northRecvBuf_RS(iB,eBl,biS,bjS) = array(I,J,K,bi,bj)
519 ENDDO
520 ENDDO
521 ENDDO
522 ELSEIF ( southCommMode .NE. COMM_NONE
523 & .AND. southCommMode .NE. COMM_GET ) THEN
524 STOP ' S/R EXCH: Invalid commS mode.'
525 ENDIF
526
527 C o Send or Put north edge
528 jMin = mysNy-exchWidthY+1
529 jMax = mysNy
530 IF ( northCommMode .EQ. COMM_MSG ) THEN
531 iB = 0
532 DO K=1,myNz
533 DO J=jMin,jMax
534 DO I=iMin,iMax
535 iB = iB + 1
536 northSendBuf_RS(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
537 ENDDO
538 ENDDO
539 ENDDO
540 C Send the data
541 #ifdef ALLOW_USE_MPI
542 #ifndef ALWAYS_USE_MPI
543 IF ( usingMPI ) THEN
544 #endif
545 theProc = tilePidN(bi,bj)
546 theTag = _tileTagSendN(bi,bj)
547 theSize = iB
548 theType = MPI_DOUBLE_PRECISION
549 #ifdef RS_IS_REAL4
550 theType = MPI_REAL4
551 #endif
552 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
553 CALL MPI_Isend(northSendBuf_RS(1,eBl,bi,bj), theSize, theType,
554 & theProc, theTag, MPI_COMM_MODEL,
555 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc )
556 #ifndef ALWAYS_USE_MPI
557 ENDIF
558 #endif
559 #endif /* ALLOW_USE_MPI */
560 southRecvAck(eBl,biN,bjN) = 1.
561 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
562 iB = 0
563 DO K=1,myNz
564 DO J=jMin,jMax
565 DO I=iMin,iMax
566 iB = iB + 1
567 southRecvBuf_RS(iB,eBl,biN,bjN) = array(I,J,K,bi,bj)
568 ENDDO
569 ENDDO
570 ENDDO
571 ELSEIF ( northCommMode .NE. COMM_NONE
572 & .AND. northCommMode .NE. COMM_GET ) THEN
573 STOP ' S/R EXCH: Invalid commN mode.'
574 ENDIF
575
576 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
577 c >>>>>>>>>>>>>>>>>>> ADJOINT RUN <<<<<<<<<<<<<<<<<<<
578 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
579 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
580
581 jMin = 1-exchWidthY
582 jMax = 0
583 IF ( southCommMode .EQ. COMM_MSG ) THEN
584 iB = 0
585 DO K=1,myNz
586 DO J=jMin,jMax
587 DO I=iMin,iMax
588 iB = iB + 1
589 southSendBuf_RS(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
590 array(I,J,K,bi,bj) = 0.0
591 ENDDO
592 ENDDO
593 ENDDO
594 C Send the data
595 #ifdef ALLOW_USE_MPI
596 #ifndef ALWAYS_USE_MPI
597 IF ( usingMPI ) THEN
598 #endif
599 theProc = tilePidS(bi,bj)
600 theTag = _tileTagSendS(bi,bj)
601 theSize = iB
602 theType = MPI_DOUBLE_PRECISION
603 #ifdef RS_IS_REAL4
604 theType = MPI_REAL4
605 #endif
606 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
607 CALL MPI_Isend(southSendBuf_RS(1,eBl,bi,bj), theSize, theType,
608 & theProc, theTag, MPI_COMM_MODEL,
609 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc)
610 #ifndef ALWAYS_USE_MPI
611 ENDIF
612 #endif
613 #endif /* ALLOW_USE_MPI */
614 northRecvAck(eBl,biS,bjS) = 1.
615 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
616 iB = 0
617 DO K=1,myNz
618 DO J=jMin,jMax
619 DO I=iMin,iMax
620 iB = iB + 1
621 northRecvBuf_RS(iB,eBl,biS,bjS) = array(I,J,K,bi,bj)
622 array(I,J,K,bi,bj) = 0.0
623 ENDDO
624 ENDDO
625 ENDDO
626 ELSEIF ( southCommMode .NE. COMM_NONE
627 & .AND. southCommMode .NE. COMM_GET ) THEN
628 STOP ' S/R EXCH: Invalid commS mode.'
629 ENDIF
630
631 C o Send or Put north edge
632 jMin = mysNy+1
633 jMax = mysNy+exchWidthY
634 IF ( northCommMode .EQ. COMM_MSG ) THEN
635 iB = 0
636 DO K=1,myNz
637 DO J=jMin,jMax
638 DO I=iMin,iMax
639 iB = iB + 1
640 northSendBuf_RS(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
641 array(I,J,K,bi,bj) = 0.0
642 ENDDO
643 ENDDO
644 ENDDO
645 C Send the data
646 #ifdef ALLOW_USE_MPI
647 #ifndef ALWAYS_USE_MPI
648 IF ( usingMPI ) THEN
649 #endif
650 theProc = tilePidN(bi,bj)
651 theTag = _tileTagSendN(bi,bj)
652 theSize = iB
653 theType = MPI_DOUBLE_PRECISION
654 #ifdef RS_IS_REAL4
655 theType = MPI_REAL4
656 #endif
657 exchNreqsY(1,bi,bj) = exchNreqsY(1,bi,bj)+1
658 CALL MPI_Isend(northSendBuf_RS(1,eBl,bi,bj), theSize, theType,
659 & theProc, theTag, MPI_COMM_MODEL,
660 & exchReqIdY(exchNreqsY(1,bi,bj),1,bi,bj), mpiRc )
661 #ifndef ALWAYS_USE_MPI
662 ENDIF
663 #endif
664 #endif /* ALLOW_USE_MPI */
665 southRecvAck(eBl,biN,bjN) = 1.
666 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
667 iB = 0
668 DO K=1,myNz
669 DO J=jMin,jMax
670 DO I=iMin,iMax
671 iB = iB + 1
672 southRecvBuf_RS(iB,eBl,biN,bjN) = array(I,J,K,bi,bj)
673 array(I,J,K,bi,bj) = 0.0
674 ENDDO
675 ENDDO
676 ENDDO
677 ELSEIF ( northCommMode .NE. COMM_NONE
678 & .AND. northCommMode .NE. COMM_GET ) THEN
679 STOP ' S/R EXCH: Invalid commN mode.'
680 ENDIF
681
682 ENDIF
683 ENDDO
684 ENDDO
685
686 C-- Signal completetion ( making sure system-wide memory state is
687 C-- consistent ).
688
689 C ** NOTE ** We are relying on being able to produce strong-ordered
690 C memory semantics here. In other words we assume that there is a
691 C mechanism which can ensure that by the time the Ack is seen the
692 C overlap region data that will be exchanged is up to date.
693 IF ( exchNeedsMemSync ) CALL MEMSYNC
694
695 DO bj=myByLo(myThid),myByHi(myThid)
696 DO bi=myBxLo(myThid),myBxHi(myThid)
697 ebL = exchangeBufLevel(1,bi,bj)
698 biS = _tileBiS(bi,bj)
699 bjS = _tileBjS(bi,bj)
700 biN = _tileBiN(bi,bj)
701 bjN = _tileBjN(bi,bj)
702 southCommMode = _tileCommModeS(bi,bj)
703 northCommMode = _tileCommModeN(bi,bj)
704 IF ( southCommMode .EQ. COMM_PUT ) northRecvAck(eBl,biS,bjS) = 1.
705 IF ( northCommMode .EQ. COMM_PUT ) southRecvAck(eBl,biN,bjN) = 1.
706 IF ( southCommMode .EQ. COMM_GET ) northRecvAck(eBl,biS,bjS) = 1.
707 IF ( northCommMode .EQ. COMM_GET ) southRecvAck(eBl,biN,bjN) = 1.
708 ENDDO
709 ENDDO
710
711 C-- Make sure "ack" setting is seen system-wide.
712 C Here strong-ordering is not an issue but we want to make
713 C sure that processes that might spin on the above Ack settings
714 C will see the setting.
715 C ** NOTE ** On some machines we wont spin on the Ack setting
716 C ( particularly the T90 ), instead we will use s system barrier.
717 C On the T90 the system barrier is very fast and switches out the
718 C thread while it waits. On most machines the system barrier
719 C is much too slow and if we own the machine and have one thread
720 C per process preemption is not a problem.
721 IF ( exchNeedsMemSync ) CALL MEMSYNC
722
723 RETURN
724 END

  ViewVC Help
Powered by ViewVC 1.1.22