Skip to content

Commit

Permalink
Merge branch 'framework/validation-of-streams-using-interval_in-inter…
Browse files Browse the repository at this point in the history
…val_out' into develop

This merge introduces the framework for validating streams at the end
of the model initialization. The intention of the new routine
MPAS_stream_mgr_validate_streams is to perform a validation of streams
that is above the low-level checks in xml_stream_parser.c, but still
generic enough to apply to all cores.

The new routine MPAS_stream_mgr_validate_streams currently does nothing
but providing a commented-out block of code to demonstrate its usage for
the specific example of a SIONlib stream, which must contain exactly
one timestamp per file.

* framework/validation-of-streams-using-interval_in-interval_out:
  New function to validate streams and call to it towards the end of mpas_init. ...
  • Loading branch information
mgduda committed Sep 26, 2017
2 parents e466b46 + c34f47c commit 9116da3
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/driver/mpas_subdriver.F
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module mpas_subdriver

subroutine mpas_init()

use mpas_stream_manager, only : MPAS_stream_mgr_init, MPAS_build_stream_filename
use mpas_stream_manager, only : MPAS_stream_mgr_init, MPAS_build_stream_filename, MPAS_stream_mgr_validate_streams
use iso_c_binding, only : c_char, c_loc, c_ptr, c_int
use mpas_c_interfacing, only : mpas_f_to_c_string, mpas_c_to_f_string
use mpas_timekeeping, only : mpas_get_clock_time, mpas_get_time
Expand Down Expand Up @@ -311,6 +311,15 @@ end subroutine xml_stream_get_attributes
call mpas_dmpar_abort(domain_ptr % dminfo)
end if

!
! Validate streams after set-up
!
call mpas_log_write(' ** Validating streams')
call MPAS_stream_mgr_validate_streams(domain_ptr % streamManager, ierr = ierr)
if ( ierr /= MPAS_STREAM_MGR_NOERR ) then
call mpas_dmpar_global_abort('ERROR: Validation of streams failed for core ' // trim(domain_ptr % core % coreName))
end if

!
! Finalize the setup of blocks and fields
!
Expand Down
107 changes: 107 additions & 0 deletions src/framework/mpas_stream_manager.F
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module mpas_stream_manager
public :: MPAS_stream_mgr_init, &
MPAS_stream_mgr_finalize, &
MPAS_stream_mgr_create_stream, &
MPAS_stream_mgr_validate_streams, &
MPAS_stream_mgr_destroy_stream, &
MPAS_stream_mgr_get_clock, &
MPAS_stream_mgr_set_property, &
Expand Down Expand Up @@ -412,6 +413,112 @@ subroutine MPAS_stream_mgr_create_stream(manager, streamID, direction, filename,
end subroutine MPAS_stream_mgr_create_stream!}}}


!-----------------------------------------------------------------------
! routine MPAS_stream_mgr_validate_streams
!
!> \brief Validate all streams or one stream, if optional argument streamID is present.
!> \author Dom Heinzeller
!> \date 12 September 2017
!> \details
!> Validates all streams of a stream manager, or one stream if optional argument
!> streamID is specified. A low-level validation of streams happens within
!> xml_stream_parser in xml_stream_parser.c (e.g. immutable streams must not be
!> specified as mutable streams etc.). MPAS_stream_mgr_validate_streams performs
!> higher-level checks that should stay separate from the low-level checks and
!> that may require additional logic or settings not necessarily present when
!> calling xml_stream_parser.
!
!-----------------------------------------------------------------------
subroutine MPAS_stream_mgr_validate_streams(manager, streamID, ierr)!{{{

implicit none

type (MPAS_streamManager_type), intent(inout) :: manager
character (len=*), intent(in), optional :: streamID
integer, intent(out), optional :: ierr

character(len=StrKIND) :: stream_name
character(len=StrKIND) :: filename_interval
integer :: direction, io_type
character (len=StrKIND) :: message
integer :: err_local

! For future validation of SIONlib data - need to check that there is only one timestamp per file
type (MPAS_TimeInterval_type) :: time_interval_zero, time_interval_file, time_interval_input, time_interval_output

if (present(streamID)) then
STREAM_DEBUG_WRITE('-- Called MPAS_stream_mgr_validate_streams() for '//trim(streamID))
else
STREAM_DEBUG_WRITE('-- Called MPAS_stream_mgr_validate_streams() for all streams')
end if

if (present(ierr)) ierr = MPAS_STREAM_MGR_NOERR
call mpas_set_timeInterval(time_interval_zero, dt = 0.0)

if (present(streamID)) then
call MPAS_stream_mgr_begin_iteration(manager, streamID, ierr=err_local)
if (err_local .eq. MPAS_STREAM_MGR_ERROR) then
if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR
return
end if
end if

call MPAS_stream_mgr_begin_iteration(manager)
do while (MPAS_stream_mgr_get_next_stream(manager, streamID = stream_name, directionProperty = direction, &
filenameIntervalProperty = filename_interval))
if (present(streamID)) then
if (trim(streamID) .ne. trim(stream_name)) cycle
end if
STREAM_DEBUG_WRITE('-- Validating stream '//trim(stream_name))
call MPAS_stream_mgr_get_property(manager, stream_name, MPAS_STREAM_PROPERTY_IOTYPE, io_type)

#if 0
! Placeholder for testing additional consistency checks for future SIONlib implementation,
! and demo of how to use MPAS_stream_mgr_get_stream_interval for directions input/output.
if (io_type == MPAS_IO_SIONLIB) then

if (trim(filename_interval) /= 'none') then
call mpas_set_timeInterval(time_interval_file, timeString=filename_interval)
else
call mpas_set_timeInterval(time_interval_file, dt = 0.0)
end if

if (direction == MPAS_STREAM_INPUT .or. direction == MPAS_STREAM_INPUT_OUTPUT) then
time_interval_input = MPAS_stream_mgr_get_stream_interval(manager, stream_name, MPAS_STREAM_INPUT, err_local)
if (err_local /= MPAS_STREAM_MGR_NOERR) then
if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR
return
end if
if (time_interval_input .gt. time_interval_zero) then
if ( (time_interval_file .eq. time_interval_zero) .or. (time_interval_file .gt. time_interval_input) ) then
message = 'Filename interval is larger than input interval for SIONlib stream ''' // trim(stream_name) //''' (only one time stamp per file allowed).'
call mpas_log_write(message, MPAS_LOG_CRIT)
end if
end if
end if

if (direction == MPAS_STREAM_OUTPUT .or. direction == MPAS_STREAM_INPUT_OUTPUT) then
time_interval_output = MPAS_stream_mgr_get_stream_interval(manager, stream_name, MPAS_STREAM_OUTPUT, err_local)
if (err_local /= MPAS_STREAM_MGR_NOERR) then
if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR
return
end if
if (time_interval_output .gt. time_interval_zero) then
if ( (time_interval_file .eq. time_interval_zero) .or. (time_interval_file .gt. time_interval_output) ) then
message = 'Filename interval is larger than output interval for SIONlib stream ''' // trim(stream_name) //''' (only one time stamp per file allowed).'
call mpas_log_write(message, MPAS_LOG_CRIT)
end if
end if
end if

end if
#endif

end do

end subroutine MPAS_stream_mgr_validate_streams!}}}


!-----------------------------------------------------------------------
! routine MPAS_stream_mgr_destroy_stream
!
Expand Down

0 comments on commit 9116da3

Please sign in to comment.