/[MITgcm]/MITgcm/pkg/flt/exch_send_put_vec.F
ViewVC logotype

Contents of /MITgcm/pkg/flt/exch_send_put_vec.F

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


Revision 1.3 - (show annotations) (download)
Wed Dec 3 01:32:35 2008 UTC (15 years, 6 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint61g
Changes since 1.2: +8 -9 lines
- move FLT_CPPOPTIONS.h to FLT_OPTIONS.h (standard name)
  + make OPTIONS file more standard.
- rename S/R MDSREADVECTOR_FLT to FLT_MDSREADVECTOR (to mach src file name)

1 C $Header: /u/gcmpack/MITgcm/pkg/flt/exch_send_put_vec.F,v 1.2 2007/10/09 00:04:53 jmc Exp $
2 C $Name: $
3
4 #include "FLT_OPTIONS.h"
5 #ifdef ALLOW_FLT
6
7 SUBROUTINE EXCH_RL_SEND_PUT_VEC_X( arrayE, arrayW,
8 I myd1, myThid )
9 C /==========================================================\
10 C | SUBROUTINE EXCH_RL_SEND_PUT_X |
11 C | o "Send" or "put" X edges for RL array. |
12 C |==========================================================|
13 C | Routine that invokes actual message passing send or |
14 C | direct "put" of data to update X 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 "FLT.h"
23 #include "EXCH.h"
24 C == Routine arguments ==
25 C arrayE - Array to be exchanged.
26 C arrayW
27 C myd1 - sizes.
28 C myd2
29 C myThid - Thread number of this instance of S/R EXCH...
30 INTEGER myd1
31 INTEGER myd2
32 _RL arrayE(myd1, nSx, nSy), arrayW(myd1, nSx, nSy)
33 INTEGER theSimulationMode
34 INTEGER myThid
35 CEndOfInterface
36
37 C == Local variables ==
38 C I, J - Loop counters and extents
39 C bi, bj
40 C biW, bjW - West tile indices
41 C biE, bjE - East tile indices
42 C theProc, theTag, theType, - Variables used in message building
43 C theSize
44 C westCommMode - Working variables holding type
45 C eastCommMode of communication a particular
46 C tile face uses.
47 INTEGER I, J
48 INTEGER bi, bj, biW, bjW, biE, bjE
49 INTEGER westCommMode
50 INTEGER eastCommMode
51
52 #ifdef ALLOW_USE_MPI
53 INTEGER theProc, theTag, theType, theSize, mpiRc
54 #endif
55 C-- Write data to exchange buffer
56 C Various actions are possible depending on the communication mode
57 C as follows:
58 C Mode Action
59 C -------- ---------------------------
60 C COMM_NONE Do nothing
61 C
62 C COMM_MSG Message passing communication ( e.g. MPI )
63 C Fill west send buffer from this tile.
64 C Send data with tag identifying tile and direction.
65 C Fill east send buffer from this tile.
66 C Send data with tag identifying tile and direction.
67 C
68 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
69 C Fill east receive buffer of west-neighbor tile
70 C Fill west receive buffer of east-neighbor tile
71 C Sync. memory
72 C Write data-ready Ack for east edge of west-neighbor
73 C tile
74 C Write data-ready Ack for west edge of east-neighbor
75 C tile
76 C Sync. memory
77 C
78 DO bj=myByLo(myThid),myByHi(myThid)
79 DO bi=myBxLo(myThid),myBxHi(myThid)
80
81 westCommMode = _tileCommModeW(bi,bj)
82 eastCommMode = _tileCommModeE(bi,bj)
83 biE = _tileBiE(bi,bj)
84 bjE = _tileBjE(bi,bj)
85 biW = _tileBiW(bi,bj)
86 bjW = _tileBjW(bi,bj)
87
88 C o Send or Put west edge
89 IF ( westCommMode .EQ. COMM_MSG ) THEN
90 C Send the data
91 #ifdef ALLOW_USE_MPI
92 #ifndef ALWAYS_USE_MPI
93 IF ( usingMPI ) THEN
94 #endif
95 theProc = tilePidW(bi,bj)
96 theTag = _tileTagSendW(bi,bj)
97 theSize = myd1
98 theType = MPI_DOUBLE_PRECISION
99 c exchVReqsX(1,bi,bj) = exchVReqsX(1,bi,bj)+1
100 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
101 CALL MPI_Isend(arrayW(1,bi,bj), theSize, theType,
102 & theProc, theTag, MPI_COMM_MODEL,
103 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc)
104 c & exchReqVIdX(exchVReqsX(1,bi,bj),1,bi,bj), mpiRc)
105 #ifndef ALWAYS_USE_MPI
106 ENDIF
107 #endif
108 #endif /* ALLOW_USE_MPI */
109 eastRecvAck(1,biW,bjW) = 1.
110 ELSEIF ( westCommMode .EQ. COMM_PUT ) THEN
111 DO I=1,myd1
112 arrayE(I,biW,bjW) = arrayW(I,bi,bj)
113 ENDDO
114 ELSEIF ( westCommMode .NE. COMM_NONE
115 & .AND. westCommMode .NE. COMM_GET ) THEN
116 STOP ' S/R EXCH: Invalid commW mode.'
117 ENDIF
118
119 C o Send or Put east edge
120 IF ( eastCommMode .EQ. COMM_MSG ) THEN
121 C Send the data
122 #ifdef ALLOW_USE_MPI
123 #ifndef ALWAYS_USE_MPI
124 IF ( usingMPI ) THEN
125 #endif
126 theProc = tilePidE(bi,bj)
127 theTag = _tileTagSendE(bi,bj)
128 theSize = myd1
129 theType = MPI_DOUBLE_PRECISION
130 c exchVReqsX(1,bi,bj) = exchVReqsX(1,bi,bj)+1
131 exchNReqsX(1,bi,bj) = exchNReqsX(1,bi,bj)+1
132 c if (theProc .eq. 2 .or. theProc .eq. 4) then
133 c if (arrayE(1,bi,bj) .ne. 0.) then
134 c write(errormessageunit,*) 'qq1y: ',myprocid,
135 c & theProc,theTag,theSize,(arrayE(i,bi,bj),i=1,32)
136 c endif
137 c endif
138 CALL MPI_Isend(arrayE(1,bi,bj), theSize, theType,
139 & theProc, theTag, MPI_COMM_MODEL,
140 & exchReqIdX(exchNReqsX(1,bi,bj),1,bi,bj), mpiRc)
141 c & exchReqVIdX(exchVReqsX(1,bi,bj),1,bi,bj), mpiRc)
142 #ifndef ALWAYS_USE_MPI
143 ENDIF
144 #endif
145 #endif /* ALLOW_USE_MPI */
146 westRecvAck(1,biE,bjE) = 1.
147 ELSEIF ( eastCommMode .EQ. COMM_PUT ) THEN
148 DO I=1,myd1
149 arrayW(I,biE,bjE) = arrayE(I,bi,bj)
150 ENDDO
151 ELSEIF ( eastCommMode .NE. COMM_NONE
152 & .AND. eastCommMode .NE. COMM_GET ) THEN
153 STOP ' S/R EXCH: Invalid commE mode.'
154 ENDIF
155
156 ENDDO
157 ENDDO
158
159 C-- Signal completetion ( making sure system-wide memory state is
160 C-- consistent ).
161
162 C ** NOTE ** We are relying on being able to produce strong-ordered
163 C memory semantics here. In other words we assume that there is a
164 C mechanism which can ensure that by the time the Ack is seen the
165 C overlap region data that will be exchanged is up to date.
166 IF ( exchNeedsMemSync ) CALL MEMSYNC
167
168 DO bj=myByLo(myThid),myByHi(myThid)
169 DO bi=myBxLo(myThid),myBxHi(myThid)
170 biE = _tileBiE(bi,bj)
171 bjE = _tileBjE(bi,bj)
172 biW = _tileBiW(bi,bj)
173 bjW = _tileBjW(bi,bj)
174 westCommMode = _tileCommModeW(bi,bj)
175 eastCommMode = _tileCommModeE(bi,bj)
176 IF ( westCommMode .EQ. COMM_PUT ) eastRecvAck(1,biW,bjW) = 1.
177 IF ( eastCommMode .EQ. COMM_PUT ) westRecvAck(1,biE,bjE) = 1.
178 IF ( westCommMode .EQ. COMM_GET ) eastRecvAck(1,biW,bjW) = 1.
179 IF ( eastCommMode .EQ. COMM_GET ) westRecvAck(1,biE,bjE) = 1.
180 ENDDO
181 ENDDO
182
183 C-- Make sure "ack" setting is seen system-wide.
184 C Here strong-ordering is not an issue but we want to make
185 C sure that processes that might spin on the above Ack settings
186 C will see the setting.
187 C ** NOTE ** On some machines we wont spin on the Ack setting
188 C ( particularly the T90 ), instead we will use s system barrier.
189 C On the T90 the system barrier is very fast and switches out the
190 C thread while it waits. On most machines the system barrier
191 C is much too slow and if we own the machine and have one thread
192 C per process preemption is not a problem.
193 IF ( exchNeedsMemSync ) CALL MEMSYNC
194
195 RETURN
196 END
197
198 SUBROUTINE EXCH_RL_SEND_PUT_VEC_Y( arrayN, arrayS,
199 I myd1, myThid )
200 C /==========================================================\
201 C | SUBROUTINE EXCH_RL_SEND_PUT_Y |
202 C | o "Send" or "put" Y edges for RL array. |
203 C |==========================================================|
204 C | Routine that invokes actual message passing send or |
205 C | direct "put" of data to update X faces of an XY[R] array.|
206 C \==========================================================/
207 IMPLICIT NONE
208
209 C == Global variables ==
210 #include "SIZE.h"
211 #include "EEPARAMS.h"
212 #include "EESUPPORT.h"
213 #include "FLT.h"
214 #include "EXCH.h"
215 C == Routine arguments ==
216 C arrayN - Array to be exchanged.
217 C arrayS
218 C myd1 - sizes.
219 C myd2
220 C myThid - Thread number of this instance of S/R EXCH...
221 INTEGER myd1
222 INTEGER myd2
223 _RL arrayN(myd1, nSx, nSy), arrayS(myd1, nSx, nSy)
224 INTEGER myThid
225 CEndOfInterface
226
227 C == Local variables ==
228 C I, J - Loop counters and extents
229 C bi, bj
230 C biN, bjN - North tile indices
231 C biS, bjS - South tile indices
232 C theProc, theTag, theType, - Variables used in message building
233 C theSize
234 C westCommMode - Working variables holding type
235 C eastCommMode of communication a particular
236 C tile face uses.
237 INTEGER I, J
238 INTEGER bi, bj, biS, bjS, biN, bjN
239 INTEGER southCommMode
240 INTEGER northCommMode
241
242 #ifdef ALLOW_USE_MPI
243 INTEGER theProc, theTag, theType, theSize, mpiRc
244 #endif
245 C-- Write data to exchange buffer
246 C Various actions are possible depending on the communication mode
247 C as follows:
248 C Mode Action
249 C -------- ---------------------------
250 C COMM_NONE Do nothing
251 C
252 C COMM_MSG Message passing communication ( e.g. MPI )
253 C Fill west send buffer from this tile.
254 C Send data with tag identifying tile and direction.
255 C Fill east send buffer from this tile.
256 C Send data with tag identifying tile and direction.
257 C
258 C COMM_PUT "Put" communication ( UMP_, shmemput, etc... )
259 C Fill east receive buffer of south-neighbor tile
260 C Fill west receive buffer of north-neighbor tile
261 C Sync. memory
262 C Write data-ready Ack for east edge of south-neighbor
263 C tile
264 C Write data-ready Ack for west edge of north-neighbor
265 C tile
266 C Sync. memory
267 C
268 DO bj=myByLo(myThid),myByHi(myThid)
269 DO bi=myBxLo(myThid),myBxHi(myThid)
270
271 southCommMode = _tileCommModeS(bi,bj)
272 northCommMode = _tileCommModeN(bi,bj)
273 biN = _tileBiN(bi,bj)
274 bjN = _tileBjN(bi,bj)
275 biS = _tileBiS(bi,bj)
276 bjS = _tileBjS(bi,bj)
277
278 C o Send or Put south edge
279 IF ( southCommMode .EQ. COMM_MSG ) THEN
280 C Send the data
281 #ifdef ALLOW_USE_MPI
282 #ifndef ALWAYS_USE_MPI
283 IF ( usingMPI ) THEN
284 #endif
285 theProc = tilePidS(bi,bj)
286 theTag = _tileTagSendS(bi,bj)
287 theSize = myd1
288 theType = MPI_DOUBLE_PRECISION
289 c exchVReqsY(1,bi,bj) = exchVReqsY(1,bi,bj)+1
290 exchNReqsY(1,bi,bj) = exchNReqsY(1,bi,bj)+1
291 CALL MPI_Isend(arrayS(1,bi,bj), theSize, theType,
292 & theProc, theTag, MPI_COMM_MODEL,
293 & exchReqIdY(exchNReqsY(1,bi,bj),1,bi,bj), mpiRc)
294 c & exchReqVIdY(exchVReqsY(1,bi,bj),1,bi,bj), mpiRc)
295 #ifndef ALWAYS_USE_MPI
296 ENDIF
297 #endif
298 #endif /* ALLOW_USE_MPI */
299 northRecvAck(1,biS,bjS) = 1.
300 ELSEIF ( southCommMode .EQ. COMM_PUT ) THEN
301 DO I=1,myd1
302 arrayN(I,biS,bjS) = arrayS(I,bi,bj)
303 ENDDO
304 ELSEIF ( southCommMode .NE. COMM_NONE
305 & .AND. southCommMode .NE. COMM_GET ) THEN
306 STOP ' S/R EXCH: Invalid commS mode.'
307 ENDIF
308
309 C o Send or Put north edge
310 IF ( northCommMode .EQ. COMM_MSG ) THEN
311 C Send the data
312 #ifdef ALLOW_USE_MPI
313 #ifndef ALWAYS_USE_MPI
314 IF ( usingMPI ) THEN
315 #endif
316 theProc = tilePidN(bi,bj)
317 theTag = _tileTagSendN(bi,bj)
318 theSize = myd1
319 theType = MPI_DOUBLE_PRECISION
320 c exchVReqsY(1,bi,bj) = exchVReqsY(1,bi,bj)+1
321 exchNReqsY(1,bi,bj) = exchNReqsY(1,bi,bj)+1
322 CALL MPI_Isend(arrayN(1,bi,bj), theSize, theType,
323 & theProc, theTag, MPI_COMM_MODEL,
324 & exchReqIdY(exchNReqsY(1,bi,bj),1,bi,bj), mpiRc)
325 c & exchReqVIdY(exchVReqsY(1,bi,bj),1,bi,bj), mpiRc)
326 #ifndef ALWAYS_USE_MPI
327 ENDIF
328 #endif
329 #endif /* ALLOW_USE_MPI */
330 southRecvAck(1,biN,bjN) = 1.
331 ELSEIF ( northCommMode .EQ. COMM_PUT ) THEN
332 DO I=1,myd1
333 arrayS(I,biN,bjN) = arrayN(I,bi,bj)
334 ENDDO
335 ELSEIF ( northCommMode .NE. COMM_NONE
336 & .AND. northCommMode .NE. COMM_GET ) THEN
337 STOP ' S/R EXCH: Invalid commN mode.'
338 ENDIF
339
340 ENDDO
341 ENDDO
342
343 C-- Signal completetion ( making sure system-wide memory state is
344 C-- consistent ).
345
346 C ** NOTE ** We are relying on being able to produce strong-ordered
347 C memory semantics here. In other words we assume that there is a
348 C mechanism which can ensure that by the time the Ack is seen the
349 C overlap region data that will be exchanged is up to date.
350 IF ( exchNeedsMemSync ) CALL MEMSYNC
351
352 DO bj=myByLo(myThid),myByHi(myThid)
353 DO bi=myBxLo(myThid),myBxHi(myThid)
354 biN = _tileBiN(bi,bj)
355 bjN = _tileBjN(bi,bj)
356 biS = _tileBiS(bi,bj)
357 bjS = _tileBjS(bi,bj)
358 southCommMode = _tileCommModeE(bi,bj)
359 northCommMode = _tileCommModeN(bi,bj)
360 IF ( southCommMode .EQ. COMM_PUT ) northRecvAck(1,biS,bjS) = 1.
361 IF ( northCommMode .EQ. COMM_PUT ) southRecvAck(1,biN,bjN) = 1.
362 IF ( southCommMode .EQ. COMM_GET ) northRecvAck(1,biS,bjS) = 1.
363 IF ( northCommMode .EQ. COMM_GET ) southRecvAck(1,biN,bjN) = 1.
364 ENDDO
365 ENDDO
366
367 C-- Make sure "ack" setting is seen system-wide.
368 C Here strong-ordering is not an issue but we want to make
369 C sure that processes that might spin on the above Ack settings
370 C will see the setting.
371 C ** NOTE ** On some machines we wont spin on the Ack setting
372 C ( particularly the T90 ), instead we will use s system barrier.
373 C On the T90 the system barrier is very fast and switches out the
374 C thread while it waits. On most machines the system barrier
375 C is much too slow and if we own the machine and have one thread
376 C per process preemption is not a problem.
377 IF ( exchNeedsMemSync ) CALL MEMSYNC
378
379 RETURN
380 END
381
382 #else /* ALLOW_FLT */
383 SUBROUTINE EXCH_RL_SEND_PUT_VEC_X( myThid )
384 INTEGER myThid
385 RETURN
386 END
387 SUBROUTINE EXCH_RL_SEND_PUT_VEC_Y( myThid )
388 INTEGER myThid
389 RETURN
390 END
391 #endif /* ALLOW_FLT */

  ViewVC Help
Powered by ViewVC 1.1.22