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

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

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


Revision 1.15 - (show annotations) (download)
Mon Sep 3 19:39:25 2012 UTC (11 years, 7 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.14: +4 -1 lines
add "if usingMPI" test where needed

1 C $Header: /u/gcmpack/MITgcm/pkg/exch2/exch2_rx1_cube.template,v 1.14 2010/05/19 01:25:17 jmc Exp $
2 C $Name: $
3
4 #include "CPP_EEOPTIONS.h"
5
6 CBOP
7 C !ROUTINE: EXCH_RX_CUBE
8
9 C !INTERFACE:
10 SUBROUTINE EXCH2_RX1_CUBE(
11 U array,
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 Scalar field (1 component) Exchange:
19 C Fill-in tile-edge overlap-region of a 1 component scalar field
20 C with corresponding near-edge interior data point
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 array :: Array with edges to exchange.
35 C signOption :: Flag controlling whether field sign depends on orientation
36 C :: (signOption not yet implemented but needed for SM exch)
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 :: my Thread Id. number
44
45 INTEGER myOLw, myOLe, myOLs, myOLn, myNz
46 _RX array(1-myOLw:sNx+myOLe,
47 & 1-myOLs:sNy+myOLn,
48 & myNz, nSx, nSy)
49 LOGICAL signOption
50 CHARACTER*2 fieldCode
51 INTEGER exchWidthX
52 INTEGER exchWidthY
53 INTEGER cornerMode
54 INTEGER myThid
55
56 C !LOCAL VARIABLES:
57 C e2_msgHandles :: Synchronization and coordination data structure used to
58 C :: coordinate access to e2Bufr1_RX or to regulate message
59 C :: buffering. In PUT communication sender will increment
60 C :: handle entry once data is ready in buffer. Receiver will
61 C :: decrement handle once data is consumed from buffer.
62 C :: For MPI MSG communication MPI_Wait uses handle to check
63 C :: Isend has cleared. This is done in routine after receives.
64 C note: a) current implementation does not use e2_msgHandles for communication
65 C between threads: all-threads barriers are used (see CNH note below).
66 C For a 2-threads synchro communication (future version),
67 C e2_msgHandles should be shared (in common block, moved to BUFFER.h)
68 C b) 1rst dim=2 so that it could be used also by exch2_rx2_cube.
69 INTEGER bi, bj
70 C Variables for working through W2 topology
71 INTEGER e2_msgHandles( 2, W2_maxNeighbours, nSx, nSy )
72 INTEGER thisTile, farTile, N, nN, oN
73 INTEGER tIlo, tIhi, tJlo, tJhi, tKlo, tKhi
74 INTEGER tIStride, tJStride, tKStride
75 INTEGER i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi
76 LOGICAL updateCorners
77
78 #ifdef ALLOW_USE_MPI
79 INTEGER iBufr, nri, nrj
80 C MPI stuff (should be in a routine call)
81 INTEGER mpiStatus(MPI_STATUS_SIZE)
82 INTEGER mpiRc
83 INTEGER wHandle
84 #endif
85 CEOP
86
87 updateCorners = cornerMode .EQ. EXCH_UPDATE_CORNERS
88 C- Tile size of array to exchange:
89 i1Lo = 1-myOLw
90 i1Hi = sNx+myOLe
91 j1Lo = 1-myOLs
92 j1Hi = sNy+myOLn
93 k1Lo = 1
94 k1Hi = myNz
95
96 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
97
98 C Prevent anyone to access shared buffer while an other thread modifies it
99 CALL BAR2( myThid )
100
101 C-- Post sends into buffer (buffer level 1):
102 DO bj=myByLo(myThid), myByHi(myThid)
103 DO bi=myBxLo(myThid), myBxHi(myThid)
104 thisTile=W2_myTileList(bi,bj)
105 nN=exch2_nNeighbours(thisTile)
106 DO N=1,nN
107 farTile=exch2_neighbourId(N,thisTile)
108 oN = exch2_opposingSend(N,thisTile)
109 CALL EXCH2_GET_SCAL_BOUNDS(
110 I fieldCode, exchWidthX, updateCorners,
111 I farTile, oN,
112 O tIlo, tiHi, tjLo, tjHi,
113 O tiStride, tjStride,
114 I myThid )
115 tKLo=1
116 tKHi=myNz
117 tKStride=1
118 C- Put my points in buffer for neighbour N to fill points
119 C (tIlo:tIhi:tiStride,tJlo:tJhi,tJStride,tKlo:tKhi,tKStride)
120 C in its copy of "array".
121 CALL EXCH2_PUT_RX1(
122 I tIlo, tIhi, tiStride,
123 I tJlo, tJhi, tjStride,
124 I tKlo, tKhi, tkStride,
125 I thisTile, N,
126 I e2BufrRecSize,
127 O iBuf1Filled(N,bi,bj),
128 O e2Bufr1_RX(1,N,bi,bj,1),
129 I array(1-myOLw,1-myOLs,1,bi,bj),
130 I i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi,
131 O e2_msgHandles(1,N,bi,bj),
132 I W2_myCommFlag(N,bi,bj), myThid )
133 ENDDO
134 ENDDO
135 ENDDO
136
137 C Wait until all threads finish filling buffer
138 CALL BAR2( myThid )
139
140 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
141
142 #ifdef ALLOW_USE_MPI
143 IF ( usingMPI ) THEN
144
145 _BEGIN_MASTER( myThid )
146
147 C-- Send my data (in buffer, level 1) to target Process
148 DO bj=1,nSy
149 DO bi=1,nSx
150 thisTile=W2_myTileList(bi,bj)
151 nN=exch2_nNeighbours(thisTile)
152 DO N=1,nN
153 C- Skip the call if this is an internal exchange
154 IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
155 CALL EXCH2_SEND_RX1(
156 I thisTile, N,
157 I e2BufrRecSize,
158 I iBuf1Filled(N,bi,bj),
159 I e2Bufr1_RX(1,N,bi,bj,1),
160 O e2_msgHandles(1,N,bi,bj),
161 I W2_myCommFlag(N,bi,bj), myThid )
162 ENDIF
163 ENDDO
164 ENDDO
165 ENDDO
166
167 C-- Receive data (in buffer, level 2) from source Process
168 DO bj=1,nSy
169 DO bi=1,nSx
170 thisTile=W2_myTileList(bi,bj)
171 nN=exch2_nNeighbours(thisTile)
172 DO N=1,nN
173 C- Skip the call if this is an internal exchange
174 IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
175 CALL EXCH2_GET_SCAL_BOUNDS(
176 I fieldCode, exchWidthX, updateCorners,
177 I thisTile, N,
178 O tIlo, tiHi, tjLo, tjHi,
179 O tiStride, tjStride,
180 I myThid )
181 nri = 1 + (tIhi-tIlo)/tiStride
182 nrj = 1 + (tJhi-tJlo)/tjStride
183 iBufr = nri*nrj*myNz
184 C Receive from neighbour N to fill buffer and later on the array
185 CALL EXCH2_RECV_RX1(
186 I thisTile, N,
187 I e2BufrRecSize,
188 I iBufr,
189 O e2Bufr1_RX(1,N,bi,bj,2),
190 I W2_myCommFlag(N,bi,bj), myThid )
191 ENDIF
192 ENDDO
193 ENDDO
194 ENDDO
195
196 C-- Clear message handles/locks
197 DO bj=1,nSy
198 DO bi=1,nSx
199 thisTile=W2_myTileList(bi,bj)
200 nN=exch2_nNeighbours(thisTile)
201 DO N=1,nN
202 C Note: In a between process tile-tile data transport using
203 C MPI the sender needs to clear an Isend wait handle here.
204 C In a within process tile-tile data transport using true
205 C shared address space/or direct transfer through commonly
206 C addressable memory blocks the receiver needs to assert
207 C that he has consumed the buffer the sender filled here.
208 farTile=exch2_neighbourId(N,thisTile)
209 IF ( W2_myCommFlag(N,bi,bj) .EQ. 'M' ) THEN
210 wHandle = e2_msgHandles(1,N,bi,bj)
211 CALL MPI_Wait( wHandle, mpiStatus, mpiRc )
212 ELSEIF ( W2_myCommFlag(N,bi,bj) .EQ. 'P' ) THEN
213 ELSE
214 ENDIF
215 ENDDO
216 ENDDO
217 ENDDO
218
219 _END_MASTER( myThid )
220 C Everyone waits until master-thread finishes receiving
221 CALL BAR2( myThid )
222
223 ENDIF
224 #endif /* ALLOW_USE_MPI */
225
226 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
227
228 C-- Extract from buffer (either from level 1 if local exch,
229 C or level 2 if coming from an other Proc)
230 DO bj=myByLo(myThid), myByHi(myThid)
231 DO bi=myBxLo(myThid), myBxHi(myThid)
232 thisTile=W2_myTileList(bi,bj)
233 nN=exch2_nNeighbours(thisTile)
234 DO N=1,nN
235 CALL EXCH2_GET_SCAL_BOUNDS(
236 I fieldCode, exchWidthX, updateCorners,
237 I thisTile, N,
238 O tIlo, tiHi, tjLo, tjHi,
239 O tiStride, tjStride,
240 I myThid )
241 tKLo=1
242 tKHi=myNz
243 tKStride=1
244
245 C From buffer, get my points
246 C (tIlo:tIhi:tiStride,tJlo:tJhi,tJStride,tKlo:tKhi,tKStride) in "array":
247 C Note: when transferring data within a process:
248 C o e2Bufr entry to read is entry associated with opposing send record
249 C o e2_msgHandle entry to read is entry associated with opposing send record.
250 CALL EXCH2_GET_RX1(
251 I tIlo, tIhi, tiStride,
252 I tJlo, tJhi, tjStride,
253 I tKlo, tKhi, tkStride,
254 I thisTile, N, bi, bj,
255 I e2BufrRecSize, W2_maxNeighbours, nSx, nSy,
256 I e2Bufr1_RX,
257 U array(1-myOLw,1-myOLs,1,bi,bj),
258 I i1Lo, i1Hi, j1Lo, j1Hi, k1Lo, k1Hi,
259 U e2_msgHandles,
260 I W2_myCommFlag(N,bi,bj), myThid )
261 ENDDO
262 ENDDO
263 ENDDO
264
265 RETURN
266 END
267
268 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
269
270 CEH3 ;;; Local Variables: ***
271 CEH3 ;;; mode:fortran ***
272 CEH3 ;;; End: ***

  ViewVC Help
Powered by ViewVC 1.1.22