Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions applications/io_demo/build/project.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
# via the Makefile.

$(info io_demo miniapp project specials)
# Enable the use of the sleep() intrinsic for gfortran
export FFLAGS_GNU_OPTIONS = -fall-intrinsics
10 changes: 8 additions & 2 deletions applications/io_demo/example/configuration.nml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,20 @@ coord_system='native'
use_xios_io = .true.
write_diag = .true.
diagnostic_frequency = 1
subroutine_timers = .false.
subroutine_timers = .true.
timer_output_path = 'timer.txt'
subroutine_counters = .false.
counter_output_suffix = 'counter.txt'
checkpoint_read = .false.
checkpoint_write = .false.
file_convention = 'UGRID'
/

&io_demo
multifile_io = .false.
io_benchmark = .true.
n_benchmark_fields = 10
benchmark_sleep_time = 0
/

&logging
Expand All @@ -57,7 +63,7 @@ coord_system='native'
&time
calendar = 'timestep'
timestep_start = '1'
timestep_end = '90'
timestep_end = '10'
calendar_type='gregorian'
calendar_start='2016-01-01 15:00:00'
calendar_origin='2016-01-01 15:00:00'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
import=lfric-driver/HEAD

[namelist:io=multifile_io]
[namelist:io_demo]
compulsory=true
description=Provides options for configuring the runtime behaviour of the IO_Demo app
ns=namelist/io_demo
sort-key=Section-A02
title=IO_Demo

[namelist:io_demo=benchmark_sleep_time]
compulsory=true
description=Number of seconds to sleep for each timestep in I/O benchmark mode
!kind=default
type=integer

[namelist:io_demo=io_benchmark]
compulsory=true
description=Configure application to run as an I/O benchmarking tool
help=Configure application to run as an I/O benchmarking tool
!kind=default
type=logical

[namelist:io_demo=multifile_io]
compulsory=true
description=Use multifile_io functionality
help=This is used to turn the multifile_io functionality in the io_demo app
=on and off
!kind=default
type=logical

[namelist:io_demo=n_benchmark_fields]
compulsory=true
description=Number of fields created in I/O benchmark
!kind=default
type=integer

[namelist:multifile_io]
compulsory=false
duplicate=true
Expand Down
14 changes: 11 additions & 3 deletions applications/io_demo/source/algorithm/io_demo_alg_mod.x90
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,30 @@ contains

!> @details Calculates the diffusion increment for a field, and adds it to said field.
!> @param[inout] field_in Input Wtheta field
subroutine io_demo_alg( field_in )
!> @param[in] visc_in Optional setting for viscosity value
subroutine io_demo_alg( field_in, visc_in )

implicit none

! Prognostic fields
type( field_type ), intent( inout ) :: field_in
type( field_type ), intent( inout ) :: field_in
real(r_def), optional, intent( in ) :: visc_in

! Diagnostic fields
type( field_type ) :: dfield_in
type( field_type ) :: visc

real(r_def), parameter :: visc_val = 100000.0_r_def
real(r_def) :: visc_val
type(mesh_type), pointer :: mesh => null()
integer(kind=i_def), parameter :: stencil_depth = 1_i_def
type( field_type ), pointer :: dx_at_w2 => null()

! Set viscosity to default value if not present
if (present(visc_in)) then
visc_val = visc_in
else
visc_val = 100000.0_r_def
end if

call log_event( "io_demo: Running algorithm", LOG_LEVEL_TRACE )
mesh => field_in%get_mesh()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
!-----------------------------------------------------------------------------
! (C) Crown copyright Met Office. All rights reserved.
! The file LICENCE, distributed with this code, contains details of the terms
! under which the code may be used.
!-----------------------------------------------------------------------------

!> @brief Setup infrastructure used for I/O benchmark
!> @details Handles the setup of all the fields that will be passed used to
!! benchmark the speed of XIOS reading and writing
module io_benchmark_setup_mod

use constants_mod, only: i_def, str_def
use driver_modeldb_mod, only: modeldb_type
use field_collection_mod, only: field_collection_type
use field_mod, only: field_type
use field_parent_mod, only: read_interface, write_interface
use file_mod, only: FILE_MODE_WRITE
use fs_continuity_mod, only: Wtheta
use function_space_collection_mod, only: function_space_collection
use lfric_xios_file_mod, only: lfric_xios_file_type, OPERATION_TIMESERIES
use lfric_xios_read_mod, only: read_field_generic
use lfric_xios_write_mod, only: write_field_generic
use linked_list_mod, only: linked_list_type
use mesh_mod, only: mesh_type
use mesh_collection_mod, only: mesh_collection
use namelist_mod, only: namelist_type

implicit none

public create_io_benchmark_fields, setup_io_benchmark_files

contains

!> @details Creates the fields needed for the IO benchmark
!> @param[in,out] modeldb The model database in which to store model data.
subroutine create_io_benchmark_fields(modeldb)
implicit none

type(modeldb_type), intent(inout) :: modeldb

type(mesh_type), pointer :: mesh
type(field_collection_type), pointer :: io_benchmark_fields
type(field_type) :: tmp_io_field
procedure(read_interface), pointer :: tmp_read_ptr
procedure(write_interface), pointer :: tmp_write_ptr

type(namelist_type), pointer :: base_mesh_nml
type(namelist_type), pointer :: finite_element_nml
type(namelist_type), pointer :: io_demo_nml
type(namelist_type), pointer :: io_nml
character(str_def) :: prime_mesh_name, tmp_field_name
integer(i_def) :: element_order_h
integer(i_def) :: element_order_v
integer(i_def) :: i
integer(i_def) :: n_benchmark_fields
integer(i_def) :: diagnostic_frequency


base_mesh_nml => modeldb%configuration%get_namelist('base_mesh')
finite_element_nml => modeldb%configuration%get_namelist('finite_element')
io_demo_nml => modeldb%configuration%get_namelist('io_demo')
io_nml => modeldb%configuration%get_namelist('io')
call base_mesh_nml%get_value( 'prime_mesh_name', prime_mesh_name )
call finite_element_nml%get_value('element_order_h', element_order_h)
call finite_element_nml%get_value('element_order_v', element_order_v)
call io_demo_nml%get_value('n_benchmark_fields', n_benchmark_fields)
call io_nml%get_value('diagnostic_frequency', diagnostic_frequency)

mesh => mesh_collection%get_mesh(prime_mesh_name)

call modeldb%fields%add_empty_field_collection("io_benchmark_fields")
io_benchmark_fields => modeldb%fields%get_field_collection("io_benchmark_fields")

do i = 1, n_benchmark_fields
write(tmp_field_name, "(A19, I3.3)") 'io_benchmark_field_', i
call tmp_io_field%initialise( vector_space = &
function_space_collection%get_fs(mesh, element_order_h, &
element_order_v, Wtheta), &
name=tmp_field_name )
tmp_read_ptr => read_field_generic
tmp_write_ptr => write_field_generic
call tmp_io_field%set_read_behaviour(tmp_read_ptr)
call tmp_io_field%set_write_behaviour(tmp_write_ptr)
call io_benchmark_fields%add_field(tmp_io_field)
end do

end subroutine create_io_benchmark_fields

subroutine setup_io_benchmark_files(file_list, modeldb)

implicit none

type(linked_list_type), intent(out) :: file_list
type(modeldb_type), optional, intent(inout) :: modeldb

integer(i_def) :: diagnostic_frequency
type(field_collection_type), pointer :: io_benchmark_fields
type(namelist_type), pointer :: io_nml

io_nml => modeldb%configuration%get_namelist('io')
call io_nml%get_value('diagnostic_frequency', diagnostic_frequency)


io_benchmark_fields => modeldb%fields%get_field_collection("io_benchmark_fields")

file_list = linked_list_type()
call file_list%insert_item( lfric_xios_file_type( "lfric_xios_write_benchmark", &
xios_id="lfric_xios_write_benchmark", &
io_mode=FILE_MODE_WRITE, &
operation=OPERATION_TIMESERIES, &
freq=diagnostic_frequency, &
fields_in_file=io_benchmark_fields ) )

nullify(io_benchmark_fields)
nullify(io_nml)

end subroutine setup_io_benchmark_files

end module io_benchmark_setup_mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
!-----------------------------------------------------------------------------
! (C) Crown copyright Met Office. All rights reserved.
! The file LICENCE, distributed with this code, contains details of the terms
! under which the code may be used.
!-----------------------------------------------------------------------------

!> Steps the I/O benchmark section of IO_demo
module io_benchmark_step_mod

use constants_mod, only: i_def, r_def
use driver_modeldb_mod, only: modeldb_type
use field_mod, only: field_type
use field_parent_mod, only: field_parent_type
use field_collection_iterator_mod, &
only: field_collection_iterator_type
use field_collection_mod, only: field_collection_type
use log_mod, only: log_event, &
log_scratch_space, &
LOG_LEVEL_INFO
use namelist_mod, only: namelist_type

implicit none

private
public :: step_io_benchmark

contains

!> A simple timestep algorithm that copies the diffusion field into the
!! various benchmark fields and divides the entire field by the fields number
!!
!> @param[in,out] modeldb The model database
subroutine step_io_benchmark(modeldb)

implicit none

type(modeldb_type), optional, intent(inout) :: modeldb

type(field_collection_type), pointer :: depository
type(field_collection_type), pointer :: io_benchmark_fields
type(field_collection_iterator_type) :: field_iter
class(field_parent_type), pointer :: step_field
type(field_type), pointer :: kernel_field
type(field_type), pointer :: diffusion_field
type(namelist_type), pointer :: io_demo_nml

integer(i_def) :: i, sleep_duration
real(r_def) :: loop_factor

io_demo_nml => modeldb%configuration%get_namelist('io_demo')
call io_demo_nml%get_value('benchmark_sleep_time', sleep_duration)

! Get field data ready
depository => modeldb%fields%get_field_collection("depository")
io_benchmark_fields => modeldb%fields%get_field_collection("io_benchmark_fields")
call depository%get_field("diffusion_field", diffusion_field)

call field_iter%initialise(io_benchmark_fields)
do i = 1, io_benchmark_fields%get_length()
if ( .not. field_iter%has_next() ) exit
step_field => field_iter%next()
select type(step_field)
type is (field_type)
! Copy diffusion field values to new fields and adjust values
kernel_field => step_field
loop_factor = real(i, r_def)
call invoke( setval_X(kernel_field, diffusion_field), &
inc_X_divideby_a(kernel_field, loop_factor) )
end select

end do

write(log_scratch_space,'(A,I0,A)') "io_demo: sleeping for ", sleep_duration, " seconds"
call log_event(log_scratch_space, LOG_LEVEL_INFO)
call sleep(sleep_duration)

nullify(step_field)
nullify(kernel_field)
nullify(diffusion_field)

end subroutine step_io_benchmark

end module io_benchmark_step_mod
Loading
Loading