Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
40 changes: 23 additions & 17 deletions .github/workflows/fabm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,21 @@ jobs:
env:
FFLAGS: -fcheck=all
ifort:
# for available versions, see https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py
# for available versions, see https://github.com/spack/spack-packages/blob/develop/repos/spack_repo/builtin/packages/intel_oneapi_compilers/package.py
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
strategy:
matrix:
include:
- version: "2021.1.2.62"
url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/17508"
# - version: "2022.2.1.16992"
# - version: "l_fortran-compiler_p_2022.2.1.16992"
# url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/18998"
# - version: "2023.2.0.49254"
# - version: "l_fortran-compiler_p_2023.2.0.49254"
# url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/237236c4-434b-4576-96ac-020ceeb22619"
- version: "2024.2.0.426"
url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/801143de-6c01-4181-9911-57e00fe40181"
# - version: "l_fortran-compiler_p_2024.2.0.426"
# url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/801143de-6c01-4181-9911-57e00fe40181"
- version: "2024.2.1.80"
url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/5e7b0f1c-6f25-4cc8-94d7-3a527e596739"
fail-fast: false
runs-on: ubuntu-latest
env:
Expand Down Expand Up @@ -125,23 +127,26 @@ jobs:
env:
FFLAGS: ${{ env.FFLAGS }} -fp-model precise -fp-model source
ifx:
# for available versions, see https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py
# for available versions, see https://github.com/spack/spack-packages/blob/develop/repos/spack_repo/builtin/packages/intel_oneapi_compilers/package.py
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
strategy:
matrix:
include:
- version: "2023.2.0.49254"
- version: "l_fortran-compiler_p_2023.2.0.49254"
url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/237236c4-434b-4576-96ac-020ceeb22619"
fflags: -check all,nouninit,nocontiguous
# nouninit because https://community.intel.com/t5/Intel-Fortran-Compiler/ifx-missing-clang-rt-msan-to-link-Fortran-program-in-debug-build/m-p/1536555
# nocontiguous because spurious errors occur when assigning null() to contiguous pointers, see https://community.intel.com/t5/Intel-Fortran-Compiler/ifx-2024-0-2-runtime-error-about-non-contiguous-target/m-p/1583909
#- version: "2024.0.2.28"
#- version: "l_fortran-compiler_p_2024.0.2.28"
# url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/41df6814-ec4b-4698-a14d-421ee2b02aa7"
- version: "2024.2.0.426"
url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/801143de-6c01-4181-9911-57e00fe40181"
fflags: -check all,nouninit,nocontiguous
# memory sanitizer (uninit) still seems broken, as it reports errors in libc.so (it should be auto-linked to sanitized libc, but apparently not)
# contiguous check still broken, to be fixed in 2025.x as per https://community.intel.com/t5/Intel-Fortran-Compiler/ifx-2024-0-2-runtime-error-about-non-contiguous-target/m-p/1583909
# - version: "l_fortran-compiler_p_2024.2.0.426"
# url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/801143de-6c01-4181-9911-57e00fe40181"
# fflags: -check all,nouninit,nocontiguous
# # memory sanitizer (uninit) still seems broken, as it reports errors in libc.so (it should be auto-linked to sanitized libc, but apparently not)
# # contiguous check still broken, to be fixed in 2025.x as per https://community.intel.com/t5/Intel-Fortran-Compiler/ifx-2024-0-2-runtime-error-about-non-contiguous-target/m-p/1583909
- version: "intel-fortran-compiler-2025.2.0.534"
url_dir: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/2c69ab6a-dfff-4d8f-ae1c-8368c79a1709"
fflags: -check all
fail-fast: false
runs-on: ubuntu-latest
steps:
Expand All @@ -153,8 +158,8 @@ jobs:
run: python -m pip install --upgrade pip pyyaml
- name: Install compiler
run: |
wget --no-verbose ${{ matrix.url_dir }}/l_fortran-compiler_p_${{ matrix.version }}_offline.sh
/bin/sh l_fortran-compiler_p_${{ matrix.version }}_offline.sh -a --silent --cli --install-dir ${HOME}/intel --eula accept
wget --no-verbose ${{ matrix.url_dir }}/${{ matrix.version }}_offline.sh
/bin/sh ${{ matrix.version }}_offline.sh -a --silent --cli --install-dir ${HOME}/intel --eula accept
- name: Clone repository
uses: actions/checkout@v5
with:
Expand Down Expand Up @@ -226,7 +231,7 @@ jobs:
- name: Run all test cases with pyfabm
run: python util/developers/run_all_testcases.py pyfabm --show_logs --compiler /home/runner/nvhpc/Linux_x86_64/${{ matrix.version }}/compilers/bin/pgfortran
aocc:
# for available versions, see https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/aocc/package.py
# for available versions, see https://github.com/spack/spack-packages/blob/develop/repos/spack_repo/builtin/packages/aocc/package.py
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
strategy:
matrix:
Expand Down Expand Up @@ -286,12 +291,13 @@ jobs:
shell: cmd /C call {0}
env:
CMAKE_GENERATOR: Ninja
FFLAGS: -fno-vectorize -fno-slp-vectorize # -fno-vectorize requires flang 21 and later
steps:
- uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
- name: Install Python dependencies
run: conda install -c conda-forge pyyaml flang>=19.0 ninja c-compiler
run: conda install -c conda-forge pyyaml flang>=21.0 ninja c-compiler flang-rt_win-64
- name: Clone repository
uses: actions/checkout@v5
with:
Expand Down
126 changes: 112 additions & 14 deletions src/test/host.F90
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,16 @@ program test_host
integer :: domain_stop(_FABM_DIMENSION_COUNT_)

character(len=1024) :: version
character(len=20) :: arg
character(len=1024) :: arg
character(len=1024) :: fabm_yaml_path = 'fabm.yaml'
character(len=1024) :: diag_path = ''
integer :: ivar
integer :: i
integer :: mode = 1
integer :: ntest = -1
logical :: no_mask = .false.
logical :: no_diag = .false.
logical :: custom_path = .false.
real(rke) :: dt = 1._rke

#if _FABM_DIMENSION_COUNT_>0
Expand Down Expand Up @@ -238,6 +241,10 @@ program test_host
no_mask = .true.
case ('--nodiag')
no_diag = .true.
case ('--diag')
i = i + 1
call get_command_argument(i, arg)
read (arg,*) diag_path
#if _FABM_DIMENSION_COUNT_>0
case ('--nx')
i = i + 1
Expand Down Expand Up @@ -269,18 +276,37 @@ program test_host
write (*,'(a)') ''
write (*,'(a)') 'FABM host emulator'
write (*,'(a)') ''
write (*,'(a)') 'Accepted arguments:'
write (*,'(a)') 'Usage: test_host [options] [fabm.yaml]'
write (*,'(a)') ''
write (*,'(a)') 'Options:'
write (*,'(a)') '-s/--simulate: simulate using provided fabm.yaml/environment.yaml'
write (*,'(a)') '-n: number of replicates when simulating'
write (*,'(a)') '-n N: number of replicates when simulating'
#if _FABM_DIMENSION_COUNT_>0
write (*,'(a)') '--nx NX: size of first dimension'
#endif
#if _FABM_DIMENSION_COUNT_>1
write (*,'(a)') '--ny NY: size of second dimension'
#endif
#if _FABM_DIMENSION_COUNT_>2
write (*,'(a)') '--nz NZ: size of third dimension'
#endif
write (*,'(a)') '--dt DT: time step (s) when simulating'
write (*,'(a)') '--nomask: unmask all points when simulating'
write (*,'(a)') '--nodiag: flag all diagnostics as not required by the host'
write (*,'(a)') '--diag FILE: yaml file with diagnostics selection (list of names)'
stop 0
case default
write (*,'(a)') 'ERROR'
write (*,'(a)') ''
write (*,'(a)') 'Unknown command line argument: ' // trim(arg)
write (*,'(a)') 'To see supported arguments, run with -h.'
stop 2
if (mode == 2 .and. .not. custom_path) then
! First unknown argument in simulate mode is the path to fabm.yaml
fabm_yaml_path = trim(arg)
custom_path = .true.
else
write (*,'(a)') 'ERROR'
write (*,'(a)') ''
write (*,'(a)') 'Unknown command line argument: ' // trim(arg)
write (*,'(a)') 'To see supported arguments, run with -h.'
stop 2
end if
end select
i = i + 1
end do
Expand Down Expand Up @@ -327,7 +353,7 @@ program test_host
call model%root%add_child(test_model, 'test_model', 'test model')
case (2)
! Test with user-provided fabm.yaml
model => fabm_create_model(initialize=.false.)
model => fabm_create_model(fabm_yaml_path, initialize=.false.)
end select
call report_test_result()

Expand All @@ -341,9 +367,10 @@ program test_host
end if
call report_test_result()

if (no_diag) then
if (no_diag .or. diag_path /= '') then
model%interior_diagnostic_variables%save = .false.
model%horizontal_diagnostic_variables%save = .false.
if (diag_path /= '') call read_diagnostics_selection
end if

! ======================================================================
Expand Down Expand Up @@ -495,6 +522,61 @@ program test_host

contains

subroutine read_diagnostics_selection
use yaml, only: yaml_parse => parse, yaml_error_length => error_length
use yaml_types, only: type_node, type_scalar, type_yaml_list => type_list, &
type_yaml_list_item => type_list_item, yaml_real_kind => real_kind

character(yaml_error_length) :: yaml_error
class (type_node), pointer :: yaml_root
type (type_yaml_list_item), pointer :: yaml_item

yaml_root => yaml_parse(diag_path, get_free_unit(), yaml_error)
if (yaml_error /= '') then
call driver%log_message(yaml_error)
stop 2
end if
select type (yaml_root)
class is (type_yaml_list)
yaml_item => yaml_root%first
do while (associated(yaml_item))
select type (node => yaml_item%node)
class is (type_scalar)
if (.not. select_for_saving(node%string)) then
call driver%log_message(trim(diag_path) // ': diagnostic ' // trim(node%string) // ' not found in model.')
stop 2
end if
class default
call driver%log_message(trim(diag_path) // ' should contain a list of strings')
stop 2
end select
yaml_item => yaml_item%next
end do
class default
call driver%log_message(trim(diag_path) // ' should contain a list at root level')
stop 2
end select
end subroutine read_diagnostics_selection

logical function select_for_saving(name)
character(len=*), intent(in) :: name
integer :: i
select_for_saving = .true.
do i = 1, size(model%interior_diagnostic_variables)
if (name == model%interior_diagnostic_variables(i)%name) then
model%interior_diagnostic_variables(i)%save = .true.
return
end if
end do
do i = 1, size(model%horizontal_diagnostic_variables)
if (name == model%horizontal_diagnostic_variables(i)%name) then
model%horizontal_diagnostic_variables(i)%save = .true.
return
end if
end do
select_for_saving = .false.
end function

subroutine read_environment
use yaml, only: yaml_parse => parse, yaml_error_length => error_length
use yaml_types, only: type_node, type_scalar, type_yaml_dictionary => type_dictionary, &
Expand Down Expand Up @@ -839,20 +921,36 @@ subroutine simulate(n)
#if _FABM_BOTTOM_INDEX_==-1 && !defined(_HAS_MASK_) && _FABM_VECTORIZED_DIMENSION_INDEX_==_FABM_DEPTH_DIMENSION_INDEX_ && defined(_FABM_DEPTH_DIMENSION_INDEX_)
! We are looping over depth, but as we have a non-constant bottom index (yet no mask), we need to skip everything below bottom
# ifdef _FABM_VERTICAL_BOTTOM_TO_SURFACE_
_START_ = bottom_index _INDEX_HORIZONTAL_LOCATION_
_START_ = bottom_index _INDEX_HORIZONTAL_LOCATION_
# else
_STOP_ = bottom_index _INDEX_HORIZONTAL_LOCATION_
_STOP_ = bottom_index _INDEX_HORIZONTAL_LOCATION_
# endif
#endif
call model%get_interior_sources(_PREARG_INTERIOR_IN_ dy _INTERIOR_SLICE_RANGE_PLUS_1_)
_END_OUTER_INTERIOR_LOOP_
#if _FABM_BOTTOM_INDEX_==-1 && !defined(_HAS_MASK_) && _FABM_VECTORIZED_DIMENSION_INDEX_==_FABM_DEPTH_DIMENSION_INDEX_ && defined(_FABM_DEPTH_DIMENSION_INDEX_)
_START_ = domain_start(_FABM_VECTORIZED_DIMENSION_INDEX_)
_STOP_ = domain_stop(_FABM_VECTORIZED_DIMENSION_INDEX_)
_START_ = domain_start(_FABM_VECTORIZED_DIMENSION_INDEX_)
_STOP_ = domain_stop(_FABM_VECTORIZED_DIMENSION_INDEX_)
# endif

call model%finalize_outputs()

_BEGIN_OUTER_INTERIOR_LOOP_
#if _FABM_BOTTOM_INDEX_==-1 && !defined(_HAS_MASK_) && _FABM_VECTORIZED_DIMENSION_INDEX_==_FABM_DEPTH_DIMENSION_INDEX_ && defined(_FABM_DEPTH_DIMENSION_INDEX_)
! We are looping over depth, but as we have a non-constant bottom index (yet no mask), we need to skip everything below bottom
# ifdef _FABM_VERTICAL_BOTTOM_TO_SURFACE_
_START_ = bottom_index _INDEX_HORIZONTAL_LOCATION_
# else
_STOP_ = bottom_index _INDEX_HORIZONTAL_LOCATION_
# endif
#endif
call model%get_vertical_movement(_PREARG_INTERIOR_IN_ w _INTERIOR_SLICE_RANGE_PLUS_1_)
_END_OUTER_INTERIOR_LOOP_
#if _FABM_BOTTOM_INDEX_==-1 && !defined(_HAS_MASK_) && _FABM_VECTORIZED_DIMENSION_INDEX_==_FABM_DEPTH_DIMENSION_INDEX_ && defined(_FABM_DEPTH_DIMENSION_INDEX_)
_START_ = domain_start(_FABM_VECTORIZED_DIMENSION_INDEX_)
_STOP_ = domain_stop(_FABM_VECTORIZED_DIMENSION_INDEX_)
# endif

_BEGIN_OUTER_HORIZONTAL_LOOP_
call model%check_bottom_state(_PREARG_HORIZONTAL_IN_ repair, valid)
_END_OUTER_HORIZONTAL_LOOP_
Expand Down
8 changes: 2 additions & 6 deletions util/developers/run_all_testcases.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,6 @@ def test_0d(args, testcases: Mapping[str, str], gotm_url=DEFAULT_GOTM_URL):


def test_harness(args, testcases: Mapping[str, str]):
run_dir = os.path.join(args.work_root, "run")
os.mkdir(run_dir)
shutil.copy(os.path.join(SCRIPT_ROOT, "environment.yaml"), run_dir)
print("Running FABM testcases with testing harness:")
for host in sorted(os.listdir(os.path.join(FABM_BASE, "src/drivers"))):
print(f" host {host}")
Expand All @@ -462,11 +459,10 @@ def test_harness(args, testcases: Mapping[str, str]):
if not os.path.isfile(os.path.join(build_dir, exe)):
exe = os.path.join("Debug", exe)
for case, path in testcases.items():
shutil.copy(path, os.path.join(run_dir, "fabm.yaml"))
run(
f"test_harness/{host}/{case}",
[os.path.join(build_dir, exe), "--simulate", "-n", "10"],
cwd=run_dir,
[os.path.join(build_dir, exe), "--simulate", "-n", "10", path],
cwd=SCRIPT_ROOT,
)


Expand Down
Loading