Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
66c7402
Add source code changes from previous Trac branch
EdHone Jan 13, 2026
1b21148
Remove old timer implementation
EdHone Jan 20, 2026
48e0a39
Bring in metadata from previous branch
EdHone Jan 13, 2026
b5fed78
Use 'native' Fortran sleep
EdHone Jan 14, 2026
83c41c1
Fix upgrade macro
EdHone Jan 16, 2026
365ae7c
Macro whitespace
EdHone Jan 16, 2026
bc512ee
Macro whitespace
EdHone Jan 16, 2026
566f018
Manual implementation of metadata - test suite runs but tests broken
EdHone Jan 19, 2026
c7fd86f
Fix metadata issues
EdHone Jan 19, 2026
ceeffd1
Fix builds and suite running
EdHone Jan 19, 2026
92085cd
small benchmark cases in developer suite
EdHone Jan 19, 2026
b483318
Interim test configs working
EdHone Jan 19, 2026
6a26746
Working tests for benchmark case
EdHone Jan 19, 2026
d34d96b
Clean up branch
EdHone Jan 20, 2026
90b4e72
Fixes for developer suite
EdHone Jan 21, 2026
86a546c
Final implementation
EdHone Feb 2, 2026
b20e02b
change vernieer output mode
EdHone Feb 2, 2026
1281590
RW comments - new namelist API and rose metadata triggers
EdHone Feb 4, 2026
d6dc8ee
More efficient function space assignment
EdHone Feb 4, 2026
b22275d
fix indentation
EdHone Feb 4, 2026
4877a8b
Update applications/io_demo/source/driver/io_demo_driver_mod.f90
EdHone Feb 6, 2026
4974278
Revert example file
EdHone Feb 24, 2026
fb90be7
LG review comments
EdHone Mar 4, 2026
14f67a2
Merge branch 'main' into 216-iodemo-bench-vernier
EdHone Mar 4, 2026
03e1316
Merge branch 'main' into 216-iodemo-bench-vernier
EdHone Mar 4, 2026
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
6 changes: 6 additions & 0 deletions applications/io_demo/example/configuration.nml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ coord_system='native'
checkpoint_read = .false.
checkpoint_write = .false.
file_convention = 'UGRID'
/

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

&logging
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
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
trigger=namelist:io_demo=benchmark_sleep_time: .true. ;
=namelist:io_demo=n_benchmark_fields: .true. ;

[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 @@ -35,27 +35,35 @@ contains
!> @details Calculates the diffusion increment for a field, and adds it to said field.
!> @param[in] modeldb Application state object
!> @param[inout] field_in Input Wtheta field
subroutine io_demo_alg( modeldb, field_in )
!> @param[in] visc_in Optional setting for viscosity value
subroutine io_demo_alg( modeldb, field_in, visc_in )

implicit none

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

! 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
integer(kind=i_def), parameter :: stencil_depth = 1_i_def

type(mesh_type), pointer :: mesh
type(field_type), pointer :: dx_at_w2
type(function_space_type), pointer :: fs

integer(i_def) :: order_h, order_v
! 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 )

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
!-----------------------------------------------------------------------------
! (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_mod, only: function_space_type
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

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(function_space_type), pointer :: wtheta_fs

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

prime_mesh_name = modeldb%config%base_mesh%prime_mesh_name()
element_order_h = modeldb%config%finite_element%element_order_h()
element_order_v = modeldb%config%finite_element%element_order_v()
n_benchmark_fields = modeldb%config%io_demo%n_benchmark_fields()
diagnostic_frequency = modeldb%config%io%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")
wtheta_fs => function_space_collection%get_fs( mesh, element_order_h, &
element_order_v, Wtheta )

do i = 1, n_benchmark_fields
write(tmp_field_name, "(A19, I3.3)") 'io_benchmark_field_', i
call tmp_io_field%initialise( vector_space = wtheta_fs, &
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

nullify( mesh, io_benchmark_fields, wtheta_fs )

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

diagnostic_frequency = modeldb%config%io%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)

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,80 @@
!-----------------------------------------------------------------------------
! (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

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

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

sleep_duration = modeldb%config%io_demo%benchmark_sleep_time()

! 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