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

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

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


Revision 1.10 - (show annotations) (download)
Thu Sep 6 16:13:53 2012 UTC (11 years, 7 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint65z, checkpoint65x, checkpoint65y, checkpoint65r, checkpoint65s, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint65j, checkpoint65k, checkpoint65h, checkpoint65i, checkpoint65n, checkpoint65l, checkpoint65m, checkpoint65b, checkpoint65c, checkpoint65a, checkpoint65f, checkpoint65g, checkpoint65d, checkpoint65e, checkpoint64, checkpoint65, checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, checkpoint65o, checkpoint64y, checkpoint64x, checkpoint64z, checkpoint64q, checkpoint64p, checkpoint64s, checkpoint64r, checkpoint64u, checkpoint64t, checkpoint64w, checkpoint64v, checkpoint64i, checkpoint64h, checkpoint64k, checkpoint64j, checkpoint64m, checkpoint64l, checkpoint64o, checkpoint64n, checkpoint64a, checkpoint64c, checkpoint64b, checkpoint64e, checkpoint64d, checkpoint64g, checkpoint64f, HEAD
Changes since 1.9: +51 -75 lines
- finish to remove ALWAYS_USE_MPI in source code that TAF does not see.
- rename S/R EXCH_RL_SEND_PUT_VEC_[X,Y] -> EXCH_SEND_PUT_VEC_[X,Y]_RL
     and S/R EXCH_RL_RECV_GET_VEC_[X,Y] -> EXCH_RECV_GET_VEC_[X,Y]_RL
  so that it closer to file names (exch_send_put_vec.F, exch_recv_get_vec.F)
  and match the printed messages.

1 C $Header: /u/gcmpack/MITgcm/pkg/flt/exch_recv_get_vec.F,v 1.9 2011/12/22 19:04:45 jmc Exp $
2 C $Name: $
3
4 #include "CPP_EEOPTIONS.h"
5 #undef EXCH_USE_SPINNING
6 #undef DBUG_EXCH_VEC
7
8 C-- Contents
9 C-- o EXCH_RECV_GET_VEC_X_RL
10 C-- o EXCH_RECV_GET_VEC_Y_RL
11
12 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
13 CBOP 0
14 C !ROUTINE: EXCH_RECV_GET_VEC_X_RL
15
16 C !INTERFACE:
17 SUBROUTINE EXCH_RECV_GET_VEC_X_RL(
18 U arrayE, arrayW,
19 I myd1, myThid )
20 C !DESCRIPTION:
21 C *==========================================================*
22 C | SUBROUTINE EXCH_RECV_GET_VEC_X_RL
23 C | o "Receive" or "Get" X edges for RL array.
24 C *==========================================================*
25 C | Routine that invokes actual message passing receive
26 C | of data to update buffer in X direction
27 C *==========================================================*
28
29 C !USES:
30 IMPLICIT NONE
31
32 C == Global variables ==
33 #include "SIZE.h"
34 #include "EEPARAMS.h"
35 #include "EESUPPORT.h"
36 #include "EXCH.h"
37
38 C !INPUT/OUTPUT PARAMETERS:
39 C arrayE :: buffer array to collect Eastern Neighbour values
40 C arrayW :: buffer array to collect Western Neighbour values
41 C myd1 :: size
42 C myThid :: my Thread Id. number
43 INTEGER myd1
44 _RL arrayE(myd1, nSx, nSy), arrayW(myd1, nSx, nSy)
45 INTEGER myThid
46 CEOP
47
48 C !LOCAL VARIABLES:
49 C bi, bj :: tile indices
50 C biW, bjW :: West tile indices
51 C biE, bjE :: East tile indices
52 C theProc :: Variables used in message building
53 C theTag :: Variables used in message building
54 C theType :: Variables used in message building
55 C theSize :: Variables used in message building
56 C westCommMode :: variables holding type of communication
57 C eastCommMode :: a particular tile face uses.
58 INTEGER bi, bj
59 c INTEGER biW, bjW, biE, bjE
60 INTEGER westCommMode
61 INTEGER eastCommMode
62 INTEGER ioUnit
63 #ifdef EXCH_USE_SPINNING
64 INTEGER spinCount
65 #endif
66 #ifdef ALLOW_USE_MPI
67 INTEGER theProc, theTag, theType, theSize
68 INTEGER mpiStatus(MPI_STATUS_SIZE,4), mpiRc
69 #endif
70
71 C-- Under a "put" scenario we
72 C-- i. set completetion signal for buffer we put into.
73 C-- ii. wait for completetion signal indicating data has been put in
74 C-- our buffer.
75 C-- Under a messaging mode we "receive" the message.
76 C-- Under a "get" scenario <= not implemented, we
77 C-- i. Check that the data is ready.
78 C-- ii. Read the data.
79 C-- iii. Set data read flag + memory sync.
80
81 ioUnit = errorMessageUnit
82
83 _BEGIN_MASTER(myThid)
84
85 DO bj=1,nSy
86 DO bi=1,nSx
87 westCommMode = _tileCommModeW(bi,bj)
88 eastCommMode = _tileCommModeE(bi,bj)
89 #ifdef DBUG_EXCH_VEC
90 write(ioUnit,'(A,5I6)') 'RECV_X,0 :',myProcId,bi,bj
91 #endif
92 c biE = _tileBiE(bi,bj)
93 c bjE = _tileBjE(bi,bj)
94 c biW = _tileBiW(bi,bj)
95 c bjW = _tileBjW(bi,bj)
96 IF ( westCommMode .EQ. COMM_MSG ) THEN
97 #ifdef ALLOW_USE_MPI
98 IF ( usingMPI ) THEN
99 theProc = tilePidW(bi,bj)
100 theTag = _tileTagRecvW(bi,bj)
101 theType = _MPI_TYPE_RL
102 theSize = myd1
103 #ifdef DBUG_EXCH_VEC
104 write(ioUnit,'(A,5I5,I8)') 'qq2xW: ',myProcId,bi,bj,
105 & theProc,theTag,theSize
106 #endif
107 CALL MPI_Recv( arrayW(1,bi,bj), theSize, theType,
108 & theProc, theTag, MPI_COMM_MODEL,
109 & mpiStatus, mpiRc )
110 c if (theProc .eq. 0 .or. theProc .eq. 2) then
111 c if (arrayW(1,bi,bj) .ne. 0.) then
112 c write(errormessageunit,*) 'qq2y: ',myProcId,
113 c & theProc,theTag,theSize,(arrayW(i,bi,bj),i=1,32)
114 c else
115 c write(errormessageunit,*) 'qq2n: ',myProcId,
116 c & theProc,theTag,theSize,(arrayW(i,bi,bj),i=1,32)
117 c endif
118 c endif
119 ENDIF
120 #endif /* ALLOW_USE_MPI */
121 ENDIF
122 #ifdef DBUG_EXCH_VEC
123 write(ioUnit,'(A,5I6)') 'RECV_X,1 :',myProcId,bi,bj
124 #endif
125
126 IF ( eastCommMode .EQ. COMM_MSG ) THEN
127 #ifdef ALLOW_USE_MPI
128 IF ( usingMPI ) THEN
129 theProc = tilePidE(bi,bj)
130 theTag = _tileTagRecvE(bi,bj)
131 theType = _MPI_TYPE_RL
132 theSize = myd1
133 #ifdef DBUG_EXCH_VEC
134 write(ioUnit,'(A,5I5,I8)') 'qq2xE: ',myProcId,bi,bj,
135 & theProc,theTag,theSize
136 #endif
137 CALL MPI_Recv( arrayE(1,bi,bj), theSize, theType,
138 & theProc, theTag, MPI_COMM_MODEL,
139 & mpiStatus, mpiRc )
140 ENDIF
141 #endif /* ALLOW_USE_MPI */
142 ENDIF
143 #ifdef DBUG_EXCH_VEC
144 write(ioUnit,'(A,5I6)') 'RECV_X,2 :',myProcId,bi,bj
145 #endif
146 ENDDO
147 ENDDO
148 #ifdef DBUG_EXCH_VEC
149 write(ioUnit,'(A,5I6,I12)') 'RECV_X:',myProcId
150 #endif
151
152 IF ( .NOT.exchUsesBarrier ) THEN
153 DO bj=1,nSy
154 DO bi=1,nSx
155 IF ( exchNReqsX(1,bi,bj) .GT. 0 ) THEN
156 #ifdef ALLOW_USE_MPI
157 IF ( usingMPI )
158 & CALL MPI_Waitall( exchNReqsX(1,bi,bj), exchReqIdX(1,1,bi,bj),
159 & mpiStatus, mpiRC )
160 #endif /* ALLOW_USE_MPI */
161 ENDIF
162 C Clear outstanding requests counter
163 exchNReqsX(1,bi,bj) = 0
164 ENDDO
165 ENDDO
166 ENDIF
167
168 _END_MASTER(myThid)
169
170 C-- need to sync threads after master has received data ;
171 C (done after mpi waitall in case waitall is really needed)
172 _BARRIER
173
174 C-- Threads wait for buffers I am going to read to be ready.
175 C note: added BARRIER in exch_send_put S/R and here above (message
176 C mode) so that we no longer needs this (undef EXCH_USE_SPINNING)
177 #ifdef EXCH_USE_SPINNING
178 IF ( exchUsesBarrier ) THEN
179 C o On some machines ( T90 ) use system barrier rather than spinning.
180 CALL BARRIER( myThid )
181 ELSE
182 C o Spin waiting for completetion flag. This avoids a global-lock
183 C i.e. we only lock waiting for data that we need.
184 DO bj=myByLo(myThid),myByHi(myThid)
185 DO bi=myBxLo(myThid),myBxHi(myThid)
186 spinCount = 0
187 westCommMode = _tileCommModeW(bi,bj)
188 eastCommMode = _tileCommModeE(bi,bj)
189 #ifdef DBUG_EXCH_VEC
190 write(ioUnit,'(A,5I6,I12)') 'spin:', myProcId,bi,bj,
191 & westRecvAck(1,bi,bj), eastRecvAck(1,bi,bj), spinCount
192 #endif
193 10 CONTINUE
194 CALL FOOL_THE_COMPILER( spinCount )
195 spinCount = spinCount+1
196 #ifdef DBUG_EXCH_VEC
197 write(ioUnit,'(A,5I6,I12)') 'spin:', myProcId,bi,bj,
198 & westRecvAck(1,bi,bj), eastRecvAck(1,bi,bj), spinCount
199 IF ( myThid.EQ.1 .AND. spinCount.GT. _EXCH_SPIN_LIMIT ) THEN
200 STOP ' S/R EXCH_RECV_GET_X: spinCount > _EXCH_SPIN_LIMIT'
201 ENDIF
202 #endif
203 IF ( westRecvAck(1,bi,bj) .EQ. 0 ) GOTO 10
204 IF ( eastRecvAck(1,bi,bj) .EQ. 0 ) GOTO 10
205 C Clear outstanding requests
206 westRecvAck(1,bi,bj) = 0
207 eastRecvAck(1,bi,bj) = 0
208 ENDDO
209 ENDDO
210 ENDIF
211 #endif /* EXCH_USE_SPINNING */
212
213 RETURN
214 END
215
216 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
217 CBOP 0
218 C !ROUTINE: EXCH_RECV_GET_VEC_Y_RL
219
220 C !INTERFACE:
221 SUBROUTINE EXCH_RECV_GET_VEC_Y_RL(
222 U arrayN, arrayS,
223 I myd1, myThid )
224 C !DESCRIPTION:
225 C *==========================================================*
226 C | SUBROUTINE EXCH_RECV_GET_VEC_Y_RL
227 C | o "Receive" or "Get" Y edges for RL array.
228 C *==========================================================*
229 C | Routine that invokes actual message passing receive
230 C | of data to update buffer in Y direction
231 C *==========================================================*
232
233 C !USES:
234 IMPLICIT NONE
235
236 C == Global variables ==
237 #include "SIZE.h"
238 #include "EEPARAMS.h"
239 #include "EESUPPORT.h"
240 #include "EXCH.h"
241
242 C !INPUT/OUTPUT PARAMETERS:
243 C arrayN :: buffer array to collect Northern Neighbour values
244 C arrayS :: buffer array to collect Southern Neighbour values
245 C myd1 :: size
246 C myThid :: my Thread Id. number
247 INTEGER myd1
248 _RL arrayN(myd1, nSx, nSy), arrayS(myd1, nSx, nSy)
249 INTEGER myThid
250 CEOP
251
252 C !LOCAL VARIABLES:
253 C bi, bj :: tile indices
254 C biS, bjS :: South tile indices
255 C biN, bjN :: North tile indices
256 C theProc :: Variables used in message building
257 C theTag :: Variables used in message building
258 C theType :: Variables used in message building
259 C theSize :: Variables used in message building
260 C southCommMode :: variables holding type of communication
261 C northCommMode :: a particular tile face uses.
262 INTEGER bi, bj
263 c INTEGER biS, bjS, biN, bjN
264 INTEGER southCommMode
265 INTEGER northCommMode
266 INTEGER ioUnit
267 #ifdef EXCH_USE_SPINNING
268 INTEGER spinCount
269 #endif
270 #ifdef ALLOW_USE_MPI
271 INTEGER theProc, theTag, theType, theSize
272 INTEGER mpiStatus(MPI_STATUS_SIZE,4), mpiRc
273 #endif
274
275 C-- Under a "put" scenario we
276 C-- i. set completetion signal for buffer we put into.
277 C-- ii. wait for completetion signal indicating data has been put in
278 C-- our buffer.
279 C-- Under a messaging mode we "receive" the message.
280 C-- Under a "get" scenario <= not implemented, we
281 C-- i. Check that the data is ready.
282 C-- ii. Read the data.
283 C-- iii. Set data read flag + memory sync.
284
285 ioUnit = errorMessageUnit
286
287 _BEGIN_MASTER(myThid)
288
289 DO bj=1,nSy
290 DO bi=1,nSx
291 southCommMode = _tileCommModeS(bi,bj)
292 northCommMode = _tileCommModeN(bi,bj)
293 #ifdef DBUG_EXCH_VEC
294 write(ioUnit,'(A,5I6)') 'RECV_Y,0 :',myProcId,bi,bj
295 #endif
296 c biN = _tileBiN(bi,bj)
297 c bjN = _tileBjN(bi,bj)
298 c biS = _tileBiS(bi,bj)
299 c bjS = _tileBjS(bi,bj)
300 IF ( southCommMode .EQ. COMM_MSG ) THEN
301 #ifdef ALLOW_USE_MPI
302 IF ( usingMPI ) THEN
303 theProc = tilePidS(bi,bj)
304 theTag = _tileTagRecvS(bi,bj)
305 theType = _MPI_TYPE_RL
306 theSize = myd1
307 CALL MPI_Recv( arrayS(1,bi,bj), theSize, theType,
308 & theProc, theTag, MPI_COMM_MODEL,
309 & mpiStatus, mpiRc )
310 ENDIF
311 #endif /* ALLOW_USE_MPI */
312 ENDIF
313 #ifdef DBUG_EXCH_VEC
314 write(ioUnit,'(A,5I6)') 'RECV_Y,1 :',myProcId,bi,bj
315 #endif
316
317 IF ( northCommMode .EQ. COMM_MSG ) THEN
318 #ifdef ALLOW_USE_MPI
319 IF ( usingMPI ) THEN
320 theProc = tilePidN(bi,bj)
321 theTag = _tileTagRecvN(bi,bj)
322 theType = _MPI_TYPE_RL
323 theSize = myd1
324 CALL MPI_Recv( arrayN(1,bi,bj), theSize, theType,
325 & theProc, theTag, MPI_COMM_MODEL,
326 & mpiStatus, mpiRc )
327 ENDIF
328 #endif /* ALLOW_USE_MPI */
329 ENDIF
330 #ifdef DBUG_EXCH_VEC
331 write(ioUnit,'(A,5I6)') 'RECV_Y,2 :',myProcId,bi,bj
332 #endif
333 ENDDO
334 ENDDO
335 #ifdef DBUG_EXCH_VEC
336 write(ioUnit,'(A,5I6,I12)') 'RECV_Y:',myProcId
337 #endif
338
339 C-- Processes wait for buffers I am going to read to be ready.
340 IF ( .NOT.exchUsesBarrier ) THEN
341 DO bj=1,nSy
342 DO bi=1,nSx
343 IF ( exchNReqsY(1,bi,bj) .GT. 0 ) THEN
344 #ifdef ALLOW_USE_MPI
345 IF ( usingMPI )
346 & CALL MPI_Waitall( exchNReqsY(1,bi,bj), exchReqIdY(1,1,bi,bj),
347 & mpiStatus, mpiRC )
348 #endif /* ALLOW_USE_MPI */
349 ENDIF
350 C Clear outstanding requests counter
351 exchNReqsY(1,bi,bj) = 0
352 ENDDO
353 ENDDO
354 ENDIF
355
356 _END_MASTER(myThid)
357
358 C-- need to sync threads after master has received data ;
359 C (done after mpi waitall in case waitall is really needed)
360 _BARRIER
361
362 C-- Threads wait for buffers I am going to read to be ready.
363 C note: added BARRIER in exch_send_put S/R and here above (message
364 C mode) so that we no longer needs this (undef EXCH_USE_SPINNING)
365 #ifdef EXCH_USE_SPINNING
366 IF ( exchUsesBarrier ) THEN
367 C o On some machines ( T90 ) use system barrier rather than spinning.
368 CALL BARRIER( myThid )
369 ELSE
370 C o Spin waiting for completetion flag. This avoids a global-lock
371 C i.e. we only lock waiting for data that we need.
372 DO bj=myByLo(myThid),myByHi(myThid)
373 DO bi=myBxLo(myThid),myBxHi(myThid)
374 spinCount = 0
375 southCommMode = _tileCommModeS(bi,bj)
376 northCommMode = _tileCommModeN(bi,bj)
377 #ifdef DBUG_EXCH_VEC
378 write(ioUnit,'(A,5I6,I12)') 'spin:', myProcId,bi,bj,
379 & southRecvAck(1,bi,bj), northRecvAck(1,bi,bj), spinCount
380 #endif
381 10 CONTINUE
382 CALL FOOL_THE_COMPILER( spinCount )
383 spinCount = spinCount+1
384 #ifdef DBUG_EXCH_VEC
385 write(ioUnit,'(A,5I6,I12)') 'spin:', myProcId,bi,bj,
386 & southRecvAck(1,bi,bj), northRecvAck(1,bi,bj), spinCount
387 IF ( myThid.EQ.1 .AND. spinCount.GT. _EXCH_SPIN_LIMIT ) THEN
388 STOP ' S/R EXCH_RECV_GET_X: spinCount > _EXCH_SPIN_LIMIT'
389 ENDIF
390 #endif
391 IF ( southRecvAck(1,bi,bj) .EQ. 0 ) GOTO 10
392 IF ( northRecvAck(1,bi,bj) .EQ. 0 ) GOTO 10
393 C Clear outstanding requests
394 southRecvAck(1,bi,bj) = 0
395 northRecvAck(1,bi,bj) = 0
396 ENDDO
397 ENDDO
398 ENDIF
399 #endif /* EXCH_USE_SPINNING */
400
401 RETURN
402 END

  ViewVC Help
Powered by ViewVC 1.1.22