/[MITgcm]/MITgcm/pkg/mdsio/mdsio_read_field.F
ViewVC logotype

Contents of /MITgcm/pkg/mdsio/mdsio_read_field.F

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


Revision 1.9 - (show annotations) (download)
Mon Jun 1 14:20:31 2009 UTC (15 years, 3 months ago) by jmc
Branch: MAIN
Changes since 1.8: +114 -57 lines
read/write tiled (local) files: read/write 1-level tile chunk at a time
 (instead of segment of length sNx); expected to speed up tiled IO.

1 C $Header: /u/gcmpack/MITgcm/pkg/mdsio/mdsio_read_field.F,v 1.8 2009/05/16 13:37:38 jmc Exp $
2 C $Name: $
3
4 #include "MDSIO_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: MDS_READ_FIELD
8 C !INTERFACE:
9 SUBROUTINE MDS_READ_FIELD(
10 I fName,
11 I filePrec,
12 I useCurrentDir,
13 I arrType,
14 I kSize,kLo,kHi,
15 O arr,
16 I irecord,
17 I myThid )
18
19 C !DESCRIPTION:
20 C Arguments:
21 C
22 C fName (string) :: base name for file to read
23 C filePrec (integer) :: number of bits per word in file (32 or 64)
24 C useCurrentDir(logic):: always read from the current directory (even if
25 C "mdsioLocalDir" is set)
26 C arrType (char(2)) :: declaration of "arr": either "RS" or "RL"
27 C kSize (integer) :: size of third dimension: normally either 1 or Nr
28 C kLo (integer) :: 1rst vertical level (of array "arr") to read-in
29 C kHi (integer) :: last vertical level (of array "arr") to read-in
30 C arr ( RS/RL ) :: array to read into, arr(:,:,kSize,:,:)
31 C irecord (integer) :: record number to read
32 C myIter (integer) :: time step number
33 C myThid (integer) :: thread identifier
34 C
35 C MDS_READ_FIELD first checks to see IF the file "fName" exists, then
36 C IF the file "fName.data" exists and finally the tiled files of the
37 C form "fName.xxx.yyy.data" exist. Currently, the meta-files are not
38 C read because it is difficult to parse files in fortran.
39 C The precision of the file is decsribed by filePrec, set either
40 C to floatPrec32 or floatPrec64. The precision or declaration of
41 C the array argument must be consistently described by the char*(2)
42 C string arrType, either "RS" or "RL".
43 C (kSize,kLo,kHi) allows for both 2-D and 3-D arrays to be handled, with
44 C the option to only read and fill-in a sub-set of consecutive vertical
45 C levels (from kLo to kHi) ; (kSize,kLo,kHi)=(1,1,1) implies a 2-D model
46 C field and (kSize,kLo,kHi)=(Nr,1,Nr) implies a 3-D model field.
47 C irecord is the record number to be read and must be >= 1.
48 C The file data is stored in arr *but* the overlaps are *not* updated,
49 C i.e., an exchange must be called. This is because the routine is
50 C sometimes called from within a MASTER_THID region.
51 C
52 C Created: 03/16/99 adcroft@mit.edu
53 CEOP
54
55 C !USES:
56 IMPLICIT NONE
57 C Global variables / common blocks
58 #include "SIZE.h"
59 #include "EEPARAMS.h"
60 #include "PARAMS.h"
61 #ifdef ALLOW_EXCH2
62 #include "W2_EXCH2_SIZE.h"
63 #include "W2_EXCH2_TOPOLOGY.h"
64 #include "W2_EXCH2_PARAMS.h"
65 #endif /* ALLOW_EXCH2 */
66 #include "EEBUFF_SCPU.h"
67
68 C !INPUT PARAMETERS:
69 CHARACTER*(*) fName
70 INTEGER filePrec
71 LOGICAL useCurrentDir
72 CHARACTER*(2) arrType
73 INTEGER kSize, kLo, kHi
74 INTEGER irecord
75 INTEGER myThid
76 C !OUTPUT PARAMETERS:
77 Real arr(*)
78
79 C !FUNCTIONS
80 INTEGER ILNBLNK
81 INTEGER MDS_RECLEN
82 LOGICAL MASTER_CPU_IO
83 EXTERNAL ILNBLNK
84 EXTERNAL MDS_RECLEN
85 EXTERNAL MASTER_CPU_IO
86
87 C !LOCAL VARIABLES:
88 CHARACTER*(MAX_LEN_FNAM) dataFName,pfName
89 CHARACTER*(MAX_LEN_MBUF) msgBuf
90 LOGICAL exst
91 LOGICAL globalFile, fileIsOpen
92 LOGICAL iAmDoingIO
93 LOGICAL useExch2ioLayOut
94 INTEGER xSize, ySize
95 INTEGER iG,jG,bi,bj,i,j,k,nNz
96 INTEGER irec,dUnit,IL,pIL
97 INTEGER length_of_rec
98 Real*4 r4seg(sNx)
99 Real*8 r8seg(sNx)
100 Real*4 r4loc(sNx,sNy)
101 Real*8 r8loc(sNx,sNy)
102 INTEGER tNx, tNy, global_nTx
103 INTEGER tBx, tBy, iGjLoc, jGjLoc
104 #ifdef ALLOW_EXCH2
105 INTEGER tN
106 #endif /* ALLOW_EXCH2 */
107
108 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
109 C Set dimensions:
110 xSize = Nx
111 ySize = Ny
112 useExch2ioLayOut = .FALSE.
113 #ifdef ALLOW_EXCH2
114 IF ( W2_useE2ioLayOut ) THEN
115 xSize = exch2_global_Nx
116 ySize = exch2_global_Ny
117 useExch2ioLayOut = .TRUE.
118 ENDIF
119 #endif /* ALLOW_EXCH2 */
120
121 C Assume nothing
122 globalFile = .FALSE.
123 fileIsOpen = .FALSE.
124 IL = ILNBLNK( fName )
125 pIL = ILNBLNK( mdsioLocalDir )
126 nNz = 1 + kHi - kLo
127
128 C Only do I/O if I am the master thread (and mpi process 0 IF useSingleCpuIO):
129 iAmDoingIO = MASTER_CPU_IO(myThid)
130
131 C Only do I/O if I am the master thread
132 IF ( iAmDoingIO ) THEN
133
134 C Record number must be >= 1
135 IF (irecord .LT. 1) THEN
136 WRITE(msgBuf,'(A,I9.8)')
137 & ' MDS_READ_FIELD: argument irecord = ',irecord
138 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
139 & SQUEEZE_RIGHT , myThid)
140 WRITE(msgBuf,'(A)')
141 & ' MDS_READ_FIELD: Invalid value for irecord'
142 CALL PRINT_ERROR( msgBuf, myThid )
143 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
144 ENDIF
145 C check for valid sub-set of levels:
146 IF ( kLo.LT.1 .OR. kHi.GT.kSize ) THEN
147 WRITE(msgBuf,'(3(A,I6))')
148 & ' MDS_READ_FIELD: arguments kSize=', kSize,
149 & ' , kLo=', kLo, ' , kHi=', kHi
150 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
151 & SQUEEZE_RIGHT , myThid)
152 WRITE(msgBuf,'(A)')
153 & ' MDS_READ_FIELD: invalid sub-set of levels'
154 CALL PRINT_ERROR( msgBuf, myThid )
155 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
156 ENDIF
157
158 C Assign special directory
159 IF ( useCurrentDir .OR. pIL.EQ.0 ) THEN
160 pfName= fName
161 ELSE
162 WRITE(pfName,'(2a)') mdsioLocalDir(1:pIL), fName(1:IL)
163 ENDIF
164 pIL=ILNBLNK( pfName )
165
166 C Assign a free unit number as the I/O channel for this routine
167 CALL MDSFINDUNIT( dUnit, myThid )
168
169 C Check first for global file with simple name (ie. fName)
170 dataFName = fName
171 INQUIRE( file=dataFName, exist=exst )
172 IF (exst) THEN
173 IF ( debugLevel .GE. debLevA ) THEN
174 WRITE(msgBuf,'(A,A)')
175 & ' MDS_READ_FIELD: opening global file: ',dataFName(1:IL)
176 #ifndef ALLOW_ECCO
177 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
178 & SQUEEZE_RIGHT , myThid)
179 #endif
180 ENDIF
181 globalFile = .TRUE.
182 ENDIF
183
184 C If negative check for global file with MDS name (ie. fName.data)
185 IF (.NOT. globalFile) THEN
186 WRITE(dataFName,'(2a)') fName(1:IL),'.data'
187 INQUIRE( file=dataFName, exist=exst )
188 IF (exst) THEN
189 IF ( debugLevel .GE. debLevA ) THEN
190 WRITE(msgBuf,'(A,A)')
191 & ' MDS_READ_FIELD: opening global file: ',dataFName(1:IL+5)
192 #ifndef ALLOW_ECCO
193 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
194 & SQUEEZE_RIGHT , myThid)
195 #endif
196 ENDIF
197 globalFile = .TRUE.
198 ENDIF
199 ENDIF
200
201 C- endif iAmDoingIO
202 ENDIF
203
204 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
205
206 IF ( useSingleCPUIO ) THEN
207
208 C master thread of process 0, only, opens a global file
209 IF ( iAmDoingIO ) THEN
210 C If global file is visible to process 0, then open it here.
211 C Otherwise stop program.
212 IF ( globalFile) THEN
213 length_of_rec = MDS_RECLEN( filePrec, xSize*ySize, myThid )
214 OPEN( dUnit, file=dataFName, status='old',
215 & access='direct', recl=length_of_rec )
216 ELSE
217 WRITE(msgBuf,'(2A)')
218 & ' MDS_READ_FIELD: filename: ', dataFName(1:IL+5)
219 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
220 & SQUEEZE_RIGHT , myThid)
221 CALL PRINT_ERROR( msgBuf, myThid )
222 WRITE(msgBuf,'(A)')
223 & ' MDS_READ_FIELD: File does not exist'
224 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
225 & SQUEEZE_RIGHT , myThid)
226 CALL PRINT_ERROR( msgBuf, myThid )
227 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
228 ENDIF
229 C- endif iAmDoingIO
230 ENDIF
231
232 DO k=kLo,kHi
233
234 C master thread of process 0, only, read from file
235 IF ( iAmDoingIO ) THEN
236 irec = 1 + k-kLo + (irecord-1)*nNz
237 IF (filePrec .EQ. precFloat32) THEN
238 READ(dUnit,rec=irec) ( xy_buffer_r4(i),i=1,xSize*ySize )
239 #ifdef _BYTESWAPIO
240 CALL MDS_BYTESWAPR4( xSize*ySize, xy_buffer_r4 )
241 #endif
242 ELSEIF (filePrec .EQ. precFloat64) THEN
243 READ(dUnit,rec=irec) ( xy_buffer_r8(i),i=1,xSize*ySize )
244 #ifdef _BYTESWAPIO
245 CALL MDS_BYTESWAPR8( xSize*ySize, xy_buffer_r8 )
246 #endif
247 ELSE
248 WRITE(msgBuf,'(A)')
249 & ' MDS_READ_FIELD: illegal value for filePrec'
250 CALL PRINT_ERROR( msgBuf, myThid )
251 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
252 ENDIF
253 C- endif iAmDoingIO
254 ENDIF
255
256 IF ( filePrec.EQ.precFloat32 ) THEN
257 CALL SCATTER_2D_R4(
258 U xy_buffer_r4,
259 O sharedLocBuf_r4,
260 I xSize, ySize,
261 I useExch2ioLayOut, .FALSE., myThid )
262 IF ( arrType.EQ.'RS' ) THEN
263 CALL MDS_PASS_R4toRS( sharedLocBuf_r4, arr,
264 I k, kSize, 0, 0, .TRUE., myThid )
265 ELSEIF ( arrType.EQ.'RL' ) THEN
266 CALL MDS_PASS_R4toRL( sharedLocBuf_r4, arr,
267 I k, kSize, 0, 0, .TRUE., myThid )
268 ELSE
269 WRITE(msgBuf,'(A)')
270 & ' MDS_READ_FIELD: illegal value for arrType'
271 CALL PRINT_ERROR( msgBuf, myThid )
272 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
273 ENDIF
274 ELSE
275 CALL SCATTER_2D_R8(
276 U xy_buffer_r8,
277 O sharedLocBuf_r8,
278 I xSize, ySize,
279 I useExch2ioLayOut, .FALSE., myThid )
280 IF ( arrType.EQ.'RS' ) THEN
281 CALL MDS_PASS_R8toRS( sharedLocBuf_r8, arr,
282 I k, kSize, 0, 0, .TRUE., myThid )
283 ELSEIF ( arrType.EQ.'RL' ) THEN
284 CALL MDS_PASS_R8toRL( sharedLocBuf_r8, arr,
285 I k, kSize, 0, 0, .TRUE., myThid )
286 ELSE
287 WRITE(msgBuf,'(A)')
288 & ' MDS_READ_FIELD: illegal value for arrType'
289 CALL PRINT_ERROR( msgBuf, myThid )
290 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
291 ENDIF
292 ENDIF
293
294 ENDDO
295 c ENDDO k=kLo,kHi
296
297 IF ( iAmDoingIO ) THEN
298 CLOSE( dUnit )
299 ENDIF
300
301 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
302 C--- else .NOT.useSingleCpuIO
303 ELSE
304
305 C Only do I/O if I am the master thread
306 IF ( iAmDoingIO ) THEN
307
308 C If we are reading from a global file then we open it here
309 IF (globalFile) THEN
310 length_of_rec = MDS_RECLEN( filePrec, sNx, myThid )
311 OPEN( dUnit, file=dataFName, status='old',
312 & access='direct', recl=length_of_rec )
313 fileIsOpen=.TRUE.
314 ENDIF
315
316 C Loop over all tiles
317 DO bj=1,nSy
318 DO bi=1,nSx
319
320 IF (globalFile) THEN
321 C--- Case of 1 Global file:
322
323 c IF (fileIsOpen) THEN
324 tNx = sNx
325 tNy = sNy
326 global_nTx = xSize/sNx
327 tBx = myXGlobalLo-1 + (bi-1)*sNx
328 tBy = myYGlobalLo-1 + (bj-1)*sNy
329 iGjLoc = 0
330 jGjLoc = 1
331 #ifdef ALLOW_EXCH2
332 IF ( useExch2ioLayOut ) THEN
333 tN = W2_myTileList(bi)
334 c tNx = exch2_tNx(tN)
335 c tNy = exch2_tNy(tN)
336 c global_nTx = exch2_global_Nx/tNx
337 tBx = exch2_txGlobalo(tN) - 1
338 tBy = exch2_tyGlobalo(tN) - 1
339 IF ( exch2_mydNx(tN) .GT. xSize ) THEN
340 C- face x-size larger than glob-size : fold it
341 iGjLoc = 0
342 jGjLoc = exch2_mydNx(tN) / xSize
343 ELSEIF ( exch2_tNy(tN) .GT. ySize ) THEN
344 C- tile y-size larger than glob-size : make a long line
345 iGjLoc = exch2_mydNx(tN)
346 jGjLoc = 0
347 ELSE
348 C- default (face fit into global-IO-array)
349 iGjLoc = 0
350 jGjLoc = 1
351 ENDIF
352 ENDIF
353 #endif /* ALLOW_EXCH2 */
354 DO k=kLo,kHi
355 DO j=1,tNy
356 irec = 1 + ( tBx + (j-1)*iGjLoc )/sNx
357 & + ( tBy + (j-1)*jGjLoc )*global_nTx
358 & +( k-kLo + (irecord-1)*nNz )*global_nTx*ySize
359 IF (filePrec .EQ. precFloat32) THEN
360 READ(dUnit,rec=irec) r4seg
361 #ifdef _BYTESWAPIO
362 CALL MDS_BYTESWAPR4( sNx, r4seg )
363 #endif
364 IF (arrType .EQ. 'RS') THEN
365 CALL MDS_SEG4toRS( j,bi,bj,k,kSize, r4seg, .TRUE., arr )
366 ELSEIF (arrType .EQ. 'RL') THEN
367 CALL MDS_SEG4toRL( j,bi,bj,k,kSize, r4seg, .TRUE., arr )
368 ELSE
369 WRITE(msgBuf,'(A)')
370 & ' MDS_READ_FIELD: illegal value for arrType'
371 CALL PRINT_ERROR( msgBuf, myThid )
372 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
373 ENDIF
374 ELSEIF (filePrec .EQ. precFloat64) THEN
375 READ(dUnit,rec=irec) r8seg
376 #ifdef _BYTESWAPIO
377 CALL MDS_BYTESWAPR8( sNx, r8seg )
378 #endif
379 IF (arrType .EQ. 'RS') THEN
380 CALL MDS_SEG8toRS( j,bi,bj,k,kSize, r8seg, .TRUE., arr )
381 ELSEIF (arrType .EQ. 'RL') THEN
382 CALL MDS_SEG8toRL( j,bi,bj,k,kSize, r8seg, .TRUE., arr )
383 ELSE
384 WRITE(msgBuf,'(A)')
385 & ' MDS_READ_FIELD: illegal value for arrType'
386 CALL PRINT_ERROR( msgBuf, myThid )
387 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
388 ENDIF
389 ELSE
390 WRITE(msgBuf,'(A)')
391 & ' MDS_READ_FIELD: illegal value for filePrec'
392 CALL PRINT_ERROR( msgBuf, myThid )
393 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
394 ENDIF
395 C End of j loop
396 ENDDO
397 C End of k loop
398 ENDDO
399
400 C end if fileIsOpen
401 c ENDIF
402
403 ELSE
404 C--- Case of 1 file per tile (globalFile=F):
405
406 C If we are reading from a tiled MDS file then we open each one here
407 iG=bi+(myXGlobalLo-1)/sNx
408 jG=bj+(myYGlobalLo-1)/sNy
409 WRITE(dataFName,'(2A,I3.3,A,I3.3,A)')
410 & pfName(1:pIL),'.',iG,'.',jG,'.data'
411 INQUIRE( file=dataFName, exist=exst )
412 C Of course, we only open the file if the tile is "active"
413 C (This is a place-holder for the active/passive mechanism
414 IF (exst) THEN
415 IF ( debugLevel .GE. debLevA ) THEN
416 WRITE(msgBuf,'(A,A)')
417 & ' MDS_READ_FIELD: opening file: ',dataFName(1:pIL+13)
418 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
419 & SQUEEZE_RIGHT , myThid)
420 ENDIF
421 length_of_rec = MDS_RECLEN( filePrec, sNx*sNy, myThid )
422 OPEN( dUnit, file=dataFName, status='old',
423 & access='direct', recl=length_of_rec )
424 fileIsOpen=.TRUE.
425 ELSE
426 fileIsOpen=.FALSE.
427 WRITE(msgBuf,'(4A)') ' MDS_READ_FIELD: filename: ',
428 & fName(1:IL),' , ', dataFName(1:pIL+13)
429 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
430 & SQUEEZE_RIGHT , myThid)
431 CALL PRINT_ERROR( msgBuf, myThid )
432 WRITE(msgBuf,'(A)')
433 & ' MDS_READ_FIELD: Files DO not exist'
434 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
435 & SQUEEZE_RIGHT , myThid)
436 CALL PRINT_ERROR( msgBuf, myThid )
437 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
438 ENDIF
439
440 DO k=kLo,kHi
441
442 irec = 1 + k-kLo + (irecord-1)*nNz
443 IF (filePrec .EQ. precFloat32) THEN
444 READ(dUnit,rec=irec) r4loc
445 #ifdef _BYTESWAPIO
446 CALL MDS_BYTESWAPR4( sNx*sNy, r4loc )
447 #endif
448 IF ( arrType.EQ.'RS' ) THEN
449 CALL MDS_PASS_R4toRS( r4loc, arr,
450 I k, kSize, bi,bj, .TRUE., myThid )
451 ELSEIF ( arrType.EQ.'RL' ) THEN
452 CALL MDS_PASS_R4toRL( r4loc, arr,
453 I k, kSize, bi,bj, .TRUE., myThid )
454 ELSE
455 WRITE(msgBuf,'(A)')
456 & ' MDS_READ_FIELD: illegal value for arrType'
457 CALL PRINT_ERROR( msgBuf, myThid )
458 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
459 ENDIF
460 ELSEIF (filePrec .EQ. precFloat64) THEN
461 READ(dUnit,rec=irec) r8loc
462 #ifdef _BYTESWAPIO
463 CALL MDS_BYTESWAPR8( sNx*sNy, r8loc )
464 #endif
465 IF ( arrType.EQ.'RS' ) THEN
466 CALL MDS_PASS_R8toRS( r8loc, arr,
467 I k, kSize, bi,bj, .TRUE., myThid )
468 ELSEIF ( arrType.EQ.'RL' ) THEN
469 CALL MDS_PASS_R8toRL( r8loc, arr,
470 I k, kSize, bi,bj, .TRUE., myThid )
471 ELSE
472 WRITE(msgBuf,'(A)')
473 & ' MDS_READ_FIELD: illegal value for arrType'
474 CALL PRINT_ERROR( msgBuf, myThid )
475 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
476 ENDIF
477 ELSE
478 WRITE(msgBuf,'(A)')
479 & ' MDS_READ_FIELD: illegal value for filePrec'
480 CALL PRINT_ERROR( msgBuf, myThid )
481 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
482 ENDIF
483
484 C End of k loop
485 ENDDO
486
487 C here We close the tiled MDS file
488 IF ( fileIsOpen ) THEN
489 CLOSE( dUnit )
490 fileIsOpen = .FALSE.
491 ENDIF
492
493 C--- End Global File / tile-file cases
494 ENDIF
495
496 C End of bi,bj loops
497 ENDDO
498 ENDDO
499
500 C If global file was opened then close it
501 IF (fileIsOpen .AND. globalFile) THEN
502 CLOSE( dUnit )
503 fileIsOpen = .FALSE.
504 ENDIF
505
506 C- endif iAmDoingIO
507 ENDIF
508
509 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
510 C if useSingleCpuIO / else / end
511 ENDIF
512
513 RETURN
514 END

  ViewVC Help
Powered by ViewVC 1.1.22