SURFEX v8.1
General documentation of Surfex
distio_mix.F90
Go to the documentation of this file.
1 !OPTIONS NOOPT
2 MODULE distio_mix
3 USE parkind1, ONLY : jprb
4 USE yomhook , ONLY : lhook, dr_hook
5 
6 USE parkind1 ,ONLY : jpim ,jprb
7 #ifdef SFX_MPI
8 USE mpl_module
9 #endif
10 
11 IMPLICIT NONE
12 
13 PRIVATE
14 
15 INTERFACE comm_array
16 MODULE PROCEDURE real_comm_array, int_comm_array
17 END INTERFACE
18 
19 PUBLIC ::&
21  &dist_inquire, &
23  &mrfsfile
24 
25 INTEGER(KIND=JPIM) :: myproc, nproc
26 INTEGER(KIND=JPIM) :: iret, ilen, iroot, itag, icomm, iwords
27 
28 INTEGER(KIND=JPIM), PARAMETER :: jpe_byte = 0
29 INTEGER(KIND=JPIM), PARAMETER :: jpe_integer = 1
30 INTEGER(KIND=JPIM), PARAMETER :: jpe_real = 2
31 INTEGER(KIND=JPIM), PARAMETER :: jpintbyt = 4
32 INTEGER(KIND=JPIM), PARAMETER :: jpreabyt = 8
33 
34 CHARACTER(LEN=*), PARAMETER :: notdef = 'NOT DEFINED'
35 CHARACTER(LEN=255), SAVE :: mrfsdir = notdef
36 CHARACTER(LEN=12), SAVE :: dist_maxfilesize = notdef
37 
38 LOGICAL, SAVE :: ll_has_mrfsdir = .false.
39 INTEGER(KIND=JPIM), SAVE :: maxfilesize = 8 * 1024 * 1024 ! 8MB
40 
41 INTEGER(KIND=JPIM), PARAMETER :: jp_maxunit = 99
42 INTEGER(KIND=JPIM), PARAMETER :: jp_minunit = 0
43 
44 CONTAINS
45 
46 !=======================================================================
47 !---- Public routines ----
48 !=======================================================================
49 
50 SUBROUTINE dist_close(UNIT, FILE, STATUS, IOSTAT)
51 
52 INTEGER(KIND=JPIM), INTENT(IN) :: UNIT
53 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: FILE, STATUS
54 INTEGER(KIND=JPIM), INTENT(OUT), OPTIONAL :: IOSTAT
55 
56 INTEGER(KIND=JPIM) :: IERR, I
57 LOGICAL OPENED
58 CHARACTER(LEN=255) CL_FILE
59 CHARACTER(LEN=80) CL_STATUS
60 
61 REAL(KIND=JPRB) :: ZHOOK_HANDLE
62 IF (lhook) CALL dr_hook('DISTIO_MIX:DIST_CLOSE',0,zhook_handle)
63 ierr = 0
64 
65 IF (PRESENT(status)) THEN
66  cl_status = adjustl(status)
67  CALL toupper(cl_status)
68 ELSE
69  cl_status = 'KEEP'
70 ENDIF
71 
72 INQUIRE(unit=unit, opened=opened)
73 
74 IF (opened) THEN
75  IF (PRESENT(file) .AND. .NOT. PRESENT(status)) THEN
76 !-- Try to remove the "file" if in MRFSDIR to conserve MRFS-space
77 ! (after all, the "file" was supposed to be a tmp-file)
78 
79  CALL get_mrfsdir()
80  IF (ll_has_mrfsdir) THEN
81  cl_file = adjustl(file)
82  i = index(trim(cl_file), trim(mrfsdir))
83  IF (i > 0) cl_status = 'DELETE'
84  ENDIF
85  ENDIF
86 
87  CLOSE(unit, status=trim(cl_status), iostat=ierr)
88 ENDIF
89 
90 IF (PRESENT(iostat)) THEN
91  iostat = ierr
92 ENDIF
93 IF (lhook) CALL dr_hook('DISTIO_MIX:DIST_CLOSE',1,zhook_handle)
94 END SUBROUTINE dist_close
95 
96 !=======================================================================
97 
98 SUBROUTINE dist_inquire(FILE, EXIST)
99 
100 CHARACTER(LEN=*), INTENT(IN) :: FILE
101 LOGICAL, INTENT(OUT) :: EXIST
102 INTEGER(KIND=JPIM) :: I_EXIST
103 
104 REAL(KIND=JPRB) :: ZHOOK_HANDLE
105 IF (lhook) CALL dr_hook('DISTIO_MIX:DIST_INQUIRE',0,zhook_handle)
106 i_exist = 0
107 #ifdef SFX_MPI
108 nproc = mpl_numproc
109 myproc = mpl_rank
110 #else
111 nproc = 1
112 myproc = 0
113 #endif
114 
115 IF (myproc == 1) THEN
116  INQUIRE(file=file, exist=exist)
117  IF (exist) i_exist = 1
118 ENDIF
119 
120 IF (nproc > 1) THEN
121 !-- Broadcast the file existence status
122  ilen = 1
123  iroot = 1
124  itag = 500
125  icomm = 0
126 #ifdef SFX_MPI
127  CALL mpl_broadcast(i_exist,kroot=iroot,ktag=itag, &
128  & cdstring='DIST_INQUIRE:')
129 #endif
130 ENDIF
131 
132 exist = (i_exist == 1)
133 IF (lhook) CALL dr_hook('DISTIO_MIX:DIST_INQUIRE',1,zhook_handle)
134 END SUBROUTINE dist_inquire
135 
136 !=======================================================================
137 
138 SUBROUTINE dist_open(&
139 !-- Optional parameters (FORTRAN-OPEN style) --
140  &unit, file, iostat,&
141  &status, form, action,&
142  &access, recl, &
143  &fmt,&
144 !-- Optional ARRAYs (real ARRAY has presedence over the integer ARRAY)
145  &array, iarray,&
146 !-- The actual filename on which the I/O is (was) applied to
147  &localfile)
149 
150 !.. A subroutine to open the same file only by the processor#1
151 ! and then distribute it to the other processors via
152 ! fast communication network.
153 
154 ! Remote processors save the contents into their (preferably)
155 ! memory resident file system and open it there and return
156 ! a handle.
157 
158 ! ... or ...
159 
160 ! if one of the ARRAYs are provided, then data is read into it
161 ! by processor#1 and distributed to others
162 
163 ! NOTE: Initially meant only for Read/Only -files
164 
165 ! Algorithm(s) used:
166 ! ==================
167 
168 ! (1) Processor#1 (raw-)reads the file
169 ! and sends it to all other processors (incl. itself)
170 ! (2) All processors store the bytes into their memory resident
171 ! file system and issue appropriate OPEN to that file
172 ! (3) File is silently closed if unit was not specified
173 
174 ! except if:
175 
176 ! If one of the arrays ARRAY or IARRAY exist, then the phase (2)
177 ! is skipped, but ARRAY/IARRAY is read in by proc#1 and xferred
178 ! to other PEs via network.
179 
180 ! After this file is closed if no unit number was given
181 
182 ! If environment-value MRFSDIR is not defined, then
183 ! all processors are forced to OPEN the same (shared) file.
184 
185 ! Author: Sami Saarinen, ECMWF, 18/11/97
186 
187 
188 
189 
190 !-- unit : I/O-channel
191 INTEGER(KIND=JPIM), INTENT(IN), OPTIONAL :: UNIT
192 
193 !-- file: Target file, that processor#1 reads
194 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: FILE
195 
196 !-- iostat: An error code from the latest I/O operation
197 ! OR internal error from the DISTIO_MIX-routine (iostat < -10000)
198 ! -10001 : Both file name AND unit number were not given
199 ! -10002 : File is not read/only
200 ! -10004 : Free format, textual direct access read not allowed
201 ! -10008 : Direct access file has record length <= 0
202 ! -10016 : Neither unit number, nor ARRAY/IARRAY were supplied
203 ! -10032 : Format error
204 ! or combination of internal errors; find out via "mod(-ierr,10000)"
205 
206 INTEGER(KIND=JPIM), INTENT(OUT), OPTIONAL :: IOSTAT
207 
208 !-- status, form, action, access, recl: FORTRAN-OPEN's keywords
209 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: STATUS, FORM, ACTION, ACCESS
210 INTEGER(KIND=JPIM), INTENT(IN), OPTIONAL :: RECL
211 
212 !-- fmt: The possible format to be used when reading an ARRAY/IARRAY
213 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: FMT
214 
215 !-- ARRAY: Real array
216 REAL(KIND=JPRB), INTENT(OUT), OPTIONAL :: ARRAY(:)
217 
218 !-- IARRAY: Integer array
219 INTEGER(KIND=JPIM), INTENT(OUT), OPTIONAL :: IARRAY(:)
220 
221 !-- localfile: The actual file name where the handle 'unit' (possibly) refers to
222 ! An output parameter that (usually) has a value $MRFSDIR/file
223 CHARACTER(LEN=*), INTENT(OUT), OPTIONAL :: LOCALFILE
224 
225 
226 ! === END OF INTERFACE BLOCK ===
227 INTEGER(KIND=JPIM) :: IERR, ITMP
228 INTEGER(KIND=JPIM) :: I_UNIT, I_RECL
229 LOGICAL LL_OPEN, LL_CLOSE, LL_HAS_BEEN_COMMUNICATED
230 LOGICAL LL_READ_ONLY, LL_FORMATTED, LL_DIRECT_ACCESS
231 LOGICAL LL_REAL_ARRAY, LL_HAS_ARRAY
232 CHARACTER(LEN=255) CL_FILE, CL_TMPNAME
233 CHARACTER(LEN= 80) CL_STATUS, CL_ACTION, CL_FORM, CL_ACCESS, CL_FMT
234 
235 !234567890-234567890-234567890-234567890-234567890-234567890-234567890--
236 
237 REAL(KIND=JPRB) :: ZHOOK_HANDLE
238 IF (lhook) CALL dr_hook('DISTIO_MIX:DIST_OPEN',0,zhook_handle)
239 ierr = 0
240 #ifdef SFX_MPI
241 nproc = mpl_numproc
242 myproc = mpl_rank
243 #else
244 nproc = 1
245 myproc = 0
246 #endif
247 
248 ll_open = .false.
249 ll_close = .false.
250 
251 !-- unit
252 IF (PRESENT(unit)) THEN
253  i_unit = unit
254 ELSE
255  CALL get_next_unit(i_unit)
256  ll_close = .true.
257 ENDIF
258 
259 !-- file
260 IF (PRESENT(file)) THEN
261  cl_file = adjustl(file)
262 ELSE
263  IF (i_unit >= jp_minunit .AND. i_unit <= jp_maxunit) THEN
264  WRITE(cl_file,"('fort.',i4)") i_unit
265  CALL strip(cl_file,' ') ! File became "fort.<unit>"
266  ELSE
267  cl_file = notdef
268  ierr = ierr + 1
269  ENDIF
270 ENDIF
271 
272 !-- status
273 IF (PRESENT(status)) THEN
274  cl_status = adjustl(status)
275  CALL toupper(cl_status)
276 ELSE
277  cl_status = 'OLD'
278 ENDIF
279 
280 !-- action
281 IF (PRESENT(action)) THEN
282  cl_action = adjustl(action)
283  CALL toupper(cl_action)
284 ELSE
285  cl_action = 'READ'
286 ENDIF
287 
288 ll_read_only = (&
289  &(cl_status == 'OLD' .OR. cl_status == 'UNKNOWN')&
290  &.AND. &
291  &(cl_action == 'READ') )
292 
293 IF (.NOT. ll_read_only) THEN
294  ierr = ierr + 2
295 ENDIF
296 
297 !-- fmt
298 IF (PRESENT(fmt)) THEN
299  cl_fmt = fmt
300 ELSE
301  cl_fmt = '*'
302 ENDIF
303 
304 !-- form
305 IF (PRESENT(form)) THEN
306  cl_form = adjustl(form)
307  CALL toupper(cl_form)
308 ELSE
309  cl_form = 'FORMATTED'
310 ENDIF
311 
312 ll_formatted = (cl_form == 'FORMATTED')
313 
314 IF (ll_formatted) THEN
315  IF (cl_fmt /= '*') THEN
316  itmp = len_trim(cl_fmt)
317  IF (itmp <= 2) THEN
318  ierr = ierr + 32
319  ELSE IF (cl_fmt(1:1) /= '(' .AND. cl_fmt(itmp:itmp) /= ')') THEN
320  ierr = ierr + 32
321  ENDIF
322  ENDIF
323 ENDIF
324 
325 !-- access
326 IF (PRESENT(access)) THEN
327  cl_access = adjustl(access)
328  CALL toupper(cl_access)
329 ELSE
330  cl_access = 'SEQUENTIAL'
331 ENDIF
332 
333 ll_direct_access = (cl_access == 'DIRECT')
334 
335 IF ( ll_direct_access .AND. ll_formatted .AND. cl_fmt == '*') THEN
336  ierr = ierr + 4
337 ENDIF
338 
339 !-- recl
340 IF (PRESENT(recl)) THEN
341  i_recl = recl
342 ELSE
343  i_recl = 0
344 ENDIF
345 
346 IF (ll_direct_access .AND. i_recl <= 0) THEN
347  ierr = ierr + 8
348 ENDIF
349 
350 !-- ARRAY or IARRAY
351 ll_real_array = .true.
352 
353 IF (PRESENT(array)) THEN
354  ll_real_array = .true.
355 ELSE IF (PRESENT(iarray)) THEN
356  ll_real_array = .false.
357 ENDIF
358 
359 ll_has_array = (PRESENT(array) .OR. PRESENT(iarray))
360 
361 IF (.NOT. ll_has_array .AND. .NOT. PRESENT(unit)) THEN
362  ierr = ierr + 16
363 ENDIF
364 
365 !=======================================================================
366 IF (ierr /= 0) ierr = -(ierr + 10000)
367 IF (ierr < 0) GOTO 9999
368 !=======================================================================
369 
370 !-- Is the memory resident file system available ?
371 CALL get_mrfsdir()
372 
373 !-- Max file size that is allowed to go over the network
375 
376 !=======================================================================
377 IF (.NOT. ll_has_array) THEN
378 !-- Communicate the file over the network
379  CALL comm_file(cl_file, ll_has_been_communicated)
380  ll_open = .true.
381 ELSE
382  ll_has_been_communicated = .false.
383  ll_open = (myproc == 1)
384  ll_close = ll_open
385 ENDIF
386 !=======================================================================
387 
388 IF (ll_has_been_communicated) THEN
389  CALL make_local_filename(cl_tmpname, cl_file)
390  cl_file = cl_tmpname
391 ENDIF
392 
393 IF (PRESENT(localfile)) THEN
394  IF (scan(cl_file,'/') > 0) THEN
395  localfile = adjustl(cl_file)
396  ELSE
397  localfile = './'//adjustl(cl_file)
398  ENDIF
399 ENDIF
400 
401 IF (ll_open) THEN
402 !-- Open the file via Fortran-OPEN
403 
404  IF (ll_formatted) THEN
405 
406 !-- Formatted file
407  IF (ll_direct_access) THEN
408 !--- .. Direct access
409  OPEN(unit=i_unit, file=trim(cl_file),&
410  &status=trim(cl_status), form='FORMATTED',&
411  &access='DIRECT', recl=i_recl, action='READ',&
412  &iostat=ierr, err=9999)
413  ELSE
414 !--- .. Sequential
415  OPEN(unit=i_unit, file=trim(cl_file),&
416  &status=trim(cl_status), form='FORMATTED',&
417  &access='SEQUENTIAL', action='READ',&
418  &position='REWIND',&
419  &iostat=ierr, err=9999)
420  ENDIF
421 
422  ELSE
423 
424 !-- Unformatted file
425  IF (ll_direct_access) THEN
426 !--- .. Direct access
427  OPEN(unit=i_unit, file=trim(cl_file),&
428  &status=trim(cl_status), form='UNFORMATTED',&
429  &access='DIRECT', recl=i_recl, action='READ',&
430  &iostat=ierr, err=9999)
431  ELSE
432 !--- .. Sequential
433  OPEN(unit=i_unit, file=trim(cl_file),&
434  &status=trim(cl_status), form='UNFORMATTED',&
435  &access='SEQUENTIAL', action='READ',&
436  &position='REWIND',&
437  &iostat=ierr, err=9999)
438  ENDIF
439 
440  ENDIF
441 
442 ENDIF
443 
444 !=======================================================================
445 IF (ll_has_array) THEN
446  IF (ll_real_array) THEN
447  CALL comm_array(i_unit, array,&
448  &trim(adjustl(cl_fmt)), ierr,&
449  &ll_direct_access, ll_formatted)
450  ELSE
451  CALL comm_array(i_unit, iarray,&
452  &trim(adjustl(cl_fmt)), ierr,&
453  &ll_direct_access, ll_formatted)
454  ENDIF
455 ENDIF
456 
457 IF (ierr /= 0) GOTO 9999
458 !=======================================================================
459 
460 IF (ll_close) CLOSE(i_unit, iostat=ierr, err=9999)
461 
462 9999 CONTINUE
463 IF (PRESENT(iostat)) THEN
464  iostat = ierr
465 ENDIF
466 IF (lhook) CALL dr_hook('DISTIO_MIX:DIST_OPEN',1,zhook_handle)
467 END SUBROUTINE dist_open
468 
469 !=======================================================================
470 
471 SUBROUTINE get_next_unit(KUNIT)
473 INTEGER(KIND=JPIM), INTENT(OUT) :: KUNIT
474 INTEGER(KIND=JPIM) :: J
475 LOGICAL LOPENED
476 REAL(KIND=JPRB) :: ZHOOK_HANDLE
477 IF (lhook) CALL dr_hook('DISTIO_MIX:GET_NEXT_UNIT',0,zhook_handle)
478 kunit = -1
479 DO j=jp_maxunit, jp_minunit, -1
480  INQUIRE(unit=j, opened=lopened)
481  IF (.NOT.lopened) THEN
482  kunit = j
483  IF (lhook) CALL dr_hook('DISTIO_MIX:GET_NEXT_UNIT',1,zhook_handle)
484  RETURN
485  ENDIF
486 ENDDO
487 IF (lhook) CALL dr_hook('DISTIO_MIX:GET_NEXT_UNIT',1,zhook_handle)
488 END SUBROUTINE get_next_unit
489 
490 SUBROUTINE get_mrfsdir(KOUT, CDOUT)
491 !-- Look for MRFSDIR (memory resident file system) environment variable
492 
493 INTEGER(KIND=JPIM), INTENT(IN) , OPTIONAL :: KOUT
494 CHARACTER(LEN=*), INTENT(OUT), OPTIONAL :: CDOUT
495 INTEGER(KIND=JPIM) :: I
496 REAL(KIND=JPRB) :: ZHOOK_HANDLE
497 IF (lhook) CALL dr_hook('DISTIO_MIX:GET_MRFSDIR',0,zhook_handle)
498 IF (mrfsdir == notdef) THEN
499  CALL get_environment_variable('DIST_MRFSPATH', mrfsdir)
500  mrfsdir = adjustl(mrfsdir)
501  i = len_trim(mrfsdir)
502  loop: DO WHILE (i > 0)
503 ! Remove any trailing slashes '/'
504  IF (mrfsdir(i:i) /= '/') EXIT loop
505  mrfsdir(i:i) = ' '
506  i = i - 1
507  ENDDO loop
508  IF (mrfsdir == '.') mrfsdir = ' '
509  ll_has_mrfsdir = (mrfsdir /= ' ')
510 
511  IF (PRESENT(kout)) THEN
512 #ifdef SFX_MPI
513  myproc = mpl_rank
514 #else
515  myproc = 0
516 #endif
517  IF (myproc == 1) THEN
518  IF (ll_has_mrfsdir) THEN
519  WRITE(kout,*)'GET_MRFSDIR: MRFSDIR="'//trim(mrfsdir)//'"'
520  ELSE
521  WRITE(kout,*)'GET_MRFSDIR: MRFSDIR not present'
522  ENDIF
523  ENDIF
524  ENDIF
525 ENDIF
526 IF (PRESENT(cdout)) THEN
527  cdout = mrfsdir
528 ENDIF
529 IF (lhook) CALL dr_hook('DISTIO_MIX:GET_MRFSDIR',1,zhook_handle)
530 END SUBROUTINE get_mrfsdir
531 
532 SUBROUTINE get_dist_maxfilesize(KOUT, KMAXSIZE)
533 !-- Get the maximum permissible size of the file to be communicated
534 ! This option is to avoid excessively large files dealt
535 ! with this concept
536 
537 INTEGER(KIND=JPIM), INTENT(IN) , OPTIONAL :: KOUT
538 INTEGER(KIND=JPIM), INTENT(OUT), OPTIONAL :: KMAXSIZE
539 REAL(KIND=JPRB) :: ZHOOK_HANDLE
540 IF (lhook) CALL dr_hook('DISTIO_MIX:GET_DIST_MAXFILESIZE',0,zhook_handle)
541 IF (dist_maxfilesize == notdef) THEN
542  CALL get_environment_variable('DIST_MAXFILESIZE', dist_maxfilesize)
543  IF (dist_maxfilesize /= ' ') THEN
545  READ(dist_maxfilesize,'(i12)',err=9999) maxfilesize
546  ENDIF
547  9999 CONTINUE
548  maxfilesize = max(-1,maxfilesize)
549 
550  IF (PRESENT(kout)) THEN
551 #ifdef SFX_MPI
552  myproc = mpl_rank
553 #else
554  myproc = 0
555 #endif
556  IF (myproc == 1) THEN
557  WRITE(kout,'(1x,2a,i12,a)')&
558  &'GET_DIST_MAXFILESIZE: ',&
559  &'Largest file to be distributed: ',&
560  &maxfilesize,' bytes'
561  ENDIF
562  ENDIF
563 ENDIF
564 IF (PRESENT(kmaxsize)) THEN
565  kmaxsize = maxfilesize
566 ENDIF
567 IF (lhook) CALL dr_hook('DISTIO_MIX:GET_DIST_MAXFILESIZE',1,zhook_handle)
568 END SUBROUTINE get_dist_maxfilesize
569 
570 !=======================================================================
571 !---- Private routines ----
572 !=======================================================================
573 
574 SUBROUTINE toupper(CDS)
576 !-- Converts lowercase letters to uppercase
577 CHARACTER(LEN=*), INTENT(INOUT) :: CDS
578 INTEGER(KIND=JPIM), PARAMETER :: ICH_A = ichar('A')
579 INTEGER(KIND=JPIM), PARAMETER :: ICHA = ichar('a')
580 INTEGER(KIND=JPIM), PARAMETER :: ICHZ = ichar('z')
581 INTEGER(KIND=JPIM) :: I, ICH, NEW_ICH, ILEN
582 CHARACTER(LEN=1) CH
583 REAL(KIND=JPRB) :: ZHOOK_HANDLE
584 IF (lhook) CALL dr_hook('DISTIO_MIX:TOUPPER',0,zhook_handle)
585 ilen = len_trim(cds)
586 DO i=1,ilen
587  ch = cds(i:i)
588  ich = ichar(ch)
589  IF ( ich >= icha .AND. ich <= ichz ) THEN
590  new_ich = ich + (ich_a - icha)
591  ch = char(new_ich)
592  cds(i:i) = ch
593  ENDIF
594 ENDDO
595 IF (lhook) CALL dr_hook('DISTIO_MIX:TOUPPER',1,zhook_handle)
596 END SUBROUTINE toupper
597 
598 SUBROUTINE strip(CDS,CDWHAT)
600 !-- Strips off all possible characters 'cdwhat'
601 CHARACTER(LEN=*), INTENT(INOUT) :: CDS
602 CHARACTER(LEN=1), INTENT(IN) :: CDWHAT
603 CHARACTER(LEN=LEN(CDS)) CLS
604 INTEGER(KIND=JPIM) :: I, J, ILEN
605 CHARACTER(LEN=1) CH
606 REAL(KIND=JPRB) :: ZHOOK_HANDLE
607 IF (lhook) CALL dr_hook('DISTIO_MIX:STRIP',0,zhook_handle)
608 cls = ' '
609 j = 0
610 ilen = len_trim(cds)
611 DO i=1,ilen
612  ch = cds(i:i)
613  IF (ch /= cdwhat) THEN
614  j = j + 1
615  cls(j:j) = ch
616  ENDIF
617 ENDDO
618 cds = trim(adjustl(cls))
619 IF (lhook) CALL dr_hook('DISTIO_MIX:STRIP',1,zhook_handle)
620 END SUBROUTINE strip
621 
622 SUBROUTINE make_local_filename(CLFILE, CDFILE)
624 CHARACTER(LEN=*), INTENT(OUT) :: CLFILE
625 CHARACTER(LEN=*), INTENT(IN) :: CDFILE
626 LOGICAL, PARAMETER :: LL_REVERSE = .true.
627 INTEGER(KIND=JPIM) :: I
628 REAL(KIND=JPRB) :: ZHOOK_HANDLE
629 IF (lhook) CALL dr_hook('DISTIO_MIX:MAKE_LOCAL_FILENAME',0,zhook_handle)
630 clfile = adjustl(cdfile)
631 i = scan(clfile,'/',ll_reverse) ! The basename after the path
632 IF (i > 0) clfile(1:i) = ' '
633 clfile = trim(adjustl(clfile))
634 clfile = trim(adjustl(mrfsdir))//"/"//clfile ! $MRFSDIR/filename
635 WRITE(clfile,"(a,'.',i4.4)") trim(adjustl(clfile)),myproc
636 IF (lhook) CALL dr_hook('DISTIO_MIX:MAKE_LOCAL_FILENAME',1,zhook_handle)
637 END SUBROUTINE make_local_filename
638 
639 SUBROUTINE comm_file(CDFILE, LDSTATUS)
640 !-- Communicate the file
641 
642 CHARACTER(LEN=*), INTENT(IN) :: CDFILE
643 LOGICAL, INTENT(OUT) :: LDSTATUS
644 
645 INTEGER(KIND=JPIM) :: IFILESIZE
646 INTEGER(KIND=JPIM), ALLOCATABLE :: FILE_CONTENTS(:)
647 LOGICAL LL_HAS_BEEN_COMMUNICATED
648 CHARACTER(LEN=255) CL_TMPNAME
649 CHARACTER(LEN=4) CL_PROCID
650 
651 REAL(KIND=JPRB) :: ZHOOK_HANDLE
652 IF (lhook) CALL dr_hook('DISTIO_MIX:COMM_FILE',0,zhook_handle)
653 ll_has_been_communicated = .false.
654 
655 IF (nproc <= 1) GOTO 9999
656 
657 ifilesize = 0
658 
659 IF (ll_has_mrfsdir) THEN
660  IF (myproc == 1) THEN
661  CALL util_filesize(trim(cdfile), ifilesize)
662  IF (maxfilesize /= -1) THEN
663  IF (ifilesize > maxfilesize) ifilesize = -ifilesize
664  ENDIF
665  ENDIF
666 ENDIF
667 
668 iroot = 1
669 itag = 100
670 icomm = 0
671 #ifdef SFX_MPI
672 CALL mpl_broadcast(ifilesize,kroot=iroot,ktag=itag, &
673  & cdstring='COMM_FILE:')
674 #endif
675 IF (ifilesize > 0) THEN
676  iwords = (ifilesize + jpintbyt - 1)/jpintbyt
677  ALLOCATE(file_contents(iwords))
678 
679 !-- Only processor#1 reads it
680  IF (myproc == 1) THEN
681  CALL util_readraw(trim(cdfile), file_contents, ifilesize, iret)
682  IF (iret /= ifilesize) THEN
683 #ifdef SFX_MPI
684  CALL mpl_message(ldabort=.true., &
685  & cdmessage='File "'//trim(cdfile)//'" read error at proc#1', &
686  & cdstring='** Problems with UTIL_READRAW **')
687 #endif
688  ENDIF
689  ENDIF
690 
691 !-- ... and then broadcasts to all
692 
693  ilen = iwords
694  iroot = 1
695  itag = 200
696  icomm = 0
697 #ifdef SFX_MPI
698  CALL mpl_broadcast(file_contents(1:ilen),kroot=iroot,ktag=itag, &
699  & cdstring='COMM_FILE:')
700 #endif
701 
702 !-- ... and finally store it into the *local* MRFSDIR
703 
704  CALL make_local_filename(cl_tmpname, cdfile)
705 
706  CALL util_writeraw(trim(cl_tmpname), file_contents, ifilesize, iret)
707  IF (iret /= ifilesize) THEN
708  WRITE(cl_procid,'(i4)') myproc
709 #ifdef SFX_MPI
710  CALL mpl_message(ldabort=.true., &
711  & cdmessage='File "'//trim(cl_tmpname)//'" write error at proc#'&
712  &//trim(adjustl(cl_procid)), &
713  & cdstring='** Problems with UTIL_WRITERAW **')
714 #endif
715  ENDIF
716 
717  DEALLOCATE(file_contents)
718  ll_has_been_communicated = .true.
719 ENDIF
720 
721 9999 CONTINUE
722 ldstatus = ll_has_been_communicated
723 IF (lhook) CALL dr_hook('DISTIO_MIX:COMM_FILE',1,zhook_handle)
724 END SUBROUTINE comm_file
725 
726 SUBROUTINE real_comm_array(I_UNIT, ARRAY,&
727  &CDFMT, IERR,&
728  &LL_DIRECT_ACCESS, LL_FORMATTED)
730 INTEGER(KIND=JPIM), INTENT(IN) :: I_UNIT
731 REAL(KIND=JPRB), INTENT(INOUT) :: ARRAY(:)
732 LOGICAL, INTENT(IN), OPTIONAL ::LL_DIRECT_ACCESS, LL_FORMATTED
733 CHARACTER(LEN=*), INTENT(IN) :: CDFMT
734 INTEGER(KIND=JPIM), INTENT(OUT) :: IERR
735 
736 LOGICAL LL_FREE_FORMAT, LL_PBIO
737 INTEGER(KIND=JPIM) :: I_SIZE
738 
739 REAL(KIND=JPRB) :: ZHOOK_HANDLE
740 IF (lhook) CALL dr_hook('DISTIO_MIX:REAL_COMM_ARRAY',0,zhook_handle)
741 ll_free_format = (cdfmt == '*')
742 ll_pbio = (cdfmt == 'PBIO')
743 i_size = SIZE(array)
744 
745 IF (myproc == 1) THEN
746  IF (ll_pbio) THEN
747  CALL pbread(i_unit, array, i_size*jpreabyt, ierr)
748  IF (ierr == i_size*jpreabyt) ierr = 0
749  ELSE
750  IF (ll_formatted) THEN
751  IF (ll_direct_access) THEN
752  READ(i_unit, fmt=cdfmt, iostat=ierr, err=9999,rec=1) array
753  ELSE
754  IF (ll_free_format) THEN
755  READ(i_unit, fmt=*, iostat=ierr, err=9999,end=9999) array
756  ELSE
757  READ(i_unit, fmt=cdfmt, iostat=ierr, err=9999,end=9999) array
758  ENDIF
759  ENDIF
760  ELSE
761  IF (ll_direct_access) THEN
762  READ(i_unit, iostat=ierr, err=9999, rec=1) array
763  ELSE
764  READ(i_unit, iostat=ierr, err=9999,end=9999) array
765  ENDIF
766  ENDIF
767  ENDIF
768 ENDIF
769 
770 9999 CONTINUE
771 
772 IF (nproc > 1) THEN
773 
774 !-- Broadcast the error code
775  iroot = 1
776  itag = 300
777  icomm = 0
778 #ifdef SFX_MPI
779  CALL mpl_broadcast(ierr,kroot=iroot,ktag=itag, &
780  & cdstring='REAL_COMM_ARRAY:')
781 #endif
782  IF (ierr == 0) THEN
783 !-- Broadcast the data itself if no errors
784  ilen = i_size
785  iroot = 1
786  itag = 301
787  icomm = 0
788 #ifdef SFX_MPI
789  CALL mpl_broadcast(array(1:ilen),kroot=iroot,ktag=itag, &
790  & cdstring='REAL_COMM_ARRAY:')
791 #endif
792  ENDIF
793 
794 ENDIF
795 
796 IF (lhook) CALL dr_hook('DISTIO_MIX:REAL_COMM_ARRAY',1,zhook_handle)
797 END SUBROUTINE real_comm_array
798 
799 
800 SUBROUTINE int_comm_array(I_UNIT, IARRAY,&
801  &CDFMT, IERR,&
802  &LL_DIRECT_ACCESS, LL_FORMATTED)
804 INTEGER(KIND=JPIM), INTENT(IN) :: I_UNIT
805 INTEGER(KIND=JPIM), INTENT(INOUT) :: IARRAY(:)
806 LOGICAL, INTENT(IN), OPTIONAL :: LL_DIRECT_ACCESS, LL_FORMATTED
807 CHARACTER(LEN=*), INTENT(IN) :: CDFMT
808 INTEGER(KIND=JPIM), INTENT(OUT) :: IERR
809 
810 LOGICAL LL_FREE_FORMAT, LL_PBIO
811 INTEGER(KIND=JPIM) :: I_SIZE
812 
813 REAL(KIND=JPRB) :: ZHOOK_HANDLE
814 IF (lhook) CALL dr_hook('DISTIO_MIX:INT_COMM_ARRAY',0,zhook_handle)
815 ll_free_format = (cdfmt == '*')
816 ll_pbio = (cdfmt == 'PBIO')
817 i_size = SIZE(iarray)
818 
819 IF (myproc == 1) THEN
820  IF (ll_pbio) THEN
821  CALL pbread(i_unit, iarray, i_size*jpintbyt, ierr)
822  IF (ierr == i_size*jpintbyt) ierr = 0
823  ELSE
824  IF (ll_formatted) THEN
825  IF (ll_direct_access) THEN
826  READ(i_unit, fmt=cdfmt, iostat=ierr, err=9999,rec=1) iarray
827  ELSE
828  IF (ll_free_format) THEN
829  READ(i_unit, fmt=*, iostat=ierr, err=9999,end=9999) iarray
830  ELSE
831  READ(i_unit, fmt=cdfmt, iostat=ierr, err=9999,end=9999) iarray
832  ENDIF
833  ENDIF
834  ELSE
835  IF (ll_direct_access) THEN
836  READ(i_unit, iostat=ierr, err=9999, rec=1) iarray
837  ELSE
838  READ(i_unit, iostat=ierr, err=9999,end=9999) iarray
839  ENDIF
840  ENDIF
841  ENDIF
842 ENDIF
843 
844 9999 CONTINUE
845 
846 IF (nproc > 1) THEN
847 
848 !-- Broadcast the error code
849  iroot = 1
850  itag = 400
851  icomm = 0
852 #ifdef SFX_MPI
853  CALL mpl_broadcast(ierr,kroot=iroot,ktag=itag,kerror=ierr)
854 #endif
855  IF (ierr == 0) THEN
856 !-- Broadcast the data itself if no errors
857  ilen = i_size
858  iroot = 1
859  itag = 401
860  icomm = 0
861 #ifdef SFX_MPI
862  CALL mpl_broadcast(iarray(1:ilen),kroot=iroot,ktag=itag, &
863  & cdstring='INT_COMM_ARRAY:')
864 #endif
865  ENDIF
866 
867 ENDIF
868 
869 IF (lhook) CALL dr_hook('DISTIO_MIX:INT_COMM_ARRAY',1,zhook_handle)
870 END SUBROUTINE int_comm_array
871 
872 SUBROUTINE mrfsfile(FILE_IN, FILE_OUT)
874 ! A routine to prepend the "$MRFSDIR" in the front of the filename
875 ! If $MRFSDIR is not defined, then return original filename w/o changes.
876 
877 ! Author: Sami Saarinen, ECMWF, 23/1/1998 for CY18R4
878 
879 
880 
881 
882 
883 CHARACTER(LEN=*), INTENT(IN) :: FILE_IN
884 CHARACTER(LEN=*), INTENT(OUT) :: FILE_OUT
885 
886 ! === END OF INTERFACE BLOCK ===
887 CHARACTER(LEN=255), SAVE :: MRFSDIR = ' '
888 LOGICAL, SAVE :: ALREADY_CALLED = .false.
889 LOGICAL, SAVE :: HAS_MRFSDIR = .false.
890 
891 !-- Cache the $MRFSDIR to avoid any further calls to GET_MRFSDIR()
892 REAL(KIND=JPRB) :: ZHOOK_HANDLE
893 IF (lhook) CALL dr_hook('DISTIO_MIX:MRFSFILE',0,zhook_handle)
894 IF (.NOT. already_called) THEN
895  CALL get_mrfsdir(cdout = mrfsdir)
896  has_mrfsdir = (mrfsdir /= ' ')
897  already_called = .true.
898 ENDIF
899 
900 IF (has_mrfsdir) THEN
901 !-- Prepend "${MRFSDIR}/" and remove any leading/trailing blanks present
902  file_out = trim(adjustl(mrfsdir))//'/'//trim(adjustl(file_in))
903 ELSE
904 !-- No change
905  file_out = file_in
906 ENDIF
907 
908 IF (lhook) CALL dr_hook('DISTIO_MIX:MRFSFILE',1,zhook_handle)
909 END SUBROUTINE mrfsfile
910 
911 END MODULE distio_mix
912 
913 
914 
static const char * trim(const char *name, int *n)
Definition: drhook.c:2383
subroutine real_comm_array(I_UNIT, ARRAY, CDFMT, IERR, LL_DIRECT_ACCESS, LL_FORMATTED)
Definition: distio_mix.F90:729
integer, parameter jpim
Definition: parkind1.F90:13
subroutine comm_file(CDFILE, LDSTATUS)
Definition: distio_mix.F90:640
subroutine strip(CDS, CDWHAT)
Definition: distio_mix.F90:599
subroutine, public dist_close(UNIT, FILE, STATUS, IOSTAT)
Definition: distio_mix.F90:51
integer(kind=jpim) iret
Definition: distio_mix.F90:26
subroutine make_local_filename(CLFILE, CDFILE)
Definition: distio_mix.F90:623
integer(kind=jpim), parameter jpintbyt
Definition: distio_mix.F90:31
integer(kind=jpim) myproc
Definition: distio_mix.F90:25
subroutine, public get_mrfsdir(KOUT, CDOUT)
Definition: distio_mix.F90:491
character(len=255), save mrfsdir
Definition: distio_mix.F90:35
integer, parameter jprb
Definition: parkind1.F90:32
integer(kind=jpim), save maxfilesize
Definition: distio_mix.F90:39
character(len= *), parameter notdef
Definition: distio_mix.F90:34
integer(kind=jpim) icomm
Definition: distio_mix.F90:26
integer(kind=jpim) iwords
Definition: distio_mix.F90:26
subroutine, public dist_open(unit, file, iostat, status, form, action, access, recl, fmt, ARRAY, IARRAY, localfile)
Definition: distio_mix.F90:148
subroutine int_comm_array(I_UNIT, IARRAY, CDFMT, IERR, LL_DIRECT_ACCESS, LL_FORMATTED)
Definition: distio_mix.F90:803
subroutine, public mrfsfile(FILE_IN, FILE_OUT)
Definition: distio_mix.F90:873
integer(kind=jpim) iroot
Definition: distio_mix.F90:26
character(len=12), save dist_maxfilesize
Definition: distio_mix.F90:36
logical lhook
Definition: yomhook.F90:15
integer(kind=jpim), parameter jpe_integer
Definition: distio_mix.F90:29
integer(kind=jpim) nproc
Definition: distio_mix.F90:25
integer(kind=jpim) itag
Definition: distio_mix.F90:26
integer(kind=jpim), parameter jpreabyt
Definition: distio_mix.F90:32
integer(kind=jpim), parameter jpe_byte
Definition: distio_mix.F90:28
logical, save ll_has_mrfsdir
Definition: distio_mix.F90:38
subroutine, public dist_inquire(FILE, EXIST)
Definition: distio_mix.F90:99
subroutine toupper(CDS)
Definition: distio_mix.F90:575
integer(kind=jpim) ilen
Definition: distio_mix.F90:26
integer(kind=jpim), parameter jp_maxunit
Definition: distio_mix.F90:41
ERROR in index
Definition: ecsort_shared.h:90
integer(kind=jpim), parameter jpe_real
Definition: distio_mix.F90:30
integer(kind=jpim), parameter jp_minunit
Definition: distio_mix.F90:42
subroutine, public get_next_unit(KUNIT)
Definition: distio_mix.F90:472
subroutine, public get_dist_maxfilesize(KOUT, KMAXSIZE)
Definition: distio_mix.F90:533