/[MITgcm]/MITgcm/eesupp/src/ini_procs.F
ViewVC logotype

Contents of /MITgcm/eesupp/src/ini_procs.F

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


Revision 1.7 - (show annotations) (download)
Wed Oct 28 03:11:35 1998 UTC (25 years, 7 months ago) by cnh
Branch: MAIN
CVS Tags: checkpoint17, checkpoint19, checkpoint18, checkpoint16
Changes since 1.6: +2 -2 lines
Changes to support
 - g77 compilation under Linux
 - LR(1) form of 64-bit is D or E for constants
 - Modified adjoint of exch with adjoint variables
   acuumulated.

1 #include "CPP_EEOPTIONS.h"
2 CStartOfInterface
3 SUBROUTINE INI_PROCS
4 C /==========================================================\
5 C | SUBROUTINE INI_PROCS |
6 C | o Initialise multiple concurrent processes environment. |
7 C |==========================================================|
8 C | Under MPI this routine calls various MPI service routines|
9 C | that map the model grid to MPI processes. The information|
10 C | is then stored in a common block for later use. |
11 C | Note: This routine can also be compiled with CPP |
12 C | directives set so that no multi-processing is initialise.|
13 C | This is OK and should work fine. |
14 C \==========================================================/
15
16 C === Global data ===
17 #include "SIZE.h"
18 #include "EEPARAMS.h"
19 #include "EESUPPORT.h"
20 CEndOfInterface
21
22 C === Local variables ===
23 #ifdef ALLOW_USE_MPI
24 C msgBuffer - IO buffer
25 C myThid - Dummy thread id
26 C mpiRC - Error code reporting variable used
27 C with MPI.
28 C mpiGridSpec - No. of processes in X and Y.
29 C mpiPeriodicity - Flag indicating XY priodicity to MPI.
30 C arrElSize - Size of an array element in bytes used
31 C to define MPI datatypes for communication
32 C operations.
33 C arrElSep - Separation in units of array elements between
34 C blocks to be communicated.
35 C elCount - No. of blocks that are associated with MPI
36 C datatype.
37 C elLen - Length of an MPI datatype in terms of preexisting
38 C datatype.
39 C elStride - Distance between starting location of elements
40 C in an MPI datatype - can be bytes of datatype
41 C units.
42 CHARACTER*(MAX_LEN_MBUF) msgBuffer
43 INTEGER mpiRC
44 INTEGER mpiGridSpec(2)
45 INTEGER mpiPeriodicity(2)
46 INTEGER mpiLProcNam
47 CHARACTER*(MPI_MAX_PROCESSOR_NAME) mpiProcNam
48 INTEGER arrElSize
49 INTEGER arrElSep
50 INTEGER elCount
51 INTEGER elLen
52 INTEGER elStride
53 #endif /* ALLOW_USE_MPI */
54 INTEGER myThid
55
56 C-- Default values set to single processor case
57 C pid[W-SE] are the MPI process id of the neighbor
58 C processes. A process can be its own neighbor!
59 myThid = 1
60 myPid = 1
61 nProcs = 1
62 myPx = 1
63 myPy = 1
64 myXGlobalLo = 1
65 myYGlobalLo = 1
66 pidW = 1
67 pidE = 1
68 pidN = 1
69 pidS = 1
70 errorMessageUnit = 0
71 standardMessageUnit = 6
72
73 #ifdef ALLOW_USE_MPI
74 C--
75 C-- MPI style full multiple-process initialisation
76 C-- ==============================================
77 #ifndef ALWAYS_USE_MPI
78 IF ( usingMPI ) THEN
79 #endif
80
81 C-- Arrange MPI processes on a cartesian grid
82 C Set variable indicating which MPI process is to the north,
83 C south, east, west, south-west, south-east, north-west
84 C and north-east of me e.g.
85 C
86 C Plan view of model domain centered on process ME
87 C ================================================
88 C
89 C : : : :
90 C : : : :
91 C : : : :
92 C .....------------------------------.....
93 C | | | |
94 C | NW | N | NE |
95 C | | | |
96 C .....------------------------------.....
97 C | | | |
98 C | W | ME | E |
99 C | | | |
100 C .....------------------------------.....
101 C | | | |
102 C | SW | S | SE |
103 C | | | |
104 C .....------------------------------.....
105 C : : : :
106 C Y : : : :
107 C / \ : : : :
108 C |
109 C |
110 C |----> X
111 C
112 C-- Set default MPI communicator to XY processor grid
113 myThid = 1
114 mpiGridSpec(1) = nPx
115 mpiGridSpec(2) = nPy
116 C Could be periodic in X and/or Y - set at run time or compile time!
117 mpiPeriodicity(1) = _mpiTRUE_
118 mpiPeriodicity(2) = _mpiTRUE_
119 #ifdef CAN_PREVENT_X_PERIODICITY
120 #ifndef ALWAYS_PREVENT_X_PERIODICITY
121 IF ( notUsingXPeriodicity ) THEN
122 #endif
123 mpiPeriodicity(1) = _mpiFALSE_
124 #ifndef ALWAYS_PREVENT_X_PERIODICITY
125 ENDIF
126 #endif
127 #endif /* CAN_PREVENT_X_PERIODICITY */
128 #ifdef CAN_PREVENT_Y_PERIODICITY
129 #ifndef ALWAYS_PREVENT_Y_PERIODICITY
130 IF ( notUsingYPeriodicity ) THEN
131 #endif
132 mpiPeriodicity(2) = _mpiFALSE_
133 #ifndef ALWAYS_PREVENT_Y_PERIODICITY
134 ENDIF
135 #endif
136 #endif /* CAN_PREVENT_Y_PERIODICITY */
137
138 CALL MPI_CART_CREATE(
139 I MPI_COMM_WORLD,2,mpiGridSpec,mpiPeriodicity,_mpiTRUE_,
140 O mpiComm, mpiRC )
141 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
142 eeBootError = .TRUE.
143 WRITE(msgBuffer,'(A,I)')
144 & 'S/R INI_PROCS: MPI_CART_CREATE return code',
145 & mpiRC
146 CALL PRINT_ERROR( msgBuffer , myThid)
147 GOTO 999
148 ENDIF
149
150 C-- Get my location on the grid
151 CALL MPI_CART_COORDS( mpiComm, mpiMyId, 2, mpiGridSpec, mpiRC )
152 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
153 eeBootError = .TRUE.
154 WRITE(msgBuffer,'(A,I)')
155 & 'S/R INI_PROCS: MPI_CART_COORDS return code',
156 & mpiRC
157 CALL PRINT_ERROR( msgBuffer , myThid)
158 GOTO 999
159 ENDIF
160 myPid = mpiMyId
161 mpiPx = mpiGridSpec(1)
162 mpiPy = mpiGridSpec(2)
163 mpiXGlobalLo = 1 + sNx*nSx*(mpiPx)
164 mpiYGlobalLo = 1 + sNy*nSy*(mpiPy)
165 myXGlobalLo = mpiXGlobalLo
166 myYGlobalLo = mpiYGlobalLo
167 myPx = mpiPx+1
168 myPy = mpiPy+1
169 C-- Get MPI id for neighboring procs.
170 mpiGridSpec(1) = mpiPx-1
171 IF ( mpiPeriodicity(1) .EQ. _mpiTRUE_ .AND. mpiGridSpec(1) .LT. 0 )
172 & mpiGridSpec(1) = nPx-1
173 mpiGridSpec(2) = mpiPy
174 CALL MPI_CART_RANK( mpiComm, mpiGridSpec, mpiPidW , mpiRC )
175 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
176 eeBootError = .TRUE.
177 WRITE(msgBuffer,'(A,I)')
178 & 'S/R INI_PROCS: MPI_CART_RANK (pidW) return code',
179 & mpiRC
180 CALL PRINT_ERROR( msgBuffer , myThid)
181 GOTO 999
182 ENDIF
183 pidW = mpiPidW
184 mpiGridSpec(1) = mpiPx+1
185 IF ( mpiPeriodicity(1) .EQ. _mpiTRUE_ .AND. mpiGridSpec(1) .GT. nPx-1 )
186 & mpiGridSpec(1) = 0
187 mpiGridSpec(2) = mpiPy
188 CALL MPI_CART_RANK( mpiComm, mpiGridSpec, mpiPidE , mpiRC )
189 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
190 eeBootError = .TRUE.
191 WRITE(msgBuffer,'(A,I)')
192 & 'S/R INI_PROCS: MPI_CART_RANK (pidE) return code',
193 & mpiRC
194 CALL PRINT_ERROR( msgBuffer , myThid)
195 GOTO 999
196 ENDIF
197 pidE = mpiPidE
198 mpiGridSpec(1) = mpiPx
199 mpiGridSpec(2) = mpiPy-1
200 IF ( mpiPeriodicity(2) .EQ. _mpiTRUE_ .AND. mpiGridSpec(2) .LT. 0 )
201 & mpiGridSpec(2) = nPy - 1
202 CALL MPI_CART_RANK( mpiComm, mpiGridSpec, mpiPidS , mpiRC )
203 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
204 eeBootError = .TRUE.
205 WRITE(msgBuffer,'(A,I)')
206 & 'S/R INI_PROCS: MPI_CART_RANK (pidS) return code',
207 & mpiRC
208 CALL PRINT_ERROR( msgBuffer , myThid)
209 GOTO 999
210 ENDIF
211 pidS = mpiPidS
212 mpiGridSpec(1) = mpiPx
213 mpiGridSpec(2) = mpiPy+1
214 IF ( mpiPeriodicity(2) .EQ. _mpiTRUE_ .AND. mpiGridSpec(2) .GT. nPy-1 )
215 & mpiGridSpec(2) = 0
216 CALL MPI_CART_RANK( mpiComm, mpiGridSpec, mpiPidN , mpiRC )
217 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
218 eeBootError = .TRUE.
219 WRITE(msgBuffer,'(A,I)')
220 & 'S/R INI_PROCS: MPI_CART_RANK (pidN) return code',
221 & mpiRC
222 CALL PRINT_ERROR( msgBuffer , myThid)
223 GOTO 999
224 ENDIF
225 pidN = mpiPidN
226
227 C-- Print summary of processor mapping on standard output
228 CALL MPI_GET_PROCESSOR_NAME( mpiProcNam, mpilProcNam, mpiRC )
229 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
230 eeBootError = .TRUE.
231 WRITE(msgBuffer,'(A,I)')
232 & 'S/R INI_PROCS: MPI_GET_PROCESSOR_NAME return code',
233 & mpiRC
234 CALL PRINT_ERROR( msgBuffer , myThid)
235 GOTO 999
236 ENDIF
237 WRITE(msgBuffer,'(A)') '======= Starting MPI parallel Run ========='
238 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
239 & SQUEEZE_BOTH , myThid)
240 WRITE(msgBuffer,'(A,A64)') ' My Processor Name = ',
241 & mpiProcNam(1:mpilProcNam)
242 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
243 & SQUEEZE_RIGHT , myThid)
244 WRITE(msgBuffer,'(A,I3,A,I3,A,I3,A,I3,A)') ' Located at (',
245 & mpiPx,',',mpiPy,
246 & ') on processor grid (0:',nPx-1,',0:',nPy-1,')'
247 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
248 & SQUEEZE_RIGHT , myThid)
249 WRITE(msgBuffer,'(A,I4,A,I4,A,I4,A,I4,A)') ' Origin at (',
250 & mpiXGlobalLo,',',mpiYGLobalLo,
251 & ') on global grid (1:',nPx*sNx*nSx,',1:',nPy*sNy*nSy,')'
252 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
253 & SQUEEZE_RIGHT , myThid)
254 WRITE(msgBuffer,'(A,I4.4)') ' North neighbor = processor ', mpiPidN
255 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
256 & SQUEEZE_RIGHT , myThid)
257 WRITE(msgBuffer,'(A,I4.4)') ' South neighbor = processor ', mpiPidS
258 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
259 & SQUEEZE_RIGHT , myThid)
260 WRITE(msgBuffer,'(A,I4.4)') ' East neighbor = processor ', mpiPidE
261 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
262 & SQUEEZE_RIGHT , myThid)
263 WRITE(msgBuffer,'(A,I4.4)') ' West neighbor = processor ', mpiPidW
264 CALL PRINT_MESSAGE( msgBuffer, standardMessageUnit,
265 & SQUEEZE_RIGHT , myThid)
266 C
267 C-- Create MPI types for transfer of array edges.
268 C-- Four and eight byte primitive (one block only) datatypes.
269 C-- These are common to all threads in the process.
270 C Notes:
271 C ======
272 C 1. The datatypes MPI_REAL4 and MPI_REAL8 are usually predefined.
273 C If they are not defined code must be added to create them -
274 C the MPI standard leaves optional whether they exist.
275 C 2. Per thread datatypes that handle all the edges for a thread
276 C are defined based on the type defined here.
277 C--
278 C-- xFace datatypes (east<-->west messages)
279 C--
280 C xFace (y=constant) for XY arrays with real*4 declaration.
281 arrElSep = (sNx+OLx*2)
282 elCount = sNy+OLy*2
283 elLen = OLx
284 elStride = arrElSep
285 CALL MPI_TYPE_VECTOR(elCount,elLen,elStride,MPI_REAL4,
286 & mpiTypeXFaceBlock_xy_r4, mpiRC)
287 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
288 eeBootError = .TRUE.
289 WRITE(msgBuffer,'(A,I)')
290 & 'S/R INI_PROCS: MPI_TYPE_VECTOR (mpiTypeXFaceBlock_xy_r4)',
291 & mpiRC
292 CALL PRINT_ERROR( msgBuffer , myThid)
293 ENDIF
294 CALL MPI_TYPE_COMMIT( mpiTypeXFaceBlock_xy_r4, mpiRC)
295 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
296 eeBootError = .TRUE.
297 WRITE(msgBuffer,'(A,I)')
298 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeXFaceBlock_xy_r4)',
299 & mpiRC
300 CALL PRINT_ERROR( msgBuffer , myThid)
301 ENDIF
302
303 C xFace (y=constant) for XY arrays with real*8 declaration.
304 CALL MPI_TYPE_VECTOR(elCount,elLen,elStride,MPI_REAL8,
305 & mpiTypeXFaceBlock_xy_r8, mpiRC)
306 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
307 eeBootError = .TRUE.
308 WRITE(msgBuffer,'(A,I)')
309 & 'S/R INI_PROCS: MPI_TYPE_VECTOR (mpiTypeXFaceBlock_xy_r8)',
310 & mpiRC
311 CALL PRINT_ERROR( msgBuffer , myThid)
312 ENDIF
313 CALL MPI_TYPE_COMMIT( mpiTypeXFaceBlock_xy_r8, mpiRC)
314 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
315 eeBootError = .TRUE.
316 WRITE(msgBuffer,'(A,I)')
317 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeXFaceBlock_xy_r8)',
318 & mpiRC
319 CALL PRINT_ERROR( msgBuffer , myThid)
320 ENDIF
321
322 C xFace (y=constant) for XYZ arrays with real*4 declaration.
323 arrElSize = 4
324 arrElSep = (sNx+OLx*2)*(sNy+OLy*2)
325 elCount = Nr
326 elLen = 1
327 elStride = arrElSize*arrElSep
328 CALL MPI_TYPE_HVECTOR(elCount,elLen,elStride,
329 & mpiTypeXFaceBlock_xy_r4,
330 & mpiTypeXFaceBlock_xyz_r4, mpiRC)
331 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
332 eeBootError = .TRUE.
333 WRITE(msgBuffer,'(A,I)')
334 & 'S/R INI_PROCS: MPI_TYPE_HVECTOR (mpiTypeXFaceBlock_xyz_r4)',
335 & mpiRC
336 CALL PRINT_ERROR( msgBuffer , myThid)
337 ENDIF
338 CALL MPI_TYPE_COMMIT( mpiTypeXFaceBlock_xyz_r4, mpiRC)
339 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
340 eeBootError = .TRUE.
341 WRITE(msgBuffer,'(A,I)')
342 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeXFaceBlock_xyz_r4)',
343 & mpiRC
344 CALL PRINT_ERROR( msgBuffer , myThid)
345 ENDIF
346
347 C xFace (y=constant) for XYZ arrays with real*8 declaration.
348 arrElSize = 8
349 elStride = arrElSize*arrElSep
350 CALL MPI_TYPE_HVECTOR(elCount,elLen,elStride,
351 & mpiTypeXFaceBlock_xy_r8,
352 & mpiTypeXFaceBlock_xyz_r8, mpiRC)
353 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
354 eeBootError = .TRUE.
355 WRITE(msgBuffer,'(A,I)')
356 & 'S/R INI_PROCS: MPI_TYPE_HVECTOR (mpiTypeXFaceBlock_xyz_r8)',
357 & mpiRC
358 CALL PRINT_ERROR( msgBuffer , myThid)
359 ENDIF
360 CALL MPI_TYPE_COMMIT( mpiTypeXFaceBlock_xyz_r8, mpiRC)
361 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
362 eeBootError = .TRUE.
363 WRITE(msgBuffer,'(A,I)')
364 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeXFaceBlock_xyz_r8)',
365 & mpiRC
366 CALL PRINT_ERROR( msgBuffer , myThid)
367 ENDIF
368 C--
369 C-- yFace datatypes (north<-->south messages)
370 C--
371 C yFace (x=constant) for XY arrays with real*4 declaration
372 elCount = OLy*(sNx+OLx*2)
373 CALL MPI_TYPE_CONTIGUOUS(elCount,MPI_REAL4,
374 & mpiTypeYFaceBlock_xy_r4, mpiRC)
375 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
376 eeBootError = .TRUE.
377 WRITE(msgBuffer,'(A,I)')
378 & 'S/R INI_PROCS: MPI_TYPE_CONTIGUOUS (mpiTypeYFaceBlock_xy_r4)',
379 & mpiRC
380 CALL PRINT_ERROR( msgBuffer , myThid)
381 ENDIF
382 CALL MPI_TYPE_COMMIT( mpiTypeYFaceBlock_xy_r4, mpiRC)
383 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
384 eeBootError = .TRUE.
385 WRITE(msgBuffer,'(A,I)')
386 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeYFaceBlock_xy_r4)',
387 & mpiRC
388 CALL PRINT_ERROR( msgBuffer , myThid)
389 ENDIF
390 C yFace (x=constant) for XY arrays with real*8 declaration
391 CALL MPI_TYPE_CONTIGUOUS(elCount,MPI_REAL8,
392 & mpiTypeYFaceBlock_xy_r8, mpiRC)
393 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
394 eeBootError = .TRUE.
395 WRITE(msgBuffer,'(A,I)')
396 & 'S/R INI_PROCS: MPI_TYPE_CONTIGUOUS (mpiTypeYFaceBlock_xy_r8)',
397 & mpiRC
398 CALL PRINT_ERROR( msgBuffer , myThid)
399 ENDIF
400 CALL MPI_TYPE_COMMIT( mpiTypeYFaceBlock_xy_r8, mpiRC)
401 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
402 eeBootError = .TRUE.
403 WRITE(msgBuffer,'(A,I)')
404 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeYFaceBlock_xy_r8)',
405 & mpiRC
406 CALL PRINT_ERROR( msgBuffer , myThid)
407 ENDIF
408 C yFace (x=constant) for XYZ arrays with real*4 declaration
409 arrElSize = 4
410 arrElSep = (sNx+OLx*2)*(sNy+OLy*2)
411 elCount = Nr
412 elLen = 1
413 elStride = arrElSize*arrElSep
414 CALL MPI_TYPE_HVECTOR(elCount,elLen,elStride,
415 & mpiTypeYFaceBlock_xy_r4,
416 & mpiTypeYFaceBlock_xyz_r4, mpiRC)
417 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
418 eeBootError = .TRUE.
419 WRITE(msgBuffer,'(A,I)')
420 & 'S/R INI_PROCS: MPI_TYPE_HVECTOR (mpiTypeYFaceBlock_xyz_r4)',
421 & mpiRC
422 CALL PRINT_ERROR( msgBuffer , myThid)
423 ENDIF
424 CALL MPI_TYPE_COMMIT( mpiTypeYFaceBlock_xyz_r4, mpiRC)
425 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
426 eeBootError = .TRUE.
427 WRITE(msgBuffer,'(A,I)')
428 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeYFaceBlock_xyz_r4)',
429 & mpiRC
430 CALL PRINT_ERROR( msgBuffer , myThid)
431 ENDIF
432 C yFace (x=constant) for XYZ arrays with real*8 declaration
433 arrElSize = 8
434 elStride = arrElSize*arrElSep
435 CALL MPI_TYPE_HVECTOR(elCount,elLen,elStride,
436 & mpiTypeYFaceBlock_xy_r8,
437 & mpiTypeYFaceBlock_xyz_r8, mpiRC)
438 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
439 eeBootError = .TRUE.
440 WRITE(msgBuffer,'(A,I)')
441 & 'S/R INI_PROCS: MPI_TYPE_HVECTOR (mpiTypeYFaceBlock_xyz_r8)',
442 & mpiRC
443 CALL PRINT_ERROR( msgBuffer , myThid)
444 ENDIF
445 CALL MPI_TYPE_COMMIT( mpiTypeYFaceBlock_xyz_r8, mpiRC)
446 IF ( mpiRC .NE. MPI_SUCCESS ) THEN
447 eeBootError = .TRUE.
448 WRITE(msgBuffer,'(A,I)')
449 & 'S/R INI_PROCS: MPI_TYPE_COMMIT (mpiTypeYFaceBlock_xyz_r8)',
450 & mpiRC
451 CALL PRINT_ERROR( msgBuffer , myThid)
452 ENDIF
453
454 C-- Assign MPI values used in generating unique tags for messages.
455 mpiTagW = 1
456 mpiTagE = 2
457 mpiTagS = 3
458 mpiTagN = 4
459
460 C
461 CALL MPI_Barrier(MPI_COMM_WORLD,mpiRC)
462
463
464 C
465 #ifndef ALWAYS_USE_MPI
466 ENDIF
467 #endif
468 #endif /* ALLOW_USE_MPI */
469
470 999 CONTINUE
471
472 RETURN
473 END
474
475 C $Id: ini_procs.F,v 1.6 1998/09/29 18:50:56 cnh Exp $

  ViewVC Help
Powered by ViewVC 1.1.22