diff --git a/.github/workflows/github_autotools_gnu.yml b/.github/workflows/github_autotools_gnu.yml index a086ccfc20..b17dd4be6f 100644 --- a/.github/workflows/github_autotools_gnu.yml +++ b/.github/workflows/github_autotools_gnu.yml @@ -1,6 +1,4 @@ -# 'main' required ci, does a distcheck (builds, tests, check install) -# image created off dockerfile in repo, compile/link flags are set there -name: Build libFMS test with autotools +name: Autotools build and unit testing with GCC on: [push, pull_request] @@ -14,31 +12,38 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - conf-flag: [ --disable-openmp, --disable-setting-flags, --with-mpi=no, --disable-r8-default] + conf-flag: [ --disable-openmp, --with-mpi=no, --disable-r8-default] input-flag: [--with-yaml, --enable-test-input=/home/unit_tests_input] exclude: - conf-flag: --with-mpi=no input-flag: --enable-test-input=/home/unit_tests_input container: - image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:13.2.0 + image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:15.1.0 env: - TEST_VERBOSE: 1 - DISTCHECK_CONFIGURE_FLAGS: "${{ matrix.conf-flag }} ${{ matrix.input-flag }} ${{ matrix.io-flag }}" + DISTCHECK_CONFIGURE_FLAGS: "${{ matrix.conf-flag }} ${{ matrix.input-flag }}" DEBUG_FLAGS: "-O0 -g -fbounds-check -ffpe-trap=invalid,zero,overflow" # debug compiler flags taken from the mkmf template + # diag manager openmp + logical mask tests fail with gcc, these are reproducible outside the CI + # test_mpp_clock_begin_end_id is an expected fail that is passing, only happens in the CI + # test_time_interp2 tests fail from file issues, only happens in the CI + SKIP_TESTS: "test_time_none.10 test_time_sum.10 test_time_avg.10 test_time_min.10 test_time_max.10 test_time_pow.10 test_time_rms.10 test_mpp_clock_begin_end_id.10 test_time_interp2.7 test_time_interp2.8" steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v6.0.1 - name: Prepare GNU autoconf for build run: autoreconf -if - name: Configure the build - if: ${{ matrix.conf-flag != '--disable-setting-flags' }} - run: ./configure ${DISTCHECK_CONFIGURE_FLAGS} FCFLAGS="$FCFLAGS $DEBUG_FLAGS" - - name: Configure the build with compiler flags - if: ${{ matrix.conf-flag == '--disable-setting-flags' }} - run: ./configure ${DISTCHECK_CONFIGURE_FLAGS} FCFLAGS="-fdefault-real-8 -fdefault-double-8 -fcray-pointer -ffree-line-length-none -I/usr/include $FCFLAGS $DEBUG_FLAGS" || cat config.log - - name: Build the library - run: make distcheck + run: ./configure ${DISTCHECK_CONFIGURE_FLAGS} FCFLAGS="$FCFLAGS $DEBUG_FLAGS" || cat config.log + - name: Run distcheck (compiles, tests, and packages) + run: make distcheck 2>&1 > distcheck.log if: ${{ matrix.conf-flag != '--with-mpi=no' }} + - name: Output errors on failure + run: grep -E "^FAIL:|^XPASS:" distcheck.log + if: failure() + - name: Upload log on failure + uses: actions/upload-artifact@v7.0.0 + if: failure() + with: + path: distcheck.log - name: Build the library (without test suite for serial build) run: make if: ${{ matrix.conf-flag == '--with-mpi=no' }} diff --git a/.github/workflows/github_autotools_intel_classic.yml b/.github/workflows/github_autotools_intel_classic.yml index 5dcf5b91f3..f0faaf9b1f 100644 --- a/.github/workflows/github_autotools_intel_classic.yml +++ b/.github/workflows/github_autotools_intel_classic.yml @@ -1,8 +1,9 @@ +name: Autotools build and unit testing with Intel Classic (weekly) + on: schedule: - cron: '0 0 * * 0' # sundays @ midnight - # cancel running jobs if theres a newer push concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/github_autotools_intel_oneapi.yml b/.github/workflows/github_autotools_intel_oneapi.yml index 386f75f2d6..4f1e33f130 100644 --- a/.github/workflows/github_autotools_intel_oneapi.yml +++ b/.github/workflows/github_autotools_intel_oneapi.yml @@ -1,3 +1,5 @@ +name: Autotools build and unit testing with Intel Oneapi + on: pull_request # cancel running jobs if theres a newer push diff --git a/.github/workflows/github_cmake_gnu.yml b/.github/workflows/github_cmake_gnu.yml index 6b2760a21f..4487818584 100644 --- a/.github/workflows/github_cmake_gnu.yml +++ b/.github/workflows/github_cmake_gnu.yml @@ -1,4 +1,4 @@ -name: Build libFMS with cmake +name: CMake build and unit testing with GCC on: [push, pull_request] @@ -15,19 +15,19 @@ jobs: libyaml-flag: [ "", -DWITH_YAML=on ] build-type: [ "-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_BUILD_TYPE=Debug" ] container: - image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:13.2.0 + image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:15.1.0 env: CMAKE_FLAGS: "${{ matrix.build-type }} ${{ matrix.libyaml-flag }}" - EXCLUDE_TESTS: "test_mpp_nesting|test_bc_restart|test_collective_io|test_fms2_io|test_io_with_mask" + EXCLUDE_TESTS: "test_mpp_nesting|test_mpp_clock_begin_end_id|test_time_*" PKG_CONFIG_PATH: "/opt/views/view/lib64/pkgconfig:/opt/views/view/lib/pkgconfig:/opt/views/view/share/pkgconfig" steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v6.0.1 - name: Generate makefiles with CMake run: | mkdir build cd build - cmake $CMAKE_FLAGS -DOPENMP=on -DUNIT_TESTS=on -DNetCDF_ROOT=/opt/view -DLIBYAML_ROOT=/opt/view .. + cmake -DOVERSUBSCRIBE_FLAG="--map-by :OVERSUBSCRIBE" $CMAKE_FLAGS -DOPENMP=on -DNetCDF_ROOT=/opt/view -DLIBYAML_ROOT=/opt/view -DUNIT_TESTS=on .. - name: Build the library run: make -C build - name: Run the unit tests @@ -40,10 +40,10 @@ jobs: libyaml-flag: [ "", -DWITH_YAML=on ] build-type: [ "-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_BUILD_TYPE=Debug" ] container: - image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:13.2.0-arm + image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:13.2.0-arm-cmake-update env: CMAKE_FLAGS: "${{ matrix.build-type }} ${{ matrix.libyaml-flag }}" - EXCLUDE_TESTS: "test_mpp_nesting|test_bc_restart|test_collective_io|test_fms2_io|test_io_with_mask|test_sat_vapor_pres" + EXCLUDE_TESTS: "test_mpp_nesting|test_sat_vapor_pres|test_mpp_clock_begin_end_id" PKG_CONFIG_PATH: "/opt/views/view/lib64/pkgconfig:/opt/views/view/lib/pkgconfig:/opt/views/view/share/pkgconfig" steps: - name: Checkout code @@ -52,7 +52,7 @@ jobs: run: | mkdir build cd build - cmake $CMAKE_FLAGS -DOPENMP=on -DUNIT_TESTS=on -DNetCDF_ROOT=/opt/view -DLIBYAML_ROOT=/opt/view .. + cmake $CMAKE_FLAGS -DOVERSUBSCRIBE_FLAG="" -DOPENMP=on -DUNIT_TESTS=on -DNetCDF_ROOT=/opt/view -DLIBYAML_ROOT=/opt/view .. - name: Build the library run: make -C build - name: Run the unit tests diff --git a/.github/workflows/github_coupler_gnu.yml b/.github/workflows/github_coupler_gnu.yml index 4236e43eaf..daf5139a54 100644 --- a/.github/workflows/github_coupler_gnu.yml +++ b/.github/workflows/github_coupler_gnu.yml @@ -1,4 +1,4 @@ -name: Test coupler build +name: FMScoupler null model build with GCC on: [pull_request] # cancel running jobs if theres a newer push @@ -10,7 +10,7 @@ jobs: coupler-build: runs-on: ubuntu-latest container: - image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:13.2.0 + image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:15.1.0 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} diff --git a/.github/workflows/github_linter.yml b/.github/workflows/github_linter.yml index 24fa8969c8..d745250aa3 100644 --- a/.github/workflows/github_linter.yml +++ b/.github/workflows/github_linter.yml @@ -1,4 +1,4 @@ -name: libFMS lint tests +name: Line length and whitespace linter on: [push, pull_request] diff --git a/.github/workflows/github_mom_gnu.yml b/.github/workflows/github_mom_gnu.yml index 7ee5c71449..b534d82fcc 100644 --- a/.github/workflows/github_mom_gnu.yml +++ b/.github/workflows/github_mom_gnu.yml @@ -1,4 +1,4 @@ -name: Run MOM6 test suite +name: MOM6 test suite with GCC # runs on PR's or when manually triggered on: [workflow_dispatch, pull_request] @@ -11,17 +11,14 @@ concurrency: jobs: build: runs-on: ubuntu-latest - container: - image: ghcr.io/noaa-gfdl/fms/fms-ci-rocky-gnu:13.2.0 - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} steps: - name: Checkout MOM6 repository uses: actions/checkout@v4.2.2 with: repository: 'NOAA-GFDL/MOM6' submodules: recursive + - name: Install dependency packages + uses: ./.github/actions/ubuntu-setup/ - name: Checkout FMS into MOM build uses: actions/checkout@v4.2.2 with: diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index 1b16cf5ed4..0edadd338a 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -1,5 +1,5 @@ -# appends -dev to the version upon release and opens pr # CI won't run on generated PR, easiest workaround is to close + reopen +name: Append version number and create PR on: release: types: [published] diff --git a/CMakeLists.txt b/CMakeLists.txt index f3d605a810..3df306a128 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,9 @@ option(PORTABLE_KINDS "Enable compiler definition -DPORTABLE_KINDS" option(GFS_PHYS "Enable compiler definition -DGFS_PHYS" OFF) option(WITH_YAML "Enable compiler definition -Duse_yaml" OFF) +# Testing-specific options +set(OVERSUBSCRIBE_FLAG " --oversubscribe " CACHE STRING "Flag for mpirun to use more cores than available") + if(32BIT) list(APPEND kinds "r4") message(STATUS "Building library with 4-byte real defaults (with mixed precision real support for most modules).") @@ -586,6 +589,9 @@ include(CTest) set(MPI_LAUNCHER "mpirun") # used in the test-lib.sh.in to make it behave differently when parsed by cmake set(USING_CMAKE "true") +set(OVERSUBSCRIBE "${OVERSUBSCRIBE_FLAG}") +message(STATUS "Using '${OVERSUBSCRIBE}' flag to oversubscribe ranks in test scripts") + # set the fms library to link tests with based on whats built if(NOT kinds) set(fmsLibraryName FMS::fms) diff --git a/configure.ac b/configure.ac index b405cfa5d4..1aaf5c8f9b 100644 --- a/configure.ac +++ b/configure.ac @@ -392,9 +392,12 @@ fi AC_CHECK_PROGS([MPI_LAUNCHER],[srun aprun mpirun]) # Check if the launcher can oversubscribe the MPI processes -AS_IF([$MPI_LAUNCHER --oversubscribe hostname >/dev/null 2>&1], \ +AS_IF([$MPI_LAUNCHER --oversubscribe nproc >/dev/null 2>&1], \ [ AC_SUBST([OVERSUBSCRIBE], [--oversubscribe])]) +# newer openmpi versions take a different flag +AS_IF([$MPI_LAUNCHER --map-by :OVERSUBSCRIBE nproc >/dev/null 2>&1], \ + [ AC_SUBST([OVERSUBSCRIBE], [--map-by :OVERSUBSCRIBE])]) # Compiler with version information. This consists of the full path # name of the compiler and the reported version number. diff --git a/test_fms/column_diagnostics/test_column_diagnostics.F90 b/test_fms/column_diagnostics/test_column_diagnostics.F90 index 0dac6cc7bd..d71c91d308 100644 --- a/test_fms/column_diagnostics/test_column_diagnostics.F90 +++ b/test_fms/column_diagnostics/test_column_diagnostics.F90 @@ -25,7 +25,7 @@ program test_column_diagnostics use column_diagnostics_mod - use fms_mod, only: fms_init + use fms_mod, only: fms_init, fms_end use mpp_mod, only: FATAL, mpp_error use time_manager_mod, only: time_manager_init, time_type, set_time, set_calendar_type use constants_mod, only : PI, DEG_TO_RAD @@ -62,6 +62,7 @@ program test_column_diagnostics call initialize_variables(0.01_lkind) !< set up input arrays; call test_initialize_diagnostic_columns !< initialize diagnostics column call test_column_diagnostics_header + call fms_end() contains !------------------------------------------! diff --git a/test_fms/interpolator/test_interpolator2.F90 b/test_fms/interpolator/test_interpolator2.F90 index 8170a6fa68..1cf450dd1b 100644 --- a/test_fms/interpolator/test_interpolator2.F90 +++ b/test_fms/interpolator/test_interpolator2.F90 @@ -36,7 +36,7 @@ program test_interpolator2 set_date_no_leap, set_date_julian, operator(/), & operator(+), operator(-), time_type_to_real, increment_time, & leap_year, days_in_month, print_date, print_time - use fms_mod, only: fms_init + use fms_mod, only: fms_init, fms_end use constants_mod, only: PI use platform_mod, only: r4_kind, r8_kind use fms_test_mod, only: permutable_indices_2d, permutable_indices_3d, permutable_indices_4d, factorial, & @@ -124,6 +124,8 @@ program test_interpolator2 call test_interpolator_end(o3) end if + call fms_end() + contains #include "test_interpolator_write_climatology.inc" diff --git a/test_fms/interpolator/test_interpolator2.sh b/test_fms/interpolator/test_interpolator2.sh index bd4cf7aab6..b43fd605c7 100755 --- a/test_fms/interpolator/test_interpolator2.sh +++ b/test_fms/interpolator/test_interpolator2.sh @@ -41,7 +41,7 @@ if test ! -z "$test_input_path" ; then rm -rf INPUT && mkdir INPUT cp $test_input_path/interpolator/INPUT/* INPUT else - SKIP_TESTS="$SKIP_TESTS $(basename $0 .sh).1" + SKIP_TESTS="$SKIP_TESTS test_interpolator2.1" fi # Create files for test. diff --git a/test_fms/test-lib.sh.in b/test_fms/test-lib.sh.in index 5f92ad7639..e5451dd2d2 100644 --- a/test_fms/test-lib.sh.in +++ b/test_fms/test-lib.sh.in @@ -32,14 +32,9 @@ TEST_NAME="$(basename "$0" .sh)" TEST_NUMBER="${TEST_NAME%%-*}" TEST_NUMBER="${TEST_NUMBER#t}" -exec 7>&2 -# For now, write all output -#if test -n "$VERBOSE" -#then - exec 4>&2 3>&1 -#else -# exec 4>/dev/null 3>/dev/null -#fi +# redirects for stdout/stderr +# used to control output from this script and each test +exec 4>&2 3>&1 7>&2 test_count=0 test_success=0