From b93ce0fbd71a4def506087dac7354b0d7da88a89 Mon Sep 17 00:00:00 2001 From: Michael Duda Date: Fri, 16 Nov 2018 14:13:26 -0700 Subject: [PATCH 1/5] Change length of xtime variables to ShortStrKIND to match netCDF files This commit changes the declared length of xtime and similar timestamp variables in the mpas_io_streams module from StrKIND to ShortStrKIND to match the length of xtime in netCDF files. Prior to this change, because the in-memory xtime variable was larger than the in-file version, reading xtime could result in a string with garbage characters at the end (beginning at character ShortStrKIND+1). These gargbage characters, in turn, could lead to errors in the timekeeping module when trying to parse the string as a timestamp. By matching the in-memory size of the xtime variable with its size in files, we avoid this problem. --- src/framework/mpas_io_streams.F | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/framework/mpas_io_streams.F b/src/framework/mpas_io_streams.F index a7e8b53937..745534a319 100644 --- a/src/framework/mpas_io_streams.F +++ b/src/framework/mpas_io_streams.F @@ -148,12 +148,12 @@ integer function MPAS_seekStream(stream, seekTime, seekPosition, actualTime, max integer :: io_err integer :: i integer :: timeDim - character (len=StrKIND), dimension(:), pointer :: xtimes - character (len=StrKIND) :: strTemp + character (len=ShortStrKIND), dimension(:), pointer :: xtimes + character (len=ShortStrKIND) :: strTemp type (MPAS_Time_type) :: sliceTime, startTime type (MPAS_TimeInterval_type) :: timeDiff, minTimeDiff - character (len=StrKIND) :: xtime0, xtime1, xtime2, xtimeGuess + character (len=ShortStrKIND) :: xtime0, xtime1, xtime2, xtimeGuess type (MPAS_Time_type) :: time0, time1, time2, timeGuess, timeGuessData type (MPAS_TimeInterval_type) :: timeInterval @@ -1510,10 +1510,10 @@ subroutine MPAS_streamAddField_0dChar(stream, field, ierr) idim = ndims allocate(indices(0)) allocate(dimSizes(1)) - dimSizes(1) = 64 + dimSizes(1) = ShortStrKIND dimNames(1) = 'StrLen' - globalDimSize = 64 - totalDimSize = 64 + globalDimSize = ShortStrKIND + totalDimSize = ShortStrKIND if (field % isVarArray) then @@ -1602,7 +1602,7 @@ subroutine MPAS_streamAddField_1dChar(stream, field, ierr) idim = ndims allocate(indices(1)) allocate(dimSizes(2)) - dimSizes(1) = 64 + dimSizes(1) = ShortStrKIND dimNames(1) = 'StrLen' dimSizes(2) = field % dimSizes(1) dimNames(2) = field % dimNames(1) From 756f03e0c47c5e5f57617e5baf0c67b17d5b6f60 Mon Sep 17 00:00:00 2001 From: Michael Duda Date: Tue, 19 Feb 2019 15:53:34 -0700 Subject: [PATCH 2/5] Add new MPAS_sanitize_string routine to mpas_c_interfacing The MPAS_sanitize_string routine converts C null characters in a Fortran string to spaces. --- src/framework/mpas_c_interfacing.F | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/framework/mpas_c_interfacing.F b/src/framework/mpas_c_interfacing.F index dd885600f4..f6dc97edc5 100644 --- a/src/framework/mpas_c_interfacing.F +++ b/src/framework/mpas_c_interfacing.F @@ -4,6 +4,37 @@ module mpas_c_interfacing contains + !----------------------------------------------------------------------- + ! routine mpas_sanitize_string + ! + !> \brief Converts C null characters in a Fortran string to spaces + !> \author Michael Duda + !> \date 19 February 2019 + !> \details + !> Converts all C null characters in a Fortran string to spaces. + !> This may be useful for strings that were provided by C code through other + !> Fortran code external to MPAS. + ! + !----------------------------------------------------------------------- + subroutine mpas_sanitize_string(str) + + use iso_c_binding, only : c_null_char + + implicit none + + character(len=*), intent(inout) :: str + + integer :: i + + do i=1,len(str) + if (str(i:i) == c_null_char) then + str(i:i) = ' ' + end if + end do + + end subroutine mpas_sanitize_string + + !----------------------------------------------------------------------- ! routine mpas_c_to_f_string ! From 9bd56e6d121f4bf2742ba5acc3da4ceff6bee5f4 Mon Sep 17 00:00:00 2001 From: Michael Duda Date: Tue, 19 Feb 2019 15:55:02 -0700 Subject: [PATCH 3/5] Remove C null characters from strings read by PIO The PIO2 library fills in unused characters of a string variable with C null characters, and replaces C null characters with spaces when reading strings. However, the PIO1 library does not perform these conversions. Consequently, if a file written by the PIO2 library is read by the PIO1 library, C null characters may be present in the resulting Fortran string. Under the assumption that C null characters will generally not be expected or handled in MPAS (e.g., in timestamp strings), this commit makes calls to MPAS_sanitize_string to convert any C null characters in strings read by PIO into spaces. --- src/framework/mpas_io.F | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/framework/mpas_io.F b/src/framework/mpas_io.F index 2c17d3c661..7fcec3a76b 100644 --- a/src/framework/mpas_io.F +++ b/src/framework/mpas_io.F @@ -2187,6 +2187,8 @@ end subroutine MPAS_io_get_var_real5d subroutine MPAS_io_get_var_char0d(handle, fieldname, val, ierr) + use mpas_c_interfacing, only : MPAS_sanitize_string + implicit none type (MPAS_IO_Handle_type), intent(inout) :: handle @@ -2198,12 +2200,15 @@ subroutine MPAS_io_get_var_char0d(handle, fieldname, val, ierr) if (present(ierr)) ierr = MPAS_IO_NOERR call MPAS_io_get_var_generic(handle, fieldname, charVal=val, ierr=ierr) + call MPAS_sanitize_string(val) end subroutine MPAS_io_get_var_char0d subroutine MPAS_io_get_var_char1d(handle, fieldname, val, ierr) + use mpas_c_interfacing, only : MPAS_sanitize_string + implicit none type (MPAS_IO_Handle_type), intent(inout) :: handle @@ -2211,10 +2216,15 @@ subroutine MPAS_io_get_var_char1d(handle, fieldname, val, ierr) character (len=*), dimension(:), intent(out) :: val integer, intent(out), optional :: ierr + integer :: i + ! call mpas_log_write('Called MPAS_io_get_var_char1d()') if (present(ierr)) ierr = MPAS_IO_NOERR call MPAS_io_get_var_generic(handle, fieldname, charArray1d=val, ierr=ierr) + do i=1,size(val) + call MPAS_sanitize_string(val(i)) + end do end subroutine MPAS_io_get_var_char1d From 2c3faa5f45dfdd0499f1b43d8489ef42fe2fc594 Mon Sep 17 00:00:00 2001 From: Michael Duda Date: Thu, 21 Feb 2019 16:46:11 -0700 Subject: [PATCH 4/5] Increment version number to 6.2 --- LICENSE | 2 +- README.md | 2 +- src/core_atmosphere/Registry.xml | 2 +- src/core_init_atmosphere/Registry.xml | 2 +- src/core_landice/Registry.xml | 2 +- src/core_ocean/Registry.xml | 2 +- src/core_seaice/Registry.xml | 2 +- src/core_sw/Registry.xml | 2 +- src/core_test/Registry.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/LICENSE b/LICENSE index f6af5ee0a0..c8060c7f24 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2018, Los Alamos National Security, LLC (LANS) (Ocean: LA-CC-13-047; +Copyright (c) 2013-2019, Los Alamos National Security, LLC (LANS) (Ocean: LA-CC-13-047; Land Ice: LA-CC-13-117) and the University Corporation for Atmospheric Research (UCAR). All rights reserved. diff --git a/README.md b/README.md index 138deec514..b233bf28d0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MPAS-v6.1 +MPAS-v6.2 ==== The Model for Prediction Across Scales (MPAS) is a collaborative project for diff --git a/src/core_atmosphere/Registry.xml b/src/core_atmosphere/Registry.xml index 7fc056c536..e5bdcc370f 100644 --- a/src/core_atmosphere/Registry.xml +++ b/src/core_atmosphere/Registry.xml @@ -1,5 +1,5 @@ - + diff --git a/src/core_init_atmosphere/Registry.xml b/src/core_init_atmosphere/Registry.xml index 670439f648..c18e576c5a 100644 --- a/src/core_init_atmosphere/Registry.xml +++ b/src/core_init_atmosphere/Registry.xml @@ -1,5 +1,5 @@ - + diff --git a/src/core_landice/Registry.xml b/src/core_landice/Registry.xml index 5a4936794d..3deaa6bff4 100644 --- a/src/core_landice/Registry.xml +++ b/src/core_landice/Registry.xml @@ -1,5 +1,5 @@ - + diff --git a/src/core_ocean/Registry.xml b/src/core_ocean/Registry.xml index bde204347f..d8ff74a773 100644 --- a/src/core_ocean/Registry.xml +++ b/src/core_ocean/Registry.xml @@ -1,5 +1,5 @@ - + - + - + diff --git a/src/core_test/Registry.xml b/src/core_test/Registry.xml index fbdaaebff2..46f51ec59c 100644 --- a/src/core_test/Registry.xml +++ b/src/core_test/Registry.xml @@ -1,5 +1,5 @@ - + From 721f4efa0b83e0ab180d2b8b9e6cdf0235f72c34 Mon Sep 17 00:00:00 2001 From: Michael Duda Date: Thu, 7 Mar 2019 15:53:31 -0700 Subject: [PATCH 5/5] Add missing 'recursive' attribute to MPAS_log_write(...) routine The MPAS_log_write routine can generate indirectly recursive calls to itself, for example, when MPAS_log_write calls log_abort, which calls MPAS_log_finalize, which then calls MPAS_log_write. This commit simply adds the missing 'recursive' attribute to the MPAS_log_write routine. --- src/framework/mpas_log.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/mpas_log.F b/src/framework/mpas_log.F index eca3b43e82..6950341a14 100644 --- a/src/framework/mpas_log.F +++ b/src/framework/mpas_log.F @@ -461,7 +461,7 @@ end subroutine mpas_log_open ! !----------------------------------------------------------------------- - subroutine mpas_log_write(message, messageType, masterOnly, flushNow, & + recursive subroutine mpas_log_write(message, messageType, masterOnly, flushNow, & intArgs, realArgs, logicArgs, err) use mpas_threading