From e763fb1b2daa2f3d265577c2b038aa7115b8031c Mon Sep 17 00:00:00 2001 From: Kuan-Chih Wang Date: Tue, 24 Mar 2026 13:12:46 -0600 Subject: [PATCH 1/5] Work around Intel compiler issues * When `-warn all` is specified, the unit tests fail to compile with errors like: error #7977: The type of the function reference does not match the type of the function definition. The errors are found to occur in pFUnit-generated code, which is outside of our control. Work around it with `-warn all,nointerfaces`. * Placing `use funit` in the smallest scoping unit causes excessive compile time for Intel compilers. Compiling the unit tests can take 20-30 minutes, which is absolutely not normal. Work around it by moving `use funit` to the module level as an exception to the coding standards. --- src/dynamics/mpas/tests/unit/CMakeLists.txt | 8 ++-- .../tests/unit/test_dyn_mpas_procedures.pf | 45 +------------------ .../mpas/tests/unit/test_dyn_procedures.pf | 31 +------------ 3 files changed, 8 insertions(+), 76 deletions(-) diff --git a/src/dynamics/mpas/tests/unit/CMakeLists.txt b/src/dynamics/mpas/tests/unit/CMakeLists.txt index 7e2f5cd26..e6a862145 100644 --- a/src/dynamics/mpas/tests/unit/CMakeLists.txt +++ b/src/dynamics/mpas/tests/unit/CMakeLists.txt @@ -9,8 +9,8 @@ add_pfunit_ctest(test_dyn_mpas_procedures target_compile_options(test_dyn_mpas_procedures PRIVATE $<$,$>:-fbacktrace -fcheck=all -ffpe-trap=invalid,overflow,zero -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans -std=f2018 -Wall -Wextra -Wpedantic> - $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all> - $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all> + $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all,nointerfaces> + $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all,nointerfaces> ) add_pfunit_ctest(test_dyn_procedures @@ -22,6 +22,6 @@ add_pfunit_ctest(test_dyn_procedures target_compile_options(test_dyn_procedures PRIVATE $<$,$>:-fbacktrace -fcheck=all -ffpe-trap=invalid,overflow,zero -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans -std=f2018 -Wall -Wextra -Wpedantic> - $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all> - $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all> + $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all,nointerfaces> + $<$,$>:-check all -fp-model=precise -stand f18 -traceback -warn all,nointerfaces> ) diff --git a/src/dynamics/mpas/tests/unit/test_dyn_mpas_procedures.pf b/src/dynamics/mpas/tests/unit/test_dyn_mpas_procedures.pf index cb402afe6..8a1a010a0 100644 --- a/src/dynamics/mpas/tests/unit/test_dyn_mpas_procedures.pf +++ b/src/dynamics/mpas/tests/unit/test_dyn_mpas_procedures.pf @@ -8,6 +8,8 @@ !> units in the last place (ULP). Otherwise, tolerance should be chosen based on significant figures. !> For utility procedures, standard unit testing practices apply. module test_dyn_mpas_procedures + use funit + implicit none private @@ -59,7 +61,6 @@ contains subroutine test_dzw_of_rdzw_by_known_values_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: dzw_of_rdzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -95,7 +96,6 @@ contains subroutine test_dzw_of_rdzw_by_known_values_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: dzw_of_rdzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -131,7 +131,6 @@ contains subroutine test_dzu_of_dzw_by_known_values_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: dzu_of_dzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -184,7 +183,6 @@ contains subroutine test_dzu_of_dzw_by_known_values_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: dzu_of_dzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -237,7 +235,6 @@ contains subroutine test_zu_of_dzw_by_known_values_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: zu_of_dzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -291,7 +288,6 @@ contains subroutine test_zu_of_dzw_by_known_values_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: zu_of_dzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -345,7 +341,6 @@ contains subroutine test_zw_of_dzw_by_known_values_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: zw_of_dzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -400,7 +395,6 @@ contains subroutine test_zw_of_dzw_by_known_values_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: zw_of_dzw - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 1 @@ -455,7 +449,6 @@ contains subroutine test_almost_divisible_by_properties_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: almost_divisible - use funit ! Division of zero. @assertTrue(almost_divisible(0.0_real32, 1776.0_real32)) @@ -505,7 +498,6 @@ contains subroutine test_almost_divisible_by_properties_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: almost_divisible - use funit ! Division of zero. @assertTrue(almost_divisible(0.0_real64, 1776.0_real64)) @@ -555,7 +547,6 @@ contains subroutine test_almost_divisible_by_inexact_arithmetic_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: almost_divisible - use funit integer :: i real(real32) :: a, b @@ -582,7 +573,6 @@ contains subroutine test_almost_divisible_by_inexact_arithmetic_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: almost_divisible - use funit integer :: i real(real64) :: a, b @@ -609,7 +599,6 @@ contains subroutine test_almost_divisible_by_precision_limits_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: almost_divisible - use funit @assertFalse(almost_divisible(1776.0_real32, 1776.1_real32)) @assertFalse(almost_divisible(1776.0_real32, 1776.01_real32)) @@ -628,7 +617,6 @@ contains subroutine test_almost_divisible_by_precision_limits_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: almost_divisible - use funit @assertFalse(almost_divisible(1776.0_real64, 1776.1_real64)) @assertFalse(almost_divisible(1776.0_real64, 1776.01_real64)) @@ -665,7 +653,6 @@ contains subroutine test_almost_equal_by_properties_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: almost_equal - use funit real(real32) :: a, b @@ -775,7 +762,6 @@ contains subroutine test_almost_equal_by_properties_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: almost_equal - use funit real(real64) :: a, b @@ -885,7 +871,6 @@ contains subroutine test_almost_equal_by_optional_tolerance_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: almost_equal - use funit @assertTrue(almost_equal(0.9_real32, 1.0_real32, absolute_tolerance=0.11_real32)) @assertFalse(almost_equal(0.9_real32, 1.0_real32, absolute_tolerance=0.09_real32)) @@ -904,7 +889,6 @@ contains subroutine test_almost_equal_by_optional_tolerance_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: almost_equal - use funit @assertTrue(almost_equal(0.9_real64, 1.0_real64, absolute_tolerance=0.11_real64)) @assertFalse(almost_equal(0.9_real64, 1.0_real64, absolute_tolerance=0.09_real64)) @@ -926,7 +910,6 @@ contains ieee_value use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: almost_equal - use funit real(real32) :: a, b @@ -984,7 +967,6 @@ contains ieee_value use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: almost_equal - use funit real(real64) :: a, b @@ -1039,7 +1021,6 @@ contains subroutine test_clamp_by_properties_int32() use, intrinsic :: iso_fortran_env, only: int32 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3_int32, clamp(-5_int32, -3_int32, 3_int32)) @assertEqual(-3_int32, clamp(-4_int32, -3_int32, 3_int32)) @@ -1071,7 +1052,6 @@ contains subroutine test_clamp_by_properties_int64() use, intrinsic :: iso_fortran_env, only: int64 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3_int64, clamp(-5_int64, -3_int64, 3_int64)) @assertEqual(-3_int64, clamp(-4_int64, -3_int64, 3_int64)) @@ -1103,7 +1083,6 @@ contains subroutine test_clamp_by_properties_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3.0_real32, clamp(-5.0_real32, -3.0_real32, 3.0_real32)) @assertEqual(-3.0_real32, clamp(-4.0_real32, -3.0_real32, 3.0_real32)) @@ -1135,7 +1114,6 @@ contains subroutine test_clamp_by_properties_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3.0_real64, clamp(-5.0_real64, -3.0_real64, 3.0_real64)) @assertEqual(-3.0_real64, clamp(-4.0_real64, -3.0_real64, 3.0_real64)) @@ -1167,7 +1145,6 @@ contains subroutine test_clamp_by_extreme_values_int32() use, intrinsic :: iso_fortran_env, only: int32 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3_int32, clamp(-huge(0_int32), -3_int32, 3_int32)) @assertEqual(3_int32, clamp(huge(0_int32), -3_int32, 3_int32)) @@ -1181,7 +1158,6 @@ contains subroutine test_clamp_by_extreme_values_int64() use, intrinsic :: iso_fortran_env, only: int64 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3_int64, clamp(-huge(0_int64), -3_int64, 3_int64)) @assertEqual(3_int64, clamp(huge(0_int64), -3_int64, 3_int64)) @@ -1198,7 +1174,6 @@ contains ieee_value use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3.0_real32, clamp(-huge(0.0_real32), -3.0_real32, 3.0_real32)) @assertEqual(3.0_real32, clamp(huge(0.0_real32), -3.0_real32, 3.0_real32)) @@ -1224,7 +1199,6 @@ contains ieee_value use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: clamp - use funit @assertEqual(-3.0_real64, clamp(-huge(0.0_real64), -3.0_real64, 3.0_real64)) @assertEqual(3.0_real64, clamp(huge(0.0_real64), -3.0_real64, 3.0_real64)) @@ -1247,7 +1221,6 @@ contains subroutine test_index_unique_by_empty_arrays() use, intrinsic :: iso_fortran_env, only: int32, int64, real32, real64 use dyn_mpas_procedures, only: index_unique - use funit character(128), allocatable :: test_data_carr(:) integer(int32), allocatable :: test_data_i32arr(:) @@ -1293,7 +1266,6 @@ contains @test subroutine test_index_unique_by_character_arrays() use dyn_mpas_procedures, only: index_unique - use funit character(*), parameter :: test_data_letters(*) = [character(1) :: & 'T', 'H', 'E', & @@ -1336,7 +1308,6 @@ contains subroutine test_index_unique_by_integer_arrays_int32() use, intrinsic :: iso_fortran_env, only: int32 use dyn_mpas_procedures, only: index_unique - use funit integer(int32), parameter :: test_data(*) = [ & 1_int32, 7_int32, 7_int32, 6_int32, 0_int32, 7_int32, 0_int32, 4_int32 & @@ -1364,7 +1335,6 @@ contains subroutine test_index_unique_by_integer_arrays_int64() use, intrinsic :: iso_fortran_env, only: int64 use dyn_mpas_procedures, only: index_unique - use funit integer(int64), parameter :: test_data(*) = [ & 1_int64, 7_int64, 7_int64, 6_int64, 0_int64, 7_int64, 0_int64, 4_int64 & @@ -1391,7 +1361,6 @@ contains @test subroutine test_index_unique_by_logical_arrays() use dyn_mpas_procedures, only: index_unique - use funit logical, parameter :: test_data(*) = [ & .false., .false., .true., .false., .false., .true. & @@ -1413,7 +1382,6 @@ contains subroutine test_index_unique_by_real_arrays_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_mpas_procedures, only: index_unique - use funit real(real32), parameter :: test_data(*) = [ & 1.0_real32, 7.0_real32, 7.0_real32, 6.0_real32, 0.0_real32, 7.0_real32, 0.0_real32, 4.0_real32 & @@ -1441,7 +1409,6 @@ contains subroutine test_index_unique_by_real_arrays_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_mpas_procedures, only: index_unique - use funit real(real64), parameter :: test_data(*) = [ & 1.0_real64, 7.0_real64, 7.0_real64, 6.0_real64, 0.0_real64, 7.0_real64, 0.0_real64, 4.0_real64 & @@ -1468,7 +1435,6 @@ contains @test subroutine test_split_by_empty_string_set() use dyn_mpas_procedures, only: split - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1504,7 +1470,6 @@ contains @test subroutine test_split_by_forward_searches() use dyn_mpas_procedures, only: split - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1539,7 +1504,6 @@ contains @test subroutine test_split_by_backward_searches() use dyn_mpas_procedures, only: split - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1574,7 +1538,6 @@ contains @test subroutine test_split_by_out_of_bounds_searches() use dyn_mpas_procedures, only: split - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1622,7 +1585,6 @@ contains @test subroutine test_tokenize_into_first_last_by_empty_string_set() use dyn_mpas_procedures, only: tokenize - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1654,7 +1616,6 @@ contains @test subroutine test_tokenize_into_first_last_by_known_string_set() use dyn_mpas_procedures, only: tokenize - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1689,7 +1650,6 @@ contains @test subroutine test_tokenize_into_tokens_separator_by_empty_string_set() use dyn_mpas_procedures, only: tokenize - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' @@ -1745,7 +1705,6 @@ contains @test subroutine test_tokenize_into_tokens_separator_by_known_string_set() use dyn_mpas_procedures, only: tokenize - use funit character(*), parameter :: test_string_comma_separated = & ',,,Mercury,,Venus,Earth,,Mars,,,Jupiter,,Saturn,Uranus,,Neptune,,,' diff --git a/src/dynamics/mpas/tests/unit/test_dyn_procedures.pf b/src/dynamics/mpas/tests/unit/test_dyn_procedures.pf index 19b266f2d..5dd6047fa 100644 --- a/src/dynamics/mpas/tests/unit/test_dyn_procedures.pf +++ b/src/dynamics/mpas/tests/unit/test_dyn_procedures.pf @@ -8,6 +8,8 @@ !> units in the last place (ULP). Otherwise, tolerance should be chosen based on significant figures. !> For utility procedures, standard unit testing practices apply. module test_dyn_procedures + use funit + implicit none private @@ -132,7 +134,6 @@ contains use dyn_procedures, only: p_by_equation_of_state, & rho_by_equation_of_state, & t_by_equation_of_state - use funit real(real64), parameter :: constant_rd = 287.04_real64 @@ -173,7 +174,6 @@ contains use dyn_procedures, only: p_by_equation_of_state, & rho_by_equation_of_state, & t_by_equation_of_state - use funit real(real64), parameter :: constant_rd = 287.04_real64 @@ -245,7 +245,6 @@ contains subroutine test_exner_function_family_by_known_values() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: exner_function - use funit real(real64), parameter :: constant_cpd = 1004.64_real64 real(real64), parameter :: constant_p0 = 100000.0_real64 @@ -297,7 +296,6 @@ contains subroutine test_exner_function_family_by_typical_values() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: exner_function - use funit real(real64), parameter :: constant_cpd = 1004.64_real64 real(real64), parameter :: constant_p0 = 100000.0_real64 @@ -361,7 +359,6 @@ contains subroutine test_hydrostatic_equation_family_by_known_values() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: dp_by_hydrostatic_equation - use funit real(real64), parameter :: constant_g = 9.80665_real64 @@ -400,7 +397,6 @@ contains subroutine test_hydrostatic_equation_family_by_typical_values() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: dp_by_hydrostatic_equation - use funit real(real64), parameter :: constant_g = 9.80665_real64 @@ -471,7 +467,6 @@ contains subroutine test_hypsometric_equation_family_by_known_values() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: p_by_hypsometric_equation - use funit real(real64), parameter :: constant_g = 9.80665_real64 real(real64), parameter :: constant_rd = 287.04_real64 @@ -520,7 +515,6 @@ contains subroutine test_hypsometric_equation_family_by_typical_values() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: p_by_hypsometric_equation - use funit real(real64), parameter :: constant_g = 9.80665_real64 real(real64), parameter :: constant_rd = 287.04_real64 @@ -604,7 +598,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: t_by_poisson_equation, & theta_by_poisson_equation - use funit real(real64), parameter :: constant_cpd = 1004.64_real64 real(real64), parameter :: constant_p0 = 100000.0_real64 @@ -658,7 +651,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: t_by_poisson_equation, & theta_by_poisson_equation - use funit real(real64), parameter :: constant_cpd = 1004.64_real64 real(real64), parameter :: constant_p0 = 100000.0_real64 @@ -735,7 +727,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: omega_of_w_rho, & w_of_omega_rho - use funit real(real64), parameter :: constant_g = 9.80665_real64 @@ -783,7 +774,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: omega_of_w_rho, & w_of_omega_rho - use funit real(real64), parameter :: constant_g = 9.80665_real64 @@ -863,7 +853,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: qv_of_sh, & sh_of_qv - use funit ! Significant figures and relative tolerance to pass the test. integer, parameter :: significant_figures = 12 @@ -908,7 +897,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: qv_of_sh, & sh_of_qv - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 2 @@ -958,7 +946,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: t_of_theta_rhod_qv, & theta_of_t_rhod_qv - use funit real(real64), parameter :: constant_cpd = 1004.64_real64 real(real64), parameter :: constant_p0 = 100000.0_real64 @@ -1014,7 +1001,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: t_of_theta_rhod_qv, & theta_of_t_rhod_qv - use funit real(real64), parameter :: constant_cpd = 1004.64_real64 real(real64), parameter :: constant_p0 = 100000.0_real64 @@ -1110,7 +1096,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: t_of_tm_qv, & tm_of_t_qv - use funit real(real64), parameter :: constant_rd = 287.04_real64 real(real64), parameter :: constant_rv = 461.52_real64 @@ -1163,7 +1148,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: t_of_tm_qv, & tm_of_t_qv - use funit real(real64), parameter :: constant_rd = 287.04_real64 real(real64), parameter :: constant_rv = 461.52_real64 @@ -1237,7 +1221,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: tm_of_tv_qv, & tv_of_tm_qv - use funit ! Significant figures and relative tolerance to pass the test. integer, parameter :: significant_figures = 12 @@ -1287,7 +1270,6 @@ contains use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: tm_of_tv_qv, & tv_of_tm_qv - use funit ! Tolerance, in the number of units in the last place (ULP), to pass the test. integer, parameter :: ulp_tolerance = 2 @@ -1354,7 +1336,6 @@ contains subroutine test_reverse_by_empty_arrays_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_procedures, only: reverse - use funit real(real32), allocatable :: array(:), reversed(:) @@ -1370,7 +1351,6 @@ contains subroutine test_reverse_by_empty_arrays_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: reverse - use funit real(real64), allocatable :: array(:), reversed(:) @@ -1386,7 +1366,6 @@ contains subroutine test_reverse_by_single_element_arrays_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_procedures, only: reverse - use funit real(real32), parameter :: expected(*) = [ & 1.0_real32 & @@ -1407,7 +1386,6 @@ contains subroutine test_reverse_by_single_element_arrays_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: reverse - use funit real(real64), parameter :: expected(*) = [ & 1.0_real64 & @@ -1428,7 +1406,6 @@ contains subroutine test_reverse_by_multiple_element_arrays_real32() use, intrinsic :: iso_fortran_env, only: real32 use dyn_procedures, only: reverse - use funit real(real32), parameter :: expected(*) = [ & 5.0_real32, & @@ -1457,7 +1434,6 @@ contains subroutine test_reverse_by_multiple_element_arrays_real64() use, intrinsic :: iso_fortran_env, only: real64 use dyn_procedures, only: reverse - use funit real(real64), parameter :: expected(*) = [ & 5.0_real64, & @@ -1486,7 +1462,6 @@ contains subroutine test_sec_to_hour_min_sec_by_positive_time() use, intrinsic :: iso_fortran_env, only: int32 use dyn_procedures, only: sec_to_hour_min_sec - use funit integer(int32) :: sec integer(int32) :: hour_min_sec(3) @@ -1566,7 +1541,6 @@ contains subroutine test_sec_to_hour_min_sec_by_negative_time() use, intrinsic :: iso_fortran_env, only: int32 use dyn_procedures, only: sec_to_hour_min_sec - use funit integer(int32) :: sec integer(int32) :: hour_min_sec(3) @@ -1646,7 +1620,6 @@ contains subroutine test_sec_to_hour_min_sec_by_extreme_time() use, intrinsic :: iso_fortran_env, only: int32 use dyn_procedures, only: sec_to_hour_min_sec - use funit integer(int32) :: sec integer(int32) :: hour_min_sec(3) From a158f0004c97d7645f9202b8ebf296c94c0b4ced Mon Sep 17 00:00:00 2001 From: Kuan-Chih Wang Date: Fri, 10 Apr 2026 15:17:18 -0600 Subject: [PATCH 2/5] Migrate lightweight CI jobs to `ubuntu-slim` Some CI jobs are very light on computing resources. Migrate those to the newly available `ubuntu-slim` runner (1 vCPU). As a result, queue time should be improved. --- .github/workflows/mpas_dynamical_core_ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mpas_dynamical_core_ci.yml b/.github/workflows/mpas_dynamical_core_ci.yml index 90c3d9aa3..c4406f197 100644 --- a/.github/workflows/mpas_dynamical_core_ci.yml +++ b/.github/workflows/mpas_dynamical_core_ci.yml @@ -28,7 +28,7 @@ jobs: conditional-check: name: Check if jobs should run timeout-minutes: 1 - runs-on: ubuntu-24.04 + runs-on: ubuntu-slim outputs: should-run: ${{ steps.conditional.outputs.result }} steps: @@ -128,7 +128,7 @@ jobs: overall-status: name: Overall status timeout-minutes: 1 - runs-on: ubuntu-24.04 + runs-on: ubuntu-slim needs: - conditional-check - source-code-linting @@ -196,7 +196,7 @@ jobs: source-code-linting: name: Lint Fortran source code timeout-minutes: 10 - runs-on: ubuntu-24.04 + runs-on: ubuntu-slim needs: conditional-check if: ${{ needs.conditional-check.outputs.should-run == 'true' }} env: From 433b697690d7b16f64ddeb0373529dcab0c96fc3 Mon Sep 17 00:00:00 2001 From: Kuan-Chih Wang Date: Fri, 10 Apr 2026 15:38:36 -0600 Subject: [PATCH 3/5] Update GitHub actions to latest versions Due to the deprecation of Node.js 20 actions, update GitHub actions to the latest versions that use Node.js 24. The deadline is September 16th, 2026. --- .github/workflows/mpas_dynamical_core_ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/mpas_dynamical_core_ci.yml b/.github/workflows/mpas_dynamical_core_ci.yml index c4406f197..fe1564175 100644 --- a/.github/workflows/mpas_dynamical_core_ci.yml +++ b/.github/workflows/mpas_dynamical_core_ci.yml @@ -33,7 +33,7 @@ jobs: should-run: ${{ steps.conditional.outputs.result }} steps: - name: Checkout CAM-SIMA - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Check if there are changes to MPAS dynamical core id: conditional @@ -204,7 +204,7 @@ jobs: SOURCE_CODE_PATH: ${{ github.workspace }}/src/dynamics/mpas steps: - name: Checkout CAM-SIMA - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Python uses: actions/setup-python@v6 @@ -226,7 +226,7 @@ jobs: - name: Upload Fortran source code linting log if: ${{ always() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: if-no-files-found: ignore name: source-code-linting-log @@ -256,12 +256,12 @@ jobs: UNIT_TESTS_PATH: ${{ github.workspace }}/src/dynamics/mpas steps: - name: Checkout CAM-SIMA - uses: actions/checkout@v5 + uses: actions/checkout@v6 # pFUnit takes a while to build. Cache it if possible to save time on consecutive workflow runs. - name: Cache pFUnit id: cache-pfunit - uses: actions/cache@v4 + uses: actions/cache@v5 with: key: cache-pfunit-${{ env.PFUNIT_REFERENCE }}-gcc-v${{ matrix.gcc-version }}-mpas path: ${{ env.PFUNIT_PATH }}/install @@ -269,7 +269,7 @@ jobs: # If there is a cache hit, just use the cached pFUnit and skip this step. - name: Checkout pFUnit if: ${{ steps.cache-pfunit.outputs.cache-hit != 'true' }} - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: repository: Goddard-Fortran-Ecosystem/pFUnit ref: ${{ env.PFUNIT_REFERENCE }} @@ -294,7 +294,7 @@ jobs: - name: Upload unit tests log if: ${{ always() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: if-no-files-found: ignore name: unit-tests-log-gcc-v${{ matrix.gcc-version }} From 64d0cf3ddb765220ede210ee9d3d42ef6b18c93f Mon Sep 17 00:00:00 2001 From: Kuan-Chih Wang Date: Fri, 10 Apr 2026 16:22:20 -0600 Subject: [PATCH 4/5] Remove unnecessary quotes --- .github/workflows/mpas_dynamical_core_ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mpas_dynamical_core_ci.yml b/.github/workflows/mpas_dynamical_core_ci.yml index fe1564175..0451899bf 100644 --- a/.github/workflows/mpas_dynamical_core_ci.yml +++ b/.github/workflows/mpas_dynamical_core_ci.yml @@ -11,7 +11,7 @@ on: - synchronize push: branches: - - 'staging/**' + - staging/** - development workflow_dispatch: @@ -200,7 +200,7 @@ jobs: needs: conditional-check if: ${{ needs.conditional-check.outputs.should-run == 'true' }} env: - FORTITUDE_VERSION: '0.7.*' + FORTITUDE_VERSION: 0.7.* SOURCE_CODE_PATH: ${{ github.workspace }}/src/dynamics/mpas steps: - name: Checkout CAM-SIMA @@ -210,7 +210,7 @@ jobs: uses: actions/setup-python@v6 with: cache: pip - python-version: '3.12' + python-version: 3.12 - name: Install Fortitude run: | From 54ef1f583e46b80d5e57dbc15230ebbb615a6e2b Mon Sep 17 00:00:00 2001 From: Kuan-Chih Wang Date: Fri, 10 Apr 2026 17:21:26 -0600 Subject: [PATCH 5/5] Containerize unit testing CI jobs in MPAS dynamical core --- .github/workflows/mpas_dynamical_core_ci.yml | 58 +++++++------------- 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/.github/workflows/mpas_dynamical_core_ci.yml b/.github/workflows/mpas_dynamical_core_ci.yml index 0451899bf..98e6b5df5 100644 --- a/.github/workflows/mpas_dynamical_core_ci.yml +++ b/.github/workflows/mpas_dynamical_core_ci.yml @@ -233,63 +233,45 @@ jobs: path: ${{ env.SOURCE_CODE_PATH }}/source-code-linting.log retention-days: 7 unit-tests: - name: Build and run unit tests (GCC ${{ matrix.gcc-version }}) + name: Build and run unit tests (${{ matrix.compiler }}) timeout-minutes: 10 strategy: fail-fast: false matrix: - gcc-version: - - '12' - - '13' - - '14' + compiler: + - gnu-11 + - gnu-12 + - gnu-13 + - gnu-14 + - gnu-15 + - intel-2024 + - intel-2025 + # The unit tests in MPAS dynamical core currently do not involve any MPI functionalities. + # Testing with a single MPI implementation is sufficient for now. + mpi: + - open-mpi-5 runs-on: ubuntu-24.04 + container: + image: ghcr.io/kuanchihwang/atm-sci-container:2026-04-12_${{ matrix.compiler }}_${{ matrix.mpi }} needs: conditional-check if: ${{ needs.conditional-check.outputs.should-run == 'true' }} env: - CC: gcc-${{ matrix.gcc-version }} - CXX: g++-${{ matrix.gcc-version }} - FC: gfortran-${{ matrix.gcc-version }} - PFUNIT_BUILD_TYPE: Release - PFUNIT_PATH: ${{ github.workspace }}/pFUnit - PFUNIT_REFERENCE: 'v4.13.0' + CONTAINER_ENVIRONMENT: pfunit UNIT_TESTS_BUILD_TYPE: Debug UNIT_TESTS_PATH: ${{ github.workspace }}/src/dynamics/mpas steps: - name: Checkout CAM-SIMA uses: actions/checkout@v6 - # pFUnit takes a while to build. Cache it if possible to save time on consecutive workflow runs. - - name: Cache pFUnit - id: cache-pfunit - uses: actions/cache@v5 - with: - key: cache-pfunit-${{ env.PFUNIT_REFERENCE }}-gcc-v${{ matrix.gcc-version }}-mpas - path: ${{ env.PFUNIT_PATH }}/install - - # If there is a cache hit, just use the cached pFUnit and skip this step. - - name: Checkout pFUnit - if: ${{ steps.cache-pfunit.outputs.cache-hit != 'true' }} - uses: actions/checkout@v6 - with: - repository: Goddard-Fortran-Ecosystem/pFUnit - ref: ${{ env.PFUNIT_REFERENCE }} - path: pFUnit - - # If there is a cache hit, just use the cached pFUnit and skip this step. - - name: Build pFUnit - if: ${{ steps.cache-pfunit.outputs.cache-hit != 'true' }} - run: | - cmake -D CMAKE_BUILD_TYPE="$PFUNIT_BUILD_TYPE" -D CMAKE_INSTALL_PREFIX="$PFUNIT_PATH/install" -B "$PFUNIT_PATH/build" -S "$PFUNIT_PATH" - cmake --build "$PFUNIT_PATH/build" --config "$PFUNIT_BUILD_TYPE" - cmake --install "$PFUNIT_PATH/build" --config "$PFUNIT_BUILD_TYPE" --prefix "$PFUNIT_PATH/install" - - name: Build unit tests run: | - cmake -D CMAKE_BUILD_TYPE="$UNIT_TESTS_BUILD_TYPE" -D CMAKE_PREFIX_PATH="$PFUNIT_PATH/install" -B "$UNIT_TESTS_PATH/build" -S "$UNIT_TESTS_PATH" + source "$(command -v container-entrypoint-hook.sh)" + cmake -D CMAKE_BUILD_TYPE="$UNIT_TESTS_BUILD_TYPE" -B "$UNIT_TESTS_PATH/build" -S "$UNIT_TESTS_PATH" cmake --build "$UNIT_TESTS_PATH/build" --config "$UNIT_TESTS_BUILD_TYPE" - name: Run unit tests run: | + source "$(command -v container-entrypoint-hook.sh)" ctest --build-config "$UNIT_TESTS_BUILD_TYPE" --output-log "$UNIT_TESTS_PATH/build/unit-tests.log" --output-on-failure --test-dir "$UNIT_TESTS_PATH/build" --verbose - name: Upload unit tests log @@ -297,6 +279,6 @@ jobs: uses: actions/upload-artifact@v7 with: if-no-files-found: ignore - name: unit-tests-log-gcc-v${{ matrix.gcc-version }} + name: unit-tests-log-${{ matrix.compiler }} path: ${{ env.UNIT_TESTS_PATH }}/build/unit-tests.log retention-days: 7