From 58e71187ad96b9c1f5d33ccc191a3fa8f3888cbd Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Fri, 21 Jun 2024 15:25:52 +0200 Subject: [PATCH] Philippe 21/06/2024: IO_Field_read: 2D fields: ensure that data can not be overwritten in case of read error --- src/LIB/SURCOUCHE/src/mode_allocbuff.f90 | 78 +++++- src/LIB/SURCOUCHE/src/mode_io_field_read.f90 | 239 ++++++++++--------- 2 files changed, 196 insertions(+), 121 deletions(-) diff --git a/src/LIB/SURCOUCHE/src/mode_allocbuff.f90 b/src/LIB/SURCOUCHE/src/mode_allocbuff.f90 index 78c250031..17e624971 100644 --- a/src/LIB/SURCOUCHE/src/mode_allocbuff.f90 +++ b/src/LIB/SURCOUCHE/src/mode_allocbuff.f90 @@ -18,9 +18,9 @@ PRIVATE INTERFACE ALLOCBUFFER_ll MODULE PROCEDURE & - ALLOCBUFFER_X1, ALLOCBUFFER_NEW_X1, ALLOCBUFFER_X2, ALLOCBUFFER_X3, & + ALLOCBUFFER_X1, ALLOCBUFFER_NEW_X1, ALLOCBUFFER_X2, ALLOCBUFFER_NEW_X2, ALLOCBUFFER_X3, & ALLOCBUFFER_X4, ALLOCBUFFER_X5, ALLOCBUFFER_X6, & - ALLOCBUFFER_N1, ALLOCBUFFER_NEW_N1, ALLOCBUFFER_N2, ALLOCBUFFER_N3, & + ALLOCBUFFER_N1, ALLOCBUFFER_NEW_N1, ALLOCBUFFER_N2, ALLOCBUFFER_NEW_N2, ALLOCBUFFER_N3, & ALLOCBUFFER_N4, & ALLOCBUFFER_L1, ALLOCBUFFER_NEW_L1 END INTERFACE @@ -108,6 +108,35 @@ CASE default END SELECT END SUBROUTINE ALLOCBUFFER_N2 +SUBROUTINE ALLOCBUFFER_NEW_N2( KTAB_OUT, KTAB_IN, HDIR ) + USE MODD_IO, ONLY: LPACK, L2D + ! + INTEGER, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: KTAB_OUT + INTEGER, DIMENSION(:,:), INTENT(IN) :: KTAB_IN + CHARACTER(LEN=*), INTENT(IN) :: HDIR + + INTEGER :: IIMAX, IJMAX + + SELECT CASE(HDIR) + CASE('XX') + CALL GET_GLOBALDIMS_ll(IIMAX,IJMAX) + ALLOCATE(KTAB_OUT(IIMAX+2*JPHEXT,SIZE(KTAB_IN,2))) + CASE('YY') + CALL GET_GLOBALDIMS_ll(IIMAX,IJMAX) + ALLOCATE(KTAB_OUT(IJMAX+2*JPHEXT,SIZE(KTAB_IN,2))) + CASE('XY') + CALL GET_GLOBALDIMS_ll(IIMAX,IJMAX) + IF (LPACK .AND. L2D) THEN + ! 2D compact case + ALLOCATE(KTAB_OUT(IIMAX+2*JPHEXT,1)) + ELSE + ALLOCATE(KTAB_OUT(IIMAX+2*JPHEXT,IJMAX+2*JPHEXT)) + END IF + CASE default + ALLOCATE( KTAB_OUT, MOLD = KTAB_IN ) + END SELECT +END SUBROUTINE ALLOCBUFFER_NEW_N2 + SUBROUTINE ALLOCBUFFER_N3(KTAB_P,KTAB,HDIR,OALLOC) USE MODD_IO, ONLY: LPACK, L2D ! @@ -340,6 +369,51 @@ CASE default END SELECT END SUBROUTINE ALLOCBUFFER_X2 +SUBROUTINE ALLOCBUFFER_NEW_X2( PTAB_OUT, PTAB_IN, HDIR, KIMAX_ll, KJMAX_ll ) + USE MODD_IO, ONLY: LPACK, L2D + ! + REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: PTAB_OUT + REAL, DIMENSION(:,:), INTENT(IN) :: PTAB_IN + CHARACTER(LEN=*), INTENT(IN) :: HDIR + INTEGER, OPTIONAL, INTENT(IN) ::KIMAX_ll + INTEGER, OPTIONAL, INTENT(IN) ::KJMAX_ll + + INTEGER :: IIMAX,IJMAX + + SELECT CASE(HDIR) + CASE('XX') + IF( PRESENT(KIMAX_ll) .AND. PRESENT(KJMAX_ll) ) THEN + IIMAX = KIMAX_ll + IJMAX = KJMAX_ll + ELSE + CALL GET_GLOBALDIMS_ll(IIMAX,IJMAX) + ENDIF + ALLOCATE(PTAB_OUT(IIMAX+2*JPHEXT,SIZE(PTAB_IN,2))) + CASE('YY') + IF( PRESENT(KIMAX_ll) .AND. PRESENT(KJMAX_ll) ) THEN + IIMAX = KIMAX_ll + IJMAX = KJMAX_ll + ELSE + CALL GET_GLOBALDIMS_ll(IIMAX,IJMAX) + ENDIF + ALLOCATE(PTAB_OUT(IJMAX+2*JPHEXT,SIZE(PTAB_IN,2))) + CASE('XY') + IF( PRESENT(KIMAX_ll) .AND. PRESENT(KJMAX_ll) ) THEN + IIMAX = KIMAX_ll + IJMAX = KJMAX_ll + ELSE + CALL GET_GLOBALDIMS_ll(IIMAX,IJMAX) + ENDIF + IF (LPACK .AND. L2D) THEN ! 2D compact case + ALLOCATE(PTAB_OUT(IIMAX+2*JPHEXT,1)) + ELSE + ALLOCATE(PTAB_OUT(IIMAX+2*JPHEXT,IJMAX+2*JPHEXT)) + END IF + CASE default + ALLOCATE( PTAB_OUT, MOLD = PTAB_IN ) + END SELECT +END SUBROUTINE ALLOCBUFFER_NEW_X2 + SUBROUTINE ALLOCBUFFER_X3(PTAB_P,PTAB,HDIR,OALLOC) USE MODD_IO, ONLY: LPACK, L2D ! diff --git a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 index 44a565132..30a1f0987 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 @@ -344,7 +344,6 @@ USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_STRUCTURE_ll, ONLY: ZONE_ll USE MODD_TIMEZ, ONLY: TIMEZ ! -USE MODE_ALLOCBUFFER_ll #ifdef MNH_GA USE MODE_GA #endif @@ -365,10 +364,9 @@ INTEGER, OPTIONAL, INTENT(IN) :: KJMAX_ll TYPE(ZONE_ll), DIMENSION(ISNPROC), OPTIONAL, INTENT(IN) :: TPSPLITTING ! splitting of the domain ! INTEGER :: IERR -real :: zfieldp0d -real, dimension(:), pointer :: zfieldp1d -REAL, DIMENSION(:,:), POINTER :: ZFIELDP -LOGICAL :: GALLOC +real :: zfield0d +real, dimension(:), allocatable :: zfield1d +real, dimension(:,:), allocatable :: zfield2d logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT @@ -384,9 +382,7 @@ INTEGER :: IINFO_ll CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_X2',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! CALL SECOND_MNH2(ZT11) -GALLOC = .FALSE. IRESP = 0 -ZFIELDP => NULL() ! IHEXTOT = 2*JPHEXT+1 CALL IO_File_read_check(TPFILE,'IO_Field_read_byfield_X2',IRESP) @@ -396,45 +392,49 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution if ( lpack .and. l1d .and. Size( pfield, 1 ) == ihextot .and. Size( pfield, 2 ) == ihextot ) then - Allocate( tzfield, source = tpfield ) + allocate( tzfield, source = tpfield ) if ( tpfile%ldimreduced ) then tzfield%ndims = tzfield%ndims - 2 if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(1) = tzfield%ndimlist(3) !Necessary if time dimension tzfield%ndimlist(2:) = NMNHDIM_UNUSED end if - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp0d, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp0d, iresp ) - pfield(:, :) = Spread( Spread( zfieldp0d, dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfield0d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfield0d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + pfield(:, :) = Spread( Spread( zfield0d, dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) else if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(1:2) = NMNHDIM_ONE end if - zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) - pfield(:, :) = Spread( Spread( pfield(jphext + 1, jphext + 1), dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + allocate( zfield2d(1,1) ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfield2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfield2d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + pfield(:, :) = Spread( Spread( zfield2d(1,1), dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) endif else if ( lpack .and. l2d .and. Size( pfield, 2 ) == ihextot ) then - Allocate( tzfield, source = tpfield ) + allocate( tzfield, source = tpfield ) if ( tpfile%ldimreduced ) then tzfield%ndims = tzfield%ndims - 1 if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(2) = tzfield%ndimlist(3) !Necessary if time dimension tzfield%ndimlist(3:) = NMNHDIM_UNUSED end if - zfieldp1d => pfield(:, jphext + 1) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp1d, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp1d, iresp ) - pfield(:, :) = Spread( pfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + allocate( zfield1d(size(pfield,1)) ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfield1d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfield1d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + pfield(:, :) = Spread( zfield1d(:), dim = 2, ncopies = ihextot ) else if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(2) = NMNHDIM_ONE end if - zfieldp => pfield(:, jphext + 1 : jphext + 1) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) - pfield(:,:) = Spread( pfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + allocate( zfield2d(size(pfield,1),1) ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfield2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfield2d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + pfield(:,:) = Spread( zfield2d(:,1), dim = 2, ncopies = ihextot ) endif else if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) @@ -444,13 +444,12 @@ IF (IRESP==0) THEN CALL SECOND_MNH2(ZT0) IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case - CALL ALLOCBUFFER_ll(ZFIELDP,PFIELD,TPFIELD%CDIR,GALLOC, KIMAX_ll, KJMAX_ll) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfieldp, iresp ) + call Allocbuffer_ll( zfield2d, pfield, tpfield%cdir, kimax_ll, kjmax_ll ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfield2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfield2d, iresp ) ELSE !Not really necessary but useful to suppress alerts with Valgrind - ALLOCATE(ZFIELDP(0,0)) - GALLOC = .TRUE. + allocate( zfield2d(0,0) ) END IF CALL SECOND_MNH2(ZT1) TIMEZ%T_READ2D_READ=TIMEZ%T_READ2D_READ + ZT1 - ZT0 @@ -461,60 +460,62 @@ 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) ! - IF (TPFIELD%CDIR == 'XX' .OR. TPFIELD%CDIR == 'YY') THEN - ! XX or YY Scatter Field - CALL SCATTER_XXFIELD(TPFIELD%CDIR,ZFIELDP,PFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM,TPSPLITTING) - ELSE IF (TPFIELD%CDIR == 'XY') THEN - IF (LPACK .AND. L2D) THEN - ! 2D compact case - call Print_msg( NVERB_FATAL, 'GEN', 'IO_Field_read_byfield_X2', '2D not (yet) allowed for parallel execution' ) - CALL SCATTER_XXFIELD('XX',ZFIELDP(:,1),PFIELD(:,JPHEXT+1),TPFILE%NMASTER_RANK,TPFILE%NMPICOMM,TPSPLITTING) - PFIELD(:,:) = SPREAD(PFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) - ELSE + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + IF (TPFIELD%CDIR == 'XX' .OR. TPFIELD%CDIR == 'YY') THEN + ! XX or YY Scatter Field + CALL SCATTER_XXFIELD(TPFIELD%CDIR,zfield2d,PFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM,TPSPLITTING) + ELSE IF (TPFIELD%CDIR == 'XY') THEN + IF (LPACK .AND. L2D) THEN + ! 2D compact case + call Print_msg( NVERB_FATAL, 'GEN', 'IO_Field_read_byfield_X2', '2D not (yet) allowed for parallel execution' ) + CALL SCATTER_XXFIELD('XX',zfield2d(:,1),PFIELD(:,JPHEXT+1),TPFILE%NMASTER_RANK,TPFILE%NMPICOMM,TPSPLITTING) + PFIELD(:,:) = SPREAD(PFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) + ELSE #ifdef MNH_GA - ! - ! init/create the ga , dim3 = 1 - ! - CALL MNH_INIT_GA(SIZE(PFIELD,1),SIZE(PFIELD,2),1,TPFIELD%CMNHNAME,"READ") - IF (ISP == TPFILE%NMASTER_RANK) THEN ! - ! put the data in the g_a , this proc get this 1 slide + ! init/create the ga , dim3 = 1 ! - lo_zplan(JPIZ) = 1 - hi_zplan(JPIZ) = 1 - !print*,"IO_READ_FIELD_BYFIELD_X2::nga_put=",g_a, lo_zplan, hi_zplan, ld_zplan, TPFIELD%CMNHNAME ; call flush(6) - call nga_put(g_a, lo_zplan, hi_zplan,ZFIELDP, ld_zplan) - END IF - call ga_sync() - ! - ! get the columun data in this proc - ! - ! temp buf to avoid problem with none stride PFIELDS buffer with HALO - ALLOCATE (ZFIELD_GA (SIZE(PFIELD,1),SIZE(PFIELD,2))) - !print*,"IO_READ_FIELD_BYFIELD_X2::nga_get=",g_a, lo_col, hi_col, ld_col, TPFIELD%CMNHNAME ; call flush(6) - call nga_get(g_a, lo_col, hi_col,ZFIELD_GA(1,1) , ld_col) - PFIELD = ZFIELD_GA - call ga_sync() - NULLIFY(TZFIELD_ll) - CALL ADD2DFIELD_ll(TZFIELD_ll,PFIELD ) - CALL UPDATE_HALO_ll(TZFIELD_ll,IINFO_ll) - CALL CLEANLIST_ll(TZFIELD_ll) - DEALLOCATE(ZFIELD_GA) + CALL MNH_INIT_GA(SIZE(PFIELD,1),SIZE(PFIELD,2),1,TPFIELD%CMNHNAME,"READ") + IF (ISP == TPFILE%NMASTER_RANK) THEN + ! + ! put the data in the g_a , this proc get this 1 slide + ! + lo_zplan(JPIZ) = 1 + hi_zplan(JPIZ) = 1 + !print*,"IO_READ_FIELD_BYFIELD_X2::nga_put=",g_a, lo_zplan, hi_zplan, ld_zplan, TPFIELD%CMNHNAME ; call flush(6) + call nga_put(g_a, lo_zplan, hi_zplan,zfield2d, ld_zplan) + END IF + call ga_sync() + ! + ! get the columun data in this proc + ! + ! temp buf to avoid problem with none stride PFIELDS buffer with HALO + ALLOCATE (ZFIELD_GA (SIZE(PFIELD,1),SIZE(PFIELD,2))) + !print*,"IO_READ_FIELD_BYFIELD_X2::nga_get=",g_a, lo_col, hi_col, ld_col, TPFIELD%CMNHNAME ; call flush(6) + call nga_get(g_a, lo_col, hi_col,ZFIELD_GA(1,1) , ld_col) + PFIELD = ZFIELD_GA + call ga_sync() + NULLIFY(TZFIELD_ll) + CALL ADD2DFIELD_ll(TZFIELD_ll,PFIELD ) + CALL UPDATE_HALO_ll(TZFIELD_ll,IINFO_ll) + CALL CLEANLIST_ll(TZFIELD_ll) + DEALLOCATE(ZFIELD_GA) #else - ! XY Scatter Field - CALL SCATTER_XYFIELD(ZFIELDP,PFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + ! XY Scatter Field + CALL SCATTER_XYFIELD(zfield2d,PFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) #endif + END IF + ELSE + if ( isp == tpfile%nmaster_rank ) pfield(:,:) = zfield2d(:,:) + CALL MPI_BCAST(PFIELD,SIZE(PFIELD),MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) END IF - ELSE - CALL MPI_BCAST(PFIELD,SIZE(PFIELD),MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) END IF CALL SECOND_MNH2(ZT2) TIMEZ%T_READ2D_SCAT=TIMEZ%T_READ2D_SCAT + ZT2 - ZT1 END IF END IF ! -IF (GALLOC) DEALLOCATE (ZFIELDP) -! IF (IRESP==-111) IRESP = 0 !-111 is not really an error (metadata has changed) ! IF (PRESENT(KRESP)) KRESP = IRESP @@ -1521,7 +1522,6 @@ USE MODD_IO, ONLY: GSMONOPROC, ISP, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ ! -USE MODE_ALLOCBUFFER_ll USE MODE_SCATTER_ll ! TYPE(TFILEDATA), INTENT(IN) :: TPFILE @@ -1530,10 +1530,9 @@ INTEGER, DIMENSION(:,:), TARGET, INTENT(INOUT) :: KFIELD ! array containing th INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR -integer :: ifieldp0d -integer, dimension(:), pointer :: ifieldp1d -INTEGER, DIMENSION(:,:), POINTER :: IFIELDP -LOGICAL :: GALLOC +integer :: ifield0d +integer, dimension(:), ALLOCATABLE :: ifield1d +INTEGER, DIMENSION(:,:), ALLOCATABLE :: ifield2d logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT @@ -1541,9 +1540,7 @@ class(tfieldmetadata), allocatable :: tzfield ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_N2',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! -GALLOC = .FALSE. IRESP = 0 -IFIELDP => NULL() ! IHEXTOT = 2*JPHEXT+1 CALL IO_File_read_check(TPFILE,'IO_Field_read_byfield_N2',IRESP) @@ -1553,45 +1550,49 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution if ( lpack .and. l1d .and. Size( kfield, 1 ) == ihextot .and. Size( kfield, 2 ) == ihextot ) then - Allocate( tzfield, source = tpfield ) + allocate( tzfield, source = tpfield ) if ( tpfile%ldimreduced ) then tzfield%ndims = tzfield%ndims - 2 if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(1) = tzfield%ndimlist(3) !Necessary if time dimension tzfield%ndimlist(2:) = NMNHDIM_UNUSED end if - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp0d, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp0d, iresp ) - kfield(:, :) = Spread( Spread( ifieldp0d, dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifield0d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifield0d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + kfield(:, :) = Spread( Spread( ifield0d, dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) else if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(1:2) = NMNHDIM_ONE end if - ifieldp => kfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp, iresp ) - kfield(:, :) = Spread( Spread( kfield(jphext + 1, jphext + 1), dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + allocate( ifield2d(1,1) ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifield2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifield2d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + kfield(:, :) = Spread( Spread( ifield2d(1,1), dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) endif else if ( lpack .and. l2d .and. Size( kfield, 2 ) == ihextot ) then - Allocate( tzfield, source = tpfield ) + allocate( tzfield, source = tpfield ) if ( tpfile%ldimreduced ) then tzfield%ndims = tzfield%ndims - 1 if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(2) = tzfield%ndimlist(3) !Necessary if time dimension tzfield%ndimlist(3:) = NMNHDIM_UNUSED end if - ifieldp1d => kfield(:, jphext + 1) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp1d, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp1d, iresp ) - kfield(:, :) = Spread( kfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + allocate( ifield1d(size(kfield,1)) ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifield1d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifield1d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + kfield(:, :) = Spread( ifield1d(:), dim = 2, ncopies = ihextot ) else if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then tzfield%ndimlist(2) = NMNHDIM_ONE end if - ifieldp => kfield(:, jphext + 1 : jphext + 1) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp, iresp ) - kfield(:, :) = Spread( kfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + allocate( ifield2d(size(kfield,1),1) ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifield2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifield2d, iresp ) + if ( iresp == 0 .or. iresp == -111 ) & + kfield(:, :) = Spread( ifield2d(:,1), dim = 2, ncopies = ihextot ) endif else if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, kfield, iresp ) @@ -1600,13 +1601,12 @@ IF (IRESP==0) THEN ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case - CALL ALLOCBUFFER_ll(IFIELDP,KFIELD,TPFIELD%CDIR,GALLOC) - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ifieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ifieldp, iresp ) + call Allocbuffer_ll( ifield2d, kfield, tpfield%cdir ) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ifield2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ifield2d, iresp ) ELSE !Not really necessary but useful to suppress alerts with Valgrind - ALLOCATE(IFIELDP(0,0)) - GALLOC = .TRUE. + allocate( ifield2d(0,0) ) END IF ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) @@ -1615,30 +1615,31 @@ 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) ! - IF (TPFIELD%CDIR == 'XX' .OR. TPFIELD%CDIR == 'YY') THEN - ! XX or YY Scatter Field - CALL SCATTER_XXFIELD(TPFIELD%CDIR,IFIELDP,KFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) - ! Broadcast Field - CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) - ELSE IF (TPFIELD%CDIR == 'XY') THEN - IF (LPACK .AND. L2D) THEN - ! 2D compact case - call Print_msg( NVERB_FATAL, 'GEN', 'IO_Field_read_byfield_N2', '2D not (yet) allowed for parallel execution' ) - CALL SCATTER_XXFIELD('XX',IFIELDP(:,1),KFIELD(:,JPHEXT+1),TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) - KFIELD(:,:) = SPREAD(KFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) + !Share data only if no error + if ( iresp == 0 .or. iresp == -111 ) then + IF (TPFIELD%CDIR == 'XX' .OR. TPFIELD%CDIR == 'YY') THEN + ! XX or YY Scatter Field + CALL SCATTER_XXFIELD(TPFIELD%CDIR,ifield2d,KFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + ! Broadcast Field + CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + ELSE IF (TPFIELD%CDIR == 'XY') THEN + IF (LPACK .AND. L2D) THEN + ! 2D compact case + call Print_msg( NVERB_FATAL, 'GEN', 'IO_Field_read_byfield_N2', '2D not (yet) allowed for parallel execution' ) + CALL SCATTER_XXFIELD('XX',ifield2d(:,1),KFIELD(:,JPHEXT+1),TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + KFIELD(:,:) = SPREAD(KFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) + ELSE + ! XY Scatter Field + CALL SCATTER_XYFIELD(ifield2d,KFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + END IF ELSE - ! XY Scatter Field - CALL SCATTER_XYFIELD(IFIELDP,KFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + if (isp == tpfile%nmaster_rank) kfield = ifield2d + CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) END IF - ELSE - IF (ISP == TPFILE%NMASTER_RANK) KFIELD = IFIELDP - CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) - END IF + end if END IF END IF ! -IF (GALLOC) DEALLOCATE (IFIELDP) -! IF (IRESP==-111) IRESP = 0 !-111 is not really an error (metadata has changed) ! IF (PRESENT(KRESP)) KRESP = IRESP -- GitLab