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

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

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


Revision 1.6 - (show annotations) (download)
Fri Nov 11 03:01:26 2005 UTC (18 years, 7 months ago) by cnh
Branch: MAIN
CVS Tags: checkpoint58b_post, checkpoint57y_post, checkpoint59, checkpoint58, checkpoint58f_post, checkpoint58d_post, checkpoint58a_post, checkpoint57z_post, checkpoint58y_post, checkpoint58t_post, checkpoint58m_post, checkpoint58w_post, checkpoint57y_pre, checkpoint58o_post, checkpoint58p_post, checkpoint58q_post, checkpoint58e_post, mitgcm_mapl_00, checkpoint58r_post, checkpoint58n_post, checkpoint59e, checkpoint59d, checkpoint59g, checkpoint59f, checkpoint59a, checkpoint59c, checkpoint59b, checkpoint59m, checkpoint59l, checkpoint59n, checkpoint59i, checkpoint59h, checkpoint59k, checkpoint58k_post, checkpoint58v_post, checkpoint58l_post, checkpoint58g_post, checkpoint58x_post, checkpoint59j, checkpoint58h_post, checkpoint58j_post, checkpoint58i_post, checkpoint57x_post, checkpoint58c_post, checkpoint58u_post, checkpoint58s_post
Changes since 1.5: +3 -3 lines
Ooops - _BARRIER in wrong place wrt to local logical.

1 C $Header: /u/u0/gcmpack/MITgcm/eesupp/src/exch_rx_send_put_x.template,v 1.5 2005/11/09 17:22:08 cnh Exp $
2 C $Name: $
3 #include "CPP_EEOPTIONS.h"
4
5 CBOP
6
7 C !ROUTINE: EXCH_RX_SEND_PUT_X
8
9 C !INTERFACE:
10 SUBROUTINE EXCH_RX_SEND_PUT_X( array,
11 I myOLw, myOLe, myOLs, myOLn, myNz,
12 I exchWidthX, exchWidthY,
13 I thesimulationMode, thecornerMode, myThid )
14 IMPLICIT NONE
15 C !DESCRIPTION:
16 C *==========================================================*
17 C | SUBROUTINE EXCH_RX_SEND_PUT_X
18 C | o "Send" or "put" X edges for RX array.
19 C *==========================================================*
20 C | Routine that invokes actual message passing send or
21 C | direct "put" of data to update X faces of an XY[R] array.
22 C *==========================================================*
23
24 C !USES:
25 C == Global variables ==
26 #include "SIZE.h"
27 #include "EEPARAMS.h"
28 #include "EESUPPORT.h"
29 #include "EXCH.h"
30
31 C !INPUT/OUTPUT PARAMETERS:
32 C == Routine arguments ==
33 C array :: Array with edges to exchange.
34 C myOLw :: West, East, North and South overlap region sizes.
35 C myOLe
36 C myOLn
37 C myOLs
38 C exchWidthX :: Width of data region exchanged.
39 C exchWidthY
40 C theSimulationMode :: Forward or reverse mode exchange ( provides
41 C support for adjoint integration of code. )
42 C theCornerMode :: Flag indicating whether corner updates are
43 C needed.
44 C myThid :: Thread number of this instance of S/R EXCH...
45 C eBl :: Edge buffer level
46 INTEGER myOLw
47 INTEGER myOLe
48 INTEGER myOLs
49 INTEGER myOLn
50 INTEGER myNz
51 _RX array(1-myOLw:sNx+myOLe,
52 & 1-myOLs:sNy+myOLn,
53 & myNZ, nSx, nSy)
54 INTEGER exchWidthX
55 INTEGER exchWidthY
56 INTEGER theSimulationMode
57 INTEGER theCornerMode
58 INTEGER myThid
59
60 C !LOCAL VARIABLES:
61 C == Local variables ==
62 C I, J, K, iMin, iMax, iB :: Loop counters and extents
63 C bi, bj
64 C biW, bjW :: West tile indices
65 C biE, bjE :: East tile indices
66 C eBl :: Current exchange buffer level
67 C theProc, theTag, theType, :: Variables used in message building
68 C theSize
69 C westCommMode :: Working variables holding type
70 C eastCommMode of communication a particular
71 C tile face uses.
72 INTEGER I, J, K, iMin, iMax, iB
73 INTEGER bi, bj, biW, bjW, biE, bjE
74 INTEGER eBl
75 INTEGER westCommMode
76 INTEGER eastCommMode
77
78 #ifdef ALLOW_USE_MPI
79 INTEGER theProc, theTag, theType, theSize, mpiRc
80 #endif
81 C-- Write data to exchange buffer
82 C Various actions are possible depending on the communication mode
83 C as follows:
84 C Mode Action
85 C -------- ---------------------------
86 C COMM_NONE Do nothing
87 C
88 C COMM_MSG Message passing communication ( e.g. MPI )
89 C Fill west send buffer from this tile.
90 C Send data with tag identifying tile and direction.
91 C Fill east send buffer from this tile.
92 C Send data with tag identifying tile and direction.
93 C
94 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
95 C Fill east receive buffer of west-neighbor tile
96 C Fill west receive buffer of east-neighbor tile
97 C Sync. memory
98 C Write data-ready Ack for east edge of west-neighbor
99 C tile
100 C Write data-ready Ack for west edge of east-neighbor
101 C tile
102 C Sync. memory
103 C
104 CEOP
105
106 INTEGER myBxLoSave(MAX_NO_THREADS)
107 INTEGER myBxHiSave(MAX_NO_THREADS)
108 INTEGER myByLoSave(MAX_NO_THREADS)
109 INTEGER myByHiSave(MAX_NO_THREADS)
110 LOGICAL doingSingleThreadedComms
111
112 doingSingleThreadedComms = .FALSE.
113 #ifdef ALLOW_USE_MPI
114 #ifndef ALWAYS_USE_MPI
115 IF ( usingMPI ) THEN
116 #endif
117 C Set default behavior to have MPI comms done by a single thread.
118 C Most MPI implementations don't support concurrent comms from
119 C several threads.
120 IF ( nThreads .GT. 1 ) THEN
121 _BARRIER
122 _BEGIN_MASTER( myThid )
123 DO I=1,nThreads
124 myBxLoSave(I) = myBxLo(I)
125 myBxHiSave(I) = myBxHi(I)
126 myByLoSave(I) = myByLo(I)
127 myByHiSave(I) = myByHi(I)
128 ENDDO
129 C Comment out loop below and myB[xy][Lo|Hi](1) settings below
130 C if you want to get multi-threaded MPI comms.
131 DO I=1,nThreads
132 myBxLo(I) = 0
133 myBxHi(I) = -1
134 myByLo(I) = 0
135 myByHi(I) = -1
136 ENDDO
137 myBxLo(1) = 1
138 myBxHi(1) = nSx
139 myByLo(1) = 1
140 myByHi(1) = nSy
141 doingSingleThreadedComms = .TRUE.
142 _END_MASTER( myThid )
143 _BARRIER
144 ENDIF
145 #ifndef ALWAYS_USE_MPI
146 ENDIF
147 #endif
148 #endif
149
150 DO bj=myByLo(myThid),myByHi(myThid)
151 DO bi=myBxLo(myThid),myBxHi(myThid)
152
153 ebL = exchangeBufLevel(1,bi,bj)
154 westCommMode = _tileCommModeW(bi,bj)
155 eastCommMode = _tileCommModeE(bi,bj)
156 biE = _tileBiE(bi,bj)
157 bjE = _tileBjE(bi,bj)
158 biW = _tileBiW(bi,bj)
159 bjW = _tileBjW(bi,bj)
160
161 C o Send or Put west edge
162 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
163 c >>>>>>>>>>>>>>>>>>> FORWARD RUN <<<<<<<<<<<<<<<<<<<
164 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
165
166 IF ( _theSimulationMode .EQ. FORWARD_SIMULATION ) THEN
167 iMin = 1
168 iMax = 1+exchWidthX-1
169 IF ( westCommMode .EQ. COMM_MSG ) THEN
170 iB = 0
171 DO K=1,myNz
172 DO J=1,sNy
173 DO I=iMin,iMax
174 iB = iB + 1
175 westSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
176 ENDDO
177 ENDDO
178 ENDDO
179 C Send the data
180 #ifdef ALLOW_USE_MPI
181 #ifndef ALWAYS_USE_MPI
182 IF ( usingMPI ) THEN
183 #endif
184 theProc = tilePidW(bi,bj)
185 theTag = _tileTagSendW(bi,bj)
186 theSize = iB
187 theType = _MPI_TYPE_RX
188 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
189 CALL MPI_Isend(westSendBuf_RX(1,eBl,bi,bj), theSize, theType,
190 & theProc, theTag, MPI_COMM_MODEL,
191 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
192 #ifndef ALWAYS_USE_MPI
193 ENDIF
194 #endif
195 #endif /* ALLOW_USE_MPI */
196 eastRecvAck(eBl,biW,bjW) = 1.
197 ELSEIF ( westCommMode .EQ. COMM_PUT ) THEN
198 iB = 0
199 DO K=1,myNz
200 DO J=1,sNy
201 DO I=iMin,iMax
202 iB = iB + 1
203 eastRecvBuf_RX(iB,eBl,biW,bjW) = array(I,J,K,bi,bj)
204 ENDDO
205 ENDDO
206 ENDDO
207 ELSEIF ( westCommMode .NE. COMM_NONE
208 & .AND. westCommMode .NE. COMM_GET ) THEN
209 STOP ' S/R EXCH: Invalid commW mode.'
210 ENDIF
211
212 C o Send or Put east edge
213 iMin = sNx-exchWidthX+1
214 iMax = sNx
215 IF ( eastCommMode .EQ. COMM_MSG ) THEN
216 iB = 0
217 DO K=1,myNz
218 DO J=1,sNy
219 DO I=iMin,iMax
220 iB = iB + 1
221 eastSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
222 ENDDO
223 ENDDO
224 ENDDO
225 C Send the data
226 #ifdef ALLOW_USE_MPI
227 #ifndef ALWAYS_USE_MPI
228 IF ( usingMPI ) THEN
229 #endif
230 theProc = tilePidE(bi,bj)
231 theTag = _tileTagSendE(bi,bj)
232 theSize = iB
233 theType = _MPI_TYPE_RX
234 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
235 CALL MPI_Isend(eastSendBuf_RX(1,eBl,bi,bj), theSize, theType,
236 & theProc, theTag, MPI_COMM_MODEL,
237 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
238 #ifndef ALWAYS_USE_MPI
239 ENDIF
240 #endif
241 #endif /* ALLOW_USE_MPI */
242 westRecvAck(eBl,biE,bjE) = 1.
243 ELSEIF ( eastCommMode .EQ. COMM_PUT ) THEN
244 iB = 0
245 DO K=1,myNz
246 DO J=1,sNy
247 DO I=iMin,iMax
248 iB = iB + 1
249 westRecvBuf_RX(iB,eBl,biE,bjE) = array(I,J,K,bi,bj)
250 ENDDO
251 ENDDO
252 ENDDO
253 ELSEIF ( eastCommMode .NE. COMM_NONE
254 & .AND. eastCommMode .NE. COMM_GET ) THEN
255 STOP ' S/R EXCH: Invalid commE mode.'
256 ENDIF
257 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
258 c >>>>>>>>>>>>>>>>>>> ADJOINT RUN <<<<<<<<<<<<<<<<<<<
259 c >>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<
260 ELSEIF ( _theSimulationMode .EQ. REVERSE_SIMULATION ) THEN
261 iMin = 1-exchWidthX
262 iMax = 0
263 IF ( westCommMode .EQ. COMM_MSG ) THEN
264 iB = 0
265 DO K=1,myNz
266 DO J=1,sNy
267 DO I=iMin,iMax
268 iB = iB + 1
269 westSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
270 array(I,J,K,bi,bj) = 0.0
271 ENDDO
272 ENDDO
273 ENDDO
274 C Send the data
275 #ifdef ALLOW_USE_MPI
276 #ifndef ALWAYS_USE_MPI
277 IF ( usingMPI ) THEN
278 #endif
279 theProc = tilePidW(bi,bj)
280 theTag = _tileTagSendW(bi,bj)
281 theSize = iB
282 theType = _MPI_TYPE_RX
283 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
284 CALL MPI_Isend(westSendBuf_RX(1,eBl,bi,bj), theSize, theType,
285 & theProc, theTag, MPI_COMM_MODEL,
286 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
287 #ifndef ALWAYS_USE_MPI
288 ENDIF
289 #endif
290 #endif /* ALLOW_USE_MPI */
291 eastRecvAck(eBl,biW,bjW) = 1.
292 ELSEIF ( westCommMode .EQ. COMM_PUT ) THEN
293 iB = 0
294 DO K=1,myNz
295 DO J=1,sNy
296 DO I=iMin,iMax
297 iB = iB + 1
298 eastRecvBuf_RX(iB,eBl,biW,bjW) = array(I,J,K,bi,bj)
299 array(I,J,K,bi,bj) = 0.0
300 ENDDO
301 ENDDO
302 ENDDO
303 ELSEIF ( westCommMode .NE. COMM_NONE
304 & .AND. westCommMode .NE. COMM_GET ) THEN
305 STOP ' S/R EXCH: Invalid commW mode.'
306 ENDIF
307
308 C o Send or Put east edge
309 iMin = sNx+1
310 iMax = sNx+exchWidthX
311 IF ( eastCommMode .EQ. COMM_MSG ) THEN
312 iB = 0
313 DO K=1,myNz
314 DO J=1,sNy
315 DO I=iMin,iMax
316 iB = iB + 1
317 eastSendBuf_RX(iB,eBl,bi,bj) = array(I,J,K,bi,bj)
318 array(I,J,K,bi,bj) = 0.0
319 ENDDO
320 ENDDO
321 ENDDO
322 C Send the data
323 #ifdef ALLOW_USE_MPI
324 #ifndef ALWAYS_USE_MPI
325 IF ( usingMPI ) THEN
326 #endif
327 theProc = tilePidE(bi,bj)
328 theTag = _tileTagSendE(bi,bj)
329 theSize = iB
330 theType = _MPI_TYPE_RX
331 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
332 CALL MPI_Isend(eastSendBuf_RX(1,eBl,bi,bj), theSize, theType,
333 & theProc, theTag, MPI_COMM_MODEL,
334 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc )
335 #ifndef ALWAYS_USE_MPI
336 ENDIF
337 #endif
338 #endif /* ALLOW_USE_MPI */
339 westRecvAck(eBl,biE,bjE) = 1.
340 ELSEIF ( eastCommMode .EQ. COMM_PUT ) THEN
341 iB = 0
342 DO K=1,myNz
343 DO J=1,sNy
344 DO I=iMin,iMax
345 iB = iB + 1
346 westRecvBuf_RX(iB,eBl,biE,bjE) = array(I,J,K,bi,bj)
347 array(I,J,K,bi,bj) = 0.0
348 ENDDO
349 ENDDO
350 ENDDO
351 ELSEIF ( eastCommMode .NE. COMM_NONE
352 & .AND. eastCommMode .NE. COMM_GET ) THEN
353 STOP ' S/R EXCH: Invalid commE mode.'
354 ENDIF
355
356 ENDIF
357
358 ENDDO
359 ENDDO
360
361 C-- Signal completetion ( making sure system-wide memory state is
362 C-- consistent ).
363
364 C ** NOTE ** We are relying on being able to produce strong-ordered
365 C memory semantics here. In other words we assume that there is a
366 C mechanism which can ensure that by the time the Ack is seen the
367 C overlap region data that will be exchanged is up to date.
368 IF ( exchNeedsMemSync ) CALL MEMSYNC
369
370 DO bj=myByLo(myThid),myByHi(myThid)
371 DO bi=myBxLo(myThid),myBxHi(myThid)
372 ebL = exchangeBufLevel(1,bi,bj)
373 biE = _tileBiE(bi,bj)
374 bjE = _tileBjE(bi,bj)
375 biW = _tileBiW(bi,bj)
376 bjW = _tileBjW(bi,bj)
377 westCommMode = _tileCommModeW(bi,bj)
378 eastCommMode = _tileCommModeE(bi,bj)
379 IF ( westCommMode .EQ. COMM_PUT ) eastRecvAck(eBl,biW,bjW) = 1.
380 IF ( eastCommMode .EQ. COMM_PUT ) westRecvAck(eBl,biE,bjE) = 1.
381 IF ( westCommMode .EQ. COMM_GET ) eastRecvAck(eBl,biW,bjW) = 1.
382 IF ( eastCommMode .EQ. COMM_GET ) westRecvAck(eBl,biE,bjE) = 1.
383 ENDDO
384 ENDDO
385
386 C-- Make sure "ack" setting is seen system-wide.
387 C Here strong-ordering is not an issue but we want to make
388 C sure that processes that might spin on the above Ack settings
389 C will see the setting.
390 C ** NOTE ** On some machines we wont spin on the Ack setting
391 C ( particularly the T90 ), instead we will use s system barrier.
392 C On the T90 the system barrier is very fast and switches out the
393 C thread while it waits. On most machines the system barrier
394 C is much too slow and if we own the machine and have one thread
395 C per process preemption is not a problem.
396 IF ( exchNeedsMemSync ) CALL MEMSYNC
397
398 _BARRIER
399 IF ( doingSingleThreadedComms ) THEN
400 C Restore saved settings that were stored to allow
401 C single thred comms.
402 _BEGIN_MASTER(myThid)
403 DO I=1,nThreads
404 myBxLo(I) = myBxLoSave(I)
405 myBxHi(I) = myBxHiSave(I)
406 myByLo(I) = myByLoSave(I)
407 myByHi(I) = myByHiSave(I)
408 ENDDO
409 _END_MASTER(myThid)
410 ENDIF
411 _BARRIER
412
413 RETURN
414 END

  ViewVC Help
Powered by ViewVC 1.1.22