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

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

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


Revision 1.1 - (show annotations) (download)
Thu Oct 17 00:30:46 2013 UTC (10 years, 6 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint64y, checkpoint64x, checkpoint64z, checkpoint64q, checkpoint64p, checkpoint64s, checkpoint64r, checkpoint64u, checkpoint64t, checkpoint64w, checkpoint64v, 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, checkpoint65, HEAD
- rewrite/simplify tape-IO S/R (new S/R MDS_READ/WRITE_TAPE replace
  previous MDSREAD/WRITEVECTOR) with 2 array argument from each type (R4/R8);
- fix globalFile and singleCpuIO options using simpler global mapping.

1 C $Header: /u/gcmpack/MITgcm/pkg/mdsio/mdsio_writevector.F,v 1.15 2013/01/13 22:43:53 jmc Exp $
2 C $Name: $
3
4 #include "MDSIO_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: MDS_WRITE_TAPE
8 C !INTERFACE:
9 SUBROUTINE MDS_WRITE_TAPE(
10 I fName,
11 I filePrec,
12 I globalfile,
13 I arrType,
14 I nSize,
15 I fldR8, fldR4,
16 I singleCpuIO,
17 I iRec,
18 I myIter,
19 I myThid )
20
21 C !DESCRIPTION:
22 C MDS_WRITE_TAPE: write an array (treated as vector) to a tape-file
23 C (renamed from MDSWRITEVECTOR with 2 explicit input array types)
24 C
25 C Arguments:
26 C fName string :: base name for file to write
27 C filePrec integer :: number of bits per word in file (32 or 64)
28 C globalFile logical :: selects between writing a global or tiled file
29 C arrType char(2) :: which array (fldR8/R4) to write, either "R8" or "R4"
30 C nSize integer :: number of elements of input array "fldR8/R4" to write
31 C fldR8 ( R8 ) :: array to write if arrType="R8", fldR8(nSize)
32 C fldR4 ( R4 ) :: array to write if arrType="R4", fldR4(nSize)
33 C bi,bj integer :: tile indices (if tiled array)
34 C singleCpuIO ( L ) :: only proc 0 do IO and collect data from other procs
35 C iRec integer :: record number to write
36 C myIter integer :: time step number
37 C myThid integer :: my Thread Id number
38
39 C !USES:
40 IMPLICIT NONE
41
42 C-- Global variables --
43 #include "SIZE.h"
44 #include "EEPARAMS.h"
45 #include "PARAMS.h"
46
47 C !INPUT/OUTPUT PARAMETERS:
48 CHARACTER*(*) fName
49 INTEGER filePrec
50 LOGICAL globalfile
51 CHARACTER*(2) arrType
52 INTEGER nSize
53 _R8 fldR8(*)
54 _R4 fldR4(*)
55 LOGICAL singleCpuIO
56 INTEGER iRec
57 INTEGER myIter
58 INTEGER myThid
59
60 #ifdef ALLOW_AUTODIFF
61
62 C !FUNCTIONS:
63 INTEGER ILNBLNK
64 INTEGER MDS_RECLEN
65 EXTERNAL ILNBLNK
66 EXTERNAL MDS_RECLEN
67
68 C !LOCAL VARIABLES:
69 CHARACTER*(MAX_LEN_FNAM) dataFName, metaFName, pfName
70 INTEGER iG, jG, jRec, dUnit, IL, pIL
71 INTEGER dimList(3,1), nDims, map2gl(2)
72 INTEGER length_of_rec
73 CHARACTER*(MAX_LEN_MBUF) msgBuf
74
75 C simple implementation of singleCpuIO without any specific EXCH2
76 C feature (should work as long as reading and writing match)
77 INTEGER j
78 INTEGER vec_size
79 C Note: would be better to use explicit (allocate/delocate) dynamical
80 C allocation instead of this implicit form:
81 _R8 gl_buffer_r8(nSize*nPx*nPy)
82 _R4 gl_buffer_r4(nSize*nPx*nPy)
83 _R8 local_r8 (nSize)
84 _R4 local_r4 (nSize)
85 _RL dummyRL(1)
86 CHARACTER*8 blank8c
87 CEOP
88
89 DATA dummyRL(1) / 0. _d 0 /
90 DATA blank8c / ' ' /
91 DATA map2gl / 0, 1 /
92
93 vec_size = nSize*nPx*nPy
94
95 C-- Copy input array to local buffer
96 IF ( arrType.EQ.'R4' ) THEN
97 IF ( filePrec.EQ.precFloat32 ) THEN
98 DO j=1,nSize
99 local_r4(j) = fldR4(j)
100 ENDDO
101 ELSE
102 DO j=1,nSize
103 local_r8(j) = fldR4(j)
104 ENDDO
105 ENDIF
106 ELSEIF ( arrType.EQ.'R8' ) THEN
107 IF ( filePrec.EQ.precFloat32 ) THEN
108 DO j=1,nSize
109 local_r4(j) = fldR8(j)
110 ENDDO
111 ELSE
112 DO j=1,nSize
113 local_r8(j) = fldR8(j)
114 ENDDO
115 ENDIF
116 ELSE
117 WRITE(msgBuf,'(A)')
118 & ' MDS_WRITE_TAPE: illegal value for arrType'
119 CALL PRINT_ERROR( msgBuf, myThid )
120 STOP 'ABNORMAL END: S/R MDS_WRITE_TAPE'
121 ENDIF
122
123 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
124
125 C-- Only do I/O if I am the master thread
126 _BEGIN_MASTER( myThid )
127
128 C- Record number must be >= 1
129 IF ( iRec.LT.1 ) THEN
130 WRITE(msgBuf,'(A,I10)')
131 & ' MDS_WRITE_TAPE: argument iRec =',iRec
132 CALL PRINT_ERROR( msgBuf, myThid )
133 WRITE(msgBuf,'(A)')
134 & ' MDS_WRITE_TAPE: invalid value for iRec'
135 CALL PRINT_ERROR( msgBuf, myThid )
136 STOP 'ABNORMAL END: S/R MDS_WRITE_TAPE'
137 ENDIF
138
139 C- Assume nothing
140 IL = ILNBLNK( fName )
141 pIL = ILNBLNK( mdsioLocalDir )
142
143 C- Assign special directory
144 IF ( pIL.EQ.0 ) THEN
145 pfName = fName
146 ELSE
147 WRITE(pfName,'(2A)') mdsioLocalDir(1:pIL), fName(1:IL)
148 ENDIF
149 pIL = ILNBLNK( pfName )
150 IF ( debugLevel.GE.debLevC .AND.
151 & ( .NOT.singleCpuIO .OR. myProcId.EQ.0 ) ) THEN
152 WRITE(msgBuf,'(A,I8,2A)')
153 & ' MDS_WRITE_TAPE: iRec=', iRec, ', file=', pfName(1:pIL)
154 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
155 & SQUEEZE_RIGHT, myThid )
156 ENDIF
157
158 C- Assign a free unit number as the I/O channel for this routine
159 CALL MDSFINDUNIT( dUnit, myThid )
160
161 C If option globalFile is desired but does not work or if
162 C globalFile is too slow, then try using single-CPU I/O.
163 IF ( singleCpuIO ) THEN
164
165 C- Gather array from all procs
166 IF ( filePrec.EQ.precFloat32 ) THEN
167 CALL GATHER_VEC_R4( gl_buffer_r4, local_r4, nSize, myThid )
168 ELSEIF ( filePrec.EQ.precFloat64 ) THEN
169 CALL GATHER_VEC_R8( gl_buffer_r8, local_r8, nSize, myThid )
170 ELSE
171 WRITE(msgBuf,'(A)')
172 & ' MDS_WRITE_TAPE: illegal value for filePrec'
173 CALL PRINT_ERROR( msgBuf, myThid )
174 STOP 'ABNORMAL END: S/R MDS_WRITE_TAPE'
175 ENDIF
176
177 IF ( myProcId .EQ. 0 ) THEN
178 C-- Master thread of process 0, only, opens a global file
179
180 WRITE(dataFName,'(2a)') fName(1:IL),'.data'
181 length_of_rec = MDS_RECLEN( filePrec, vec_size, myThid )
182 IF (iRec .EQ. 1) THEN
183 OPEN( dUnit, file=dataFName, status=_NEW_STATUS,
184 & access='direct', recl=length_of_rec )
185 ELSE
186 OPEN( dUnit, file=dataFName, status=_OLD_STATUS,
187 & access='direct', recl=length_of_rec )
188 ENDIF
189
190 C- Write global buffer to file:
191 IF ( filePrec.EQ.precFloat32 ) THEN
192 #ifdef _BYTESWAPIO
193 CALL MDS_BYTESWAPR4( vec_size, gl_buffer_r4 )
194 #endif
195 WRITE(dUnit,rec=iRec) gl_buffer_r4
196 ELSEIF ( filePrec.EQ.precFloat64 ) THEN
197 #ifdef _BYTESWAPIO
198 CALL MDS_BYTESWAPR8( vec_size, gl_buffer_r8 )
199 #endif
200 WRITE(dUnit,rec=iRec) gl_buffer_r8
201 ENDIF
202
203 C- Close data-file and create meta-file
204 CLOSE( dUnit )
205 WRITE(metaFName,'(2a)') fName(1:IL),'.meta'
206 dimList(1,1) = vec_size
207 dimList(2,1) = 1
208 dimList(3,1) = vec_size
209 nDims = 1
210 CALL MDS_WRITE_META(
211 I metaFName, dataFName, the_run_name, ' ',
212 I filePrec, nDims, dimList, map2gl, 0, blank8c,
213 I 0, dummyRL, oneRL, iRec, myIter, myThid )
214
215 C- end if myProcId=0
216 ENDIF
217
218 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
219 C if ( singleCpuIO ), else
220 ELSEIF ( .NOT. singleCpuIO ) THEN
221
222 IF ( globalFile ) THEN
223 C- If we are writing to a global file then we open it here
224 WRITE(dataFName,'(2A)') fName(1:IL),'.data'
225 length_of_rec = MDS_RECLEN( filePrec, nSize, myThid )
226 IF ( iRec.EQ.1 ) THEN
227 OPEN( dUnit, file=dataFName, status=_NEW_STATUS,
228 & access='direct', recl=length_of_rec )
229 ELSE
230 OPEN( dUnit, file=dataFName, status=_OLD_STATUS,
231 & access='direct', recl=length_of_rec )
232 ENDIF
233
234 ELSE
235 C- If we are writing to a tiled MDS file then we open each one here
236 iG = 1 + (myXGlobalLo-1)/sNx
237 jG = 1 + (myYGlobalLo-1)/sNy
238 WRITE(dataFName,'(2A,I3.3,A,I3.3,A)')
239 & pfName(1:pIL),'.',iG,'.',jG,'.data'
240 length_of_rec = MDS_RECLEN( filePrec, nSize, myThid )
241 IF (iRec .EQ. 1) THEN
242 OPEN( dUnit, file=dataFName, status=_NEW_STATUS,
243 & access='direct', recl=length_of_rec )
244 ELSE
245 OPEN( dUnit, file=dataFName, status=_OLD_STATUS,
246 & access='direct', recl=length_of_rec )
247 ENDIF
248 ENDIF
249
250 C- Write local buffer to file:
251 IF (globalFile) THEN
252 C-- Original: nPy=2, nSx=2 -> produces too large file (1.5 x normal size)
253 c iG = myXGlobalLo-1+(bi-1)*sNx
254 c jG = myYGlobalLo-1+(bj-1)*sNy
255 c jRec = 1 + int(iG/sNx) + (jG/sNy)*nSx*nPx +
256 c & (iRec-1)*nSx*nPx*nSy*nPy
257 C-- Alternative: same layout as in scatter/gather_vector (for singleCpuIO)
258 C problem: nPx=2, nSx=2, writing a global (i.e., with bi,bj dim);
259 C- 2nd proc get iG=3 -> badly placed data over nPx*nPy*nSize range
260 C that will be overwritten by next record
261 c iG = 1 + (myXGlobalLo-1)/sNx
262 c jG = 1 + (myYGlobalLo-1)/sNy
263 c jRec = iG + (jG-1)*nPx + (iRec-1)*nPx*nPy
264 C-- Simpler: should work (but hard to interpret the sequence of data in file)
265 jRec = 1 + myProcId + (iRec-1)*nPx*nPy
266 ELSE
267 jRec = iRec
268 ENDIF
269 IF ( filePrec.EQ.precFloat32 ) THEN
270 #ifdef _BYTESWAPIO
271 CALL MDS_BYTESWAPR4( nSize, local_r4 )
272 #endif
273 WRITE(dUnit,rec=jRec) local_r4
274 ELSEIF ( filePrec.EQ.precFloat64 ) THEN
275 #ifdef _BYTESWAPIO
276 CALL MDS_BYTESWAPR8( nSize, local_r8 )
277 #endif
278 WRITE(dUnit,rec=jRec) local_r8
279 ELSE
280 WRITE(msgBuf,'(A)')
281 & ' MDS_WRITE_TAPE: illegal value for filePrec'
282 CALL PRINT_ERROR( msgBuf, myThid )
283 STOP 'ABNORMAL END: S/R MDS_WRITE_TAPE'
284 ENDIF
285
286 C- Close data-file and create meta-file
287 CLOSE( dUnit )
288 IF ( globalFile ) THEN
289 C meta-file for global file
290 WRITE(metaFName,'(2A)') fName(1:IL),'.meta'
291 dimList(1,1) = vec_size
292 dimList(2,1) = 1
293 dimList(3,1) = vec_size
294 nDims = 1
295 ELSE
296 C meta-file for tiled file
297 iG = 1 + (myXGlobalLo-1)/sNx
298 jG = 1 + (myYGlobalLo-1)/sNy
299 WRITE(metaFName,'(2A,I3.3,A,I3.3,A)')
300 & pfName(1:pIL),'.',iG,'.',jG,'.meta'
301 dimList(1,1) = nPx*nPy*nSize
302 dimList(2,1) = 1 + myProcId*nSize
303 dimList(3,1) = (1+myProcId)*nSize
304 nDims = 1
305 ENDIF
306 C- write meta-file
307 CALL MDS_WRITE_META(
308 I metaFName, dataFName, the_run_name, ' ',
309 I filePrec, nDims, dimList, map2gl, 0, blank8c,
310 I 0, dummyRL, oneRL, iRec, myIter, myThid )
311 c I metaFName, dataFName, the_run_name, titleLine,
312 c I filePrec, nDims, dimList, map2gl, nFlds, fldList,
313 c I nTimRec, timList, misVal, iRec, myIter, myThid )
314
315 C end-if ( .not. singleCpuIO )
316 ENDIF
317
318 _END_MASTER( myThid )
319
320 #else /* ALLOW_AUTODIFF */
321 STOP 'ABNORMAL END: S/R MDS_WRITE_TAPE is empty'
322 #endif /* ALLOW_AUTODIFF */
323
324 RETURN
325 END

  ViewVC Help
Powered by ViewVC 1.1.22