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

Annotation 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 - (hide 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 adcroft 1.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