/[MITgcm]/MITgcm/pkg/exch2/exch2_rx2_cube_ad.template
ViewVC logotype

Contents of /MITgcm/pkg/exch2/exch2_rx2_cube_ad.template

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


Revision 1.13 - (show annotations) (download)
Mon Sep 3 19:39:25 2012 UTC (11 years, 9 months ago) by jmc
Branch: MAIN
CVS Tags: 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, checkpoint63s, checkpoint64, checkpoint65, checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, checkpoint65z, checkpoint65x, checkpoint65y, checkpoint65r, checkpoint65s, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint65j, checkpoint65k, checkpoint65h, checkpoint65i, checkpoint65n, checkpoint65o, checkpoint65l, checkpoint65m, checkpoint65b, checkpoint65c, checkpoint65a, checkpoint65f, checkpoint65g, checkpoint65d, checkpoint65e, HEAD
Changes since 1.12: +3 -2 lines
add "if usingMPI" test where needed

1 C $Header: /u/gcmpack/MITgcm/pkg/exch2/exch2_rx2_cube_ad.template,v 1.12 2012/03/26 19:13:15 jmc Exp $
2 C $Name: $
3
4 #include "CPP_EEOPTIONS.h"
5
6 CBOP
7 C !ROUTINE: EXCH_RX2_CUBE_AD
8
9 C !INTERFACE:
10 SUBROUTINE EXCH2_RX2_CUBE_AD(
11 U array1, array2,
12 I signOption, fieldCode,
13 I myOLw, myOLe, myOLs, myOLn, myNz,
14 I exchWidthX, exchWidthY,
15 I cornerMode, myThid )
16
17 C !DESCRIPTION:
18 C Two components vector field AD-Exchange:
19 C Tile-edge overlap-region of a 2 component vector field is added to
20 C corresponding near-edge interior data point and then zero out.
21
22 C !USES:
23 IMPLICIT NONE
24
25 C == Global data ==
26 #include "SIZE.h"
27 #include "EEPARAMS.h"
28 #include "EESUPPORT.h"
29 #include "W2_EXCH2_SIZE.h"
30 #include "W2_EXCH2_TOPOLOGY.h"
31 #include "W2_EXCH2_BUFFER.h"
32
33 C !INPUT/OUTPUT PARAMETERS:
34 C array1 :: 1rst component array with edges to exchange.
35 C array2 :: 2nd component array with edges to exchange.
36 C signOption :: Flag controlling whether vector is signed.
37 C fieldCode :: field code (position on staggered grid)
38 C myOLw,myOLe :: West and East overlap region sizes.
39 C myOLs,myOLn :: South and North overlap region sizes.
40 C exchWidthX :: Width of data region exchanged in X.
41 C exchWidthY :: Width of data region exchanged in Y.
42 C cornerMode :: halo-corner-region treatment: update/ignore corner region
43 C myThid :: Thread number of this instance of S/R EXCH...
44
45 INTEGER myOLw, myOLe, myOLs, myOLn, myNz
46 _RX array1(1-myOLw:sNx+myOLe,
47 & 1-myOLs:sNy+myOLn,
48 & myNz, nSx, nSy)
49 _RX array2(1-myOLw:sNx+myOLe,
50 & 1-myOLs:sNy+myOLn,
51 & myNz, nSx, nSy)
52 LOGICAL signOption
53 CHARACTER*2 fieldCode
54 INTEGER exchWidthX
55 INTEGER exchWidthY
56 INTEGER cornerMode
57 INTEGER myThid
58
59 C !LOCAL VARIABLES:
60 C e2_msgHandles :: Synchronization and coordination data structure used to
61 C :: coordinate access to e2Bufr1_RX or to regulate message
62 C :: buffering. In PUT communication sender will increment
63 C :: handle entry once data is ready in buffer. Receiver will
64 C :: decrement handle once data is consumed from buffer.
65 C :: For MPI MSG communication MPI_Wait uses handle to check
66 C :: Isend has cleared. This is done in routine after receives.
67 C note: a) current implementation does not use e2_msgHandles for communication
68 C between threads: all-threads barriers are used (see CNH note below).
69 C For a 2-threads synchro communication (future version),
70 C e2_msgHandles should be shared (in common block, moved to BUFFER.h)
71 INTEGER bi, bj
72 C Variables for working through W2 topology
73 INTEGER e2_msgHandles( 2, W2_maxNeighbours, nSx, nSy )
74 INTEGER thisTile, farTile, N, nN, oN
75 INTEGER tIlo1, tIhi1, tJlo1, tJhi1, oIs1, oJs1
76 INTEGER tIlo2, tIhi2, tJlo2, tJhi2, oIs2, oJs2
77 INTEGER tIStride, tJStride
78 INTEGER tKlo, tKhi, tKStride
79 INTEGER i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi
80 INTEGER i2Lo, i2Hi, j2Lo, j2Hi, k2Lo, k2Hi
81 LOGICAL updateCorners
82
83 #ifdef ALLOW_USE_MPI
84 INTEGER iBufr1, iBufr2, nri, nrj
85 C MPI stuff (should be in a routine call)
86 INTEGER mpiStatus(MPI_STATUS_SIZE)
87 INTEGER mpiRc
88 INTEGER wHandle
89 #endif
90 CEOP
91
92 updateCorners = cornerMode .EQ. EXCH_UPDATE_CORNERS
93 C- Tile size of arrays to exchange:
94 i1Lo = 1-myOLw
95 i1Hi = sNx+myOLe
96 j1Lo = 1-myOLs
97 j1Hi = sNy+myOLn
98 k1Lo = 1
99 k1Hi = myNz
100 i2Lo = 1-myOLw
101 i2Hi = sNx+myOLe
102 j2Lo = 1-myOLs
103 j2Hi = sNy+myOLn
104 k2Lo = 1
105 k2Hi = myNz
106
107 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
108
109 C Prevent anyone to access shared buffer while an other thread modifies it
110 CALL BAR2( myThid )
111
112 C-- Extract from buffer (either from level 1 if local exch,
113 C or level 2 if coming from an other Proc)
114 C AD: = fill buffer from my-tile-edge overlap-region, level 1 or 2 depending
115 C AD: on local (to this Proc) or remote Proc tile destination
116 DO bj=myByLo(myThid), myByHi(myThid)
117 DO bi=myBxLo(myThid), myBxHi(myThid)
118 thisTile=W2_myTileList(bi,bj)
119 nN=exch2_nNeighbours(thisTile)
120 DO N=1,nN
121 CALL EXCH2_GET_UV_BOUNDS(
122 I fieldCode, exchWidthX, updateCorners,
123 I thisTile, N,
124 O tIlo1, tIhi1, tJlo1, tJhi1,
125 O tIlo2, tIhi2, tJlo2, tJhi2,
126 O tiStride, tjStride,
127 O oIs1, oJs1, oIs2, oJs2,
128 I myThid )
129 tKLo=1
130 tKHi=myNz
131 tKStride=1
132
133 C From buffer, get my points
134 C (tIlo:tIhi:tiStride,tJlo:tJhi,tJStride,tKlo:tKhi,tKStride) in "array1,2":
135 C Note: when transferring data within a process:
136 C o e2Bufr entry to read is entry associated with opposing send record
137 C o e2_msgHandle entry to read is entry associated with opposing send record.
138 CALL EXCH2_AD_GET_RX2(
139 I tIlo1, tIhi1, tIlo2, tIhi2, tiStride,
140 I tJlo1, tJhi1, tJlo2, tJhi2, tjStride,
141 I tKlo, tKhi, tkStride,
142 I thisTile, N, bi, bj,
143 I e2BufrRecSize, W2_maxNeighbours, nSx, nSy,
144 O iBuf1Filled(N,bi,bj), iBuf2Filled(N,bi,bj),
145 O e2Bufr1_RX, e2Bufr2_RX,
146 U array1(1-myOLw,1-myOLs,1,bi,bj),
147 U array2(1-myOLw,1-myOLs,1,bi,bj),
148 I i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi,
149 I i2Lo, i2Hi, j2Lo, j2Hi, k2Lo, k2Hi,
150 U e2_msgHandles,
151 I W2_myCommFlag(N,bi,bj), myThid )
152 ENDDO
153 ENDDO
154 ENDDO
155
156 C Wait until all threads finish filling buffer
157 CALL BAR2( myThid )
158
159 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
160
161 #ifdef ALLOW_USE_MPI
162 IF ( usingMPI ) THEN
163 C AD: all MPI part is acting on buffer and is identical to forward code,
164 C AD: except a) the buffer level: send from lev.2, receive into lev.1
165 C AD: b) the length of transferred buffer (<- match the ad_put/ad_get)
166
167 _BEGIN_MASTER( myThid )
168
169 C-- Send my data (in buffer, level 1) to target Process
170 DO bj=1,nSy
171 DO bi=1,nSx
172 thisTile=W2_myTileList(bi,bj)
173 nN=exch2_nNeighbours(thisTile)
174 DO N=1,nN
175 C- Skip the call if this is an internal exchange
176 IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
177 CALL EXCH2_SEND_RX2(
178 I thisTile, N,
179 I e2BufrRecSize,
180 I iBuf1Filled(N,bi,bj), iBuf2Filled(N,bi,bj),
181 I e2Bufr1_RX(1,N,bi,bj,2), e2Bufr2_RX(1,N,bi,bj,2),
182 O e2_msgHandles(1,N,bi,bj),
183 I W2_myCommFlag(N,bi,bj), myThid )
184 ENDIF
185 ENDDO
186 ENDDO
187 ENDDO
188
189 C-- Receive data (in buffer, level 1) from source Process
190 DO bj=1,nSy
191 DO bi=1,nSx
192 thisTile=W2_myTileList(bi,bj)
193 nN=exch2_nNeighbours(thisTile)
194 DO N=1,nN
195 C- Skip the call if this is an internal exchange
196 IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
197 farTile=exch2_neighbourId(N,thisTile)
198 oN = exch2_opposingSend(N,thisTile)
199 CALL EXCH2_GET_UV_BOUNDS(
200 I fieldCode, exchWidthX, updateCorners,
201 I farTile, oN,
202 O tIlo1, tIhi1, tJlo1, tJhi1,
203 O tIlo2, tIhi2, tJlo2, tJhi2,
204 O tiStride, tjStride,
205 O oIs1, oJs1, oIs2, oJs2,
206 I myThid )
207 nri = 1 + (tIhi1-tIlo1)/tiStride
208 nrj = 1 + (tJhi1-tJlo1)/tjStride
209 iBufr1 = nri*nrj*myNz
210 nri = 1 + (tIhi2-tIlo2)/tiStride
211 nrj = 1 + (tJhi2-tJlo2)/tjStride
212 iBufr2 = nri*nrj*myNz
213 C Receive from neighbour N to fill buffer and later on the array
214 CALL EXCH2_RECV_RX2(
215 I thisTile, N,
216 I e2BufrRecSize,
217 I iBufr1, iBufr2,
218 I e2Bufr1_RX(1,N,bi,bj,1), e2Bufr2_RX(1,N,bi,bj,1),
219 I W2_myCommFlag(N,bi,bj), myThid )
220 ENDIF
221 ENDDO
222 ENDDO
223 ENDDO
224
225 C-- Clear message handles/locks
226 DO bj=1,nSy
227 DO bi=1,nSx
228 thisTile=W2_myTileList(bi,bj)
229 nN=exch2_nNeighbours(thisTile)
230 DO N=1,nN
231 C Note: In a between process tile-tile data transport using
232 C MPI the sender needs to clear an Isend wait handle here.
233 C In a within process tile-tile data transport using true
234 C shared address space/or direct transfer through commonly
235 C addressable memory blocks the receiver needs to assert
236 C that he has consumed the buffer the sender filled here.
237 farTile=exch2_neighbourId(N,thisTile)
238 IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
239 wHandle = e2_msgHandles(1,N,bi,bj)
240 CALL MPI_Wait( wHandle, mpiStatus, mpiRc )
241 wHandle = e2_msgHandles(2,N,bi,bj)
242 CALL MPI_Wait( wHandle, mpiStatus, mpiRc )
243 ELSEIF ( W2_myCommFlag(N,bi,bj) .EQ. 'P' ) THEN
244 ELSE
245 ENDIF
246 ENDDO
247 ENDDO
248 ENDDO
249
250 _END_MASTER( myThid )
251 C Everyone waits until master-thread finishes receiving
252 CALL BAR2( myThid )
253
254 ENDIF
255 #endif /* ALLOW_USE_MPI */
256
257 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
258
259 C-- Post sends into buffer (buffer level 1):
260 DO bj=myByLo(myThid), myByHi(myThid)
261 DO bi=myBxLo(myThid), myBxHi(myThid)
262 thisTile=W2_myTileList(bi,bj)
263 nN=exch2_nNeighbours(thisTile)
264 DO N=1,nN
265 farTile=exch2_neighbourId(N,thisTile)
266 oN = exch2_opposingSend(N,thisTile)
267 CALL EXCH2_GET_UV_BOUNDS(
268 I fieldCode, exchWidthX, updateCorners,
269 I farTile, oN,
270 O tIlo1, tIhi1, tJlo1, tJhi1,
271 O tIlo2, tIhi2, tJlo2, tJhi2,
272 O tiStride, tjStride,
273 O oIs1, oJs1, oIs2, oJs2,
274 I myThid )
275 tKLo=1
276 tKHi=myNz
277 tKStride=1
278 C- Put my points in buffer for neighbour N to fill points
279 C (tIlo:tIhi:tiStride,tJlo:tJhi,tJStride,tKlo:tKhi,tKStride)
280 C in its copy of "array1" & "array2".
281 CALL EXCH2_AD_PUT_RX2(
282 I tIlo1, tIhi1, tIlo2, tIhi2, tiStride,
283 I tJlo1, tJhi1, tJlo2, tJhi2, tjStride,
284 I tKlo, tKhi, tkStride,
285 I oIs1, oJs1, oIs2, oJs2,
286 I thisTile, N,
287 I e2BufrRecSize,
288 O e2Bufr1_RX(1,N,bi,bj,1), e2Bufr2_RX(1,N,bi,bj,1),
289 I array1(1-myOLw,1-myOLs,1,bi,bj),
290 I array2(1-myOLw,1-myOLs,1,bi,bj),
291 I i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi,
292 I i2Lo, i2Hi, j2Lo, j2Hi, k2Lo, k2Hi,
293 O e2_msgHandles(1,N,bi,bj),
294 I W2_myCommFlag(N,bi,bj), signOption, myThid )
295 ENDDO
296 ENDDO
297 ENDDO
298
299 RETURN
300 END
301
302 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
303
304 CEH3 ;;; Local Variables: ***
305 CEH3 ;;; mode:fortran ***
306 CEH3 ;;; End: ***

  ViewVC Help
Powered by ViewVC 1.1.22