From aa1e91b035fe290825bccf3dd534792ddff2a98f Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Fri, 21 Jun 2024 13:36:42 +0200 Subject: [PATCH] Philippe 21/06/2024: IO_Field_read: 0D fields: ensure that data can not be overwritten in case of read error --- src/LIB/SURCOUCHE/src/mode_io_field_read.f90 | 110 ++++++++++++------- 1 file changed, 73 insertions(+), 37 deletions(-) diff --git a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 index eb27e129c..cf22c530e 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 @@ -1,4 +1,4 @@ -!MNH_LIC Copyright 1994-2023 CNRS, Meteo-France and Universite Paul Sabatier +!MNH_LIC Copyright 1994-2024 CNRS, Meteo-France and Universite Paul Sabatier !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence !MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt !MNH_LIC for details. version 1. @@ -18,6 +18,7 @@ ! J. Escobar 11/02/2020: for GA & // IO, add update_halo + sync, & mpi_allreduce for error handling in // IO ! P. Wautelet 22/09/2020: add IO_Format_read_select subroutine ! P. Wautelet 22/09/2020: use ldimreduced to allow reduction in the number of dimensions of fields (used by 2D simulations) +! P. Wautelet 21/06/2024: ensure that data can not be overwritten in case of read error !----------------------------------------------------------------- MODULE MODE_IO_FIELD_READ @@ -167,6 +168,7 @@ INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code INTEGER :: IERR INTEGER :: IRESP logical :: glfi, gnc4 +real :: zfield ! Intermediate data (always used for reads to not overwrite data in case of error) ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_X0',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -178,12 +180,13 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, pfield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfield, iresp ) + if ( iresp == 0 .or. iresp == -111 ) pfield = zfield ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, pfield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfield, iresp ) END IF ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) @@ -192,8 +195,12 @@ IF (IRESP==0) THEN !because metadata of field has been modified in IO_Field_read_xxx IF (IRESP==-111) CALL IO_Field_metadata_bcast(TPFILE,TPFIELD) ! - ! Broadcast Field - CALL MPI_BCAST(PFIELD,1,MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + if ( isp == tpfile%nmaster_rank ) pfield = zfield + ! Broadcast Field + CALL MPI_BCAST(PFIELD,1,MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + end if END IF END IF ! @@ -1357,6 +1364,7 @@ INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR INTEGER :: IRESP +integer :: ifield ! Intermediate data (always used for reads to not overwrite data in case of error) logical :: glfi, gnc4 ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_N0',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) @@ -1369,12 +1377,13 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, kfield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, kfield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ifield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ifield, iresp ) + if ( iresp == 0 .or. iresp == -111 ) kfield = ifield ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, kfield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, kfield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ifield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ifield, iresp ) END IF ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) @@ -1383,7 +1392,11 @@ IF (IRESP==0) THEN !because metadata of field has been modified in IO_Field_read_xxx IF (IRESP==-111) CALL IO_Field_metadata_bcast(TPFILE,TPFIELD) ! - CALL MPI_BCAST(KFIELD,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + if ( isp == tpfile%nmaster_rank ) kfield = ifield + CALL MPI_BCAST(KFIELD,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + end if END IF END IF ! @@ -1822,6 +1835,7 @@ INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR INTEGER :: IRESP +logical :: gfield ! Intermediate data (always used for reads to not overwrite data in case of error) logical :: glfi, gnc4 ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_L0',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) @@ -1834,12 +1848,13 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ofield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ofield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, gfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, gfield, iresp ) + if ( iresp == 0 .or. iresp == -111 ) ofield = gfield ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ofield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ofield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, gfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, gfield, iresp ) END IF ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) @@ -1848,7 +1863,12 @@ IF (IRESP==0) THEN !because metadata of field has been modified in IO_Field_read_xxx IF (IRESP==-111) CALL IO_Field_metadata_bcast(TPFILE,TPFIELD) ! - CALL MPI_BCAST(OFIELD,1,MNHLOG_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + if ( isp == tpfile%nmaster_rank ) ofield = gfield + ! Broadcast Field + CALL MPI_BCAST(OFIELD,1,MNHLOG_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + end if END IF END IF ! @@ -1956,9 +1976,10 @@ CLASS(TFIELDMETADATA), INTENT(INOUT) :: TPFIELD CHARACTER(LEN=*), INTENT(INOUT) :: HFIELD ! array containing the data field INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! -INTEGER :: IERR -INTEGER :: IRESP -logical :: glfi, gnc4 +CHARACTER(LEN=:), ALLOCATABLE :: YFIELD ! Intermediate data (always used for reads to not overwrite data in case of error) +INTEGER :: IERR +INTEGER :: IRESP +logical :: glfi, gnc4 ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_C0',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -1969,13 +1990,15 @@ CALL IO_File_read_check(TPFILE,'IO_Field_read_byfield_C0',IRESP) call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN + allocate( yfield, mold = hfield ) IF (GSMONOPROC) THEN ! sequential execution - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, hfield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, hfield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, yfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, yfield, iresp ) + if ( iresp == 0 .or. iresp == -111 ) hfield(:) = yfield(:) ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, hfield, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, hfield, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, yfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, yfield, iresp ) END IF ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) @@ -1984,7 +2007,12 @@ IF (IRESP==0) THEN !because metadata of field has been modified in IO_Field_read_xxx IF (IRESP==-111) CALL IO_Field_metadata_bcast(TPFILE,TPFIELD) ! - CALL MPI_BCAST(HFIELD,LEN(HFIELD),MPI_CHARACTER,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + if ( isp == tpfile%nmaster_rank ) hfield(:) = yfield(:) + ! Broadcast Field + CALL MPI_BCAST(HFIELD,LEN(HFIELD),MPI_CHARACTER,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + end if END IF END IF ! @@ -2031,6 +2059,7 @@ INTEGER :: IERR INTEGER :: IRESP INTEGER,DIMENSION(3) :: ITDATE logical :: glfi, gnc4 +type(date_time) :: tzdata ! Intermediate data (always used for reads to not overwrite data in case of error) ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_T0',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -2042,15 +2071,13 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, tpdata, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, tpdata, iresp ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, tzdata, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, tzdata, iresp ) + if ( iresp == 0 .or. iresp == -111 ) tpdata = tzdata ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, tpdata, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, tpdata, iresp ) - ITDATE(1) = TPDATA%nyear - ITDATE(2) = TPDATA%nmonth - ITDATE(3) = TPDATA%nday + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, tzdata, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, tzdata, iresp ) END IF ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) @@ -2059,11 +2086,20 @@ IF (IRESP==0) THEN !because metadata of field has been modified in IO_Field_read_xxx IF (IRESP==-111) CALL IO_Field_metadata_bcast(TPFILE,TPFIELD) ! - CALL MPI_BCAST( ITDATE, 3, MNHINT_MPI, TPFILE%NMASTER_RANK-1, TPFILE%NMPICOMM, IERR ) - CALL MPI_BCAST( TPDATA%xtime, 1, MNHREAL_MPI, TPFILE%NMASTER_RANK-1, TPFILE%NMPICOMM, IERR ) - TPDATA%nyear = ITDATE(1) - TPDATA%nmonth = ITDATE(2) - TPDATA%nday = ITDATE(3) + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + if ( isp == tpfile%nmaster_rank ) then + tpdata = tzdata + ITDATE(1) = TPDATA%nyear + ITDATE(2) = TPDATA%nmonth + ITDATE(3) = TPDATA%nday + end if + CALL MPI_BCAST( ITDATE, 3, MNHINT_MPI, TPFILE%NMASTER_RANK-1, TPFILE%NMPICOMM, IERR ) + CALL MPI_BCAST( TPDATA%xtime, 1, MNHREAL_MPI, TPFILE%NMASTER_RANK-1, TPFILE%NMPICOMM, IERR ) + TPDATA%nyear = ITDATE(1) + TPDATA%nmonth = ITDATE(2) + TPDATA%nday = ITDATE(3) + end if END IF END IF ! -- GitLab