diff --git a/.github/workflows/general-ci-tests.yml b/.github/workflows/general-ci-tests.yml new file mode 100644 index 00000000..ff6b28af --- /dev/null +++ b/.github/workflows/general-ci-tests.yml @@ -0,0 +1,110 @@ +name: General MOM_interface CI + +# This CI workflow tests against the following questions: +# 1. Does standalone mom build and run? +# 2. Does it pass the tests/check_default_params.py test? +# 3. Do the scripts in cime_config pass the black formatter? +# Please see Issue #138 for more information + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the listed branches + push: + branches: ["main" ] + pull_request: + branches: [ "main" ] + +jobs: + + check_standalone_mom_build_and_run_lightweight_examples: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + steps: + + # Copied from NCAR/MOM6 - Install Basic Build Packages for MOM6 + - name: Install Ubuntu Linux packages + shell: bash + run: | + echo "::group::Install linux packages" + sudo apt-get update + sudo apt-get install netcdf-bin + sudo apt-get install libnetcdf-dev + sudo apt-get install libnetcdff-dev + sudo apt-get install openmpi-bin + sudo apt-get install libopenmpi-dev + sudo apt-get install linux-tools-common + sudo apt-get install -y csh + echo "::endgroup::" + + # Checkout CESM (default branch) and externals + - name: Checkout CESM and Externals + run: | + git clone https://github.com/ESCOMP/CESM.git + cd CESM + ./bin/git-fleximod update + + # Checkout the correct MOM Branch + - name: Checkout initial event (Pull Request) + if: ${{ github.event_name == 'pull_request' }} + run: | + echo "Handling pull request" + cd $GITHUB_WORKSPACE/CESM/components/mom/ + git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-${{ github.event.pull_request.number }} + git checkout pr-${{ github.event.pull_request.number }} + + - name: Checkout initial event (Push) + if: ${{ github.event_name == 'push' }} + run: | + echo "Handling push" + cd $GITHUB_WORKSPACE/CESM/components/mom/ + git checkout ${{ github.sha }} + + # Build the standalone mom using the macos script. build_examples-ncar doesn't work. + - name: Build Standalone MOM + run: | + cd $GITHUB_WORKSPACE/CESM/components/mom/standalone/build + ./build_examples.sh --compiler gnu --machine ubuntu + + # CD into a couple MOM examples and run MOM in them. These are very light weight and quick. + - name: Run Double Gyre Test + run: | + cd $GITHUB_WORKSPACE/CESM/components/mom/standalone/examples/double_gyre + $GITHUB_WORKSPACE/CESM/components/mom/standalone/build/gnu/MOM6/MOM6 + - name: Run Single Column KPP Test + run: | + cd $GITHUB_WORKSPACE/CESM/components/mom/standalone/examples/single_column/KPP + $GITHUB_WORKSPACE/CESM/components/mom/standalone/build/gnu/MOM6/MOM6 + + + # Job to run the check_default_params script, which is a test + check_default_params: + + runs-on: ubuntu-latest + + steps: + # Checkout the repo + - uses: actions/checkout@v4 + + # Run the test + - name: Run the check_default_params script + run: python tests/check_default_params.py + + # Job to run the black formatter for cime_config, see black documentation for more info + check_black_format_for_cime_config: + + runs-on: ubuntu-latest + + steps: + # Checkout the repo + - uses: actions/checkout@v4 + + # Run black check + - uses: psf/black@stable + with: + options: "--check --verbose" + src: "./cime_config" + + + + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 10d2e5d9..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: python -python: - - "2.7" - - "3.6" - -git: - submodules: false # no need to check out MOM6 for now - -install: - - chmod ugo+x ./tests/check_default_params.py - - pip install pyyaml - - pip install yamllint - -script: - - ./tests/check_default_params.py - - ./tests/doctests.py - - yamllint param_templates/*.y*ml -c tests/yamllint_config.yaml - diff --git a/README.md b/README.md index 7a35aa43..9a0920d3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/ESCOMP/MOM_interface.svg?branch=master)](https://travis-ci.org/ESCOMP/MOM_interface) +[![MOM_interface CI](https://github.com/ESCOMP/MOM_interface/actions/workflows/general-ci-tests.yml/badge.svg)](https://github.com/ESCOMP/MOM_interface/actions/workflows/general-ci-tests.yml) # MOM_interface diff --git a/cime_config/SystemTests/dimcs.py b/cime_config/SystemTests/dimcs.py index de58a514..5d4278a4 100644 --- a/cime_config/SystemTests/dimcs.py +++ b/cime_config/SystemTests/dimcs.py @@ -32,8 +32,8 @@ "H_RESCALE_POWER = -11", "Z_RESCALE_POWER = -11", "R_RESCALE_POWER = -11", - "Q_RESCALE_POWER = -11" - ] + "Q_RESCALE_POWER = -11", +] run_suffixes = [ "base", @@ -67,27 +67,36 @@ "scale the dimension Q by 2**-11", ] + class DIMCS(SystemTestsCompareN): def __init__(self, case): self.comp = case.get_value("COMP_OCN") - SystemTestsCompareN.__init__(self, case, N=len(nl_contents), - separate_builds = False, - run_suffixes = run_suffixes, - run_descriptions = run_descriptions, - ignore_fieldlist_diffs = True) + SystemTestsCompareN.__init__( + self, + case, + N=len(nl_contents), + separate_builds=False, + run_suffixes=run_suffixes, + run_descriptions=run_descriptions, + ignore_fieldlist_diffs=True, + ) def _common_setup(self): - nl_contents_common = ''' + nl_contents_common = """ ! DIMCS test changes - ''' - append_to_user_nl_files(caseroot = self._case.get_value("CASEROOT"), - component = self.comp, - contents = nl_contents_common) + """ + append_to_user_nl_files( + caseroot=self._case.get_value("CASEROOT"), + component=self.comp, + contents=nl_contents_common, + ) def _case_setup(self, i): # Second append user_nl change sepecific to case-i - append_to_user_nl_files(caseroot = self._case.get_value("CASEROOT"), - component = self.comp, - contents = nl_contents[i]) \ No newline at end of file + append_to_user_nl_files( + caseroot=self._case.get_value("CASEROOT"), + component=self.comp, + contents=nl_contents[i], + ) diff --git a/cime_config/SystemTests/dimcsl.py b/cime_config/SystemTests/dimcsl.py index d090e0d9..3e7ff609 100644 --- a/cime_config/SystemTests/dimcsl.py +++ b/cime_config/SystemTests/dimcsl.py @@ -27,7 +27,7 @@ "Z_RESCALE_POWER = 11", "R_RESCALE_POWER = 11", "Q_RESCALE_POWER = 11", - ] +] run_suffixes = [ "base", @@ -49,27 +49,36 @@ "scale the dimension Q by 2**11", ] + class DIMCSL(SystemTestsCompareN): def __init__(self, case): self.comp = case.get_value("COMP_OCN") - SystemTestsCompareN.__init__(self, case, N=len(nl_contents), - separate_builds = False, - run_suffixes = run_suffixes, - run_descriptions = run_descriptions, - ignore_fieldlist_diffs = True) + SystemTestsCompareN.__init__( + self, + case, + N=len(nl_contents), + separate_builds=False, + run_suffixes=run_suffixes, + run_descriptions=run_descriptions, + ignore_fieldlist_diffs=True, + ) def _common_setup(self): - nl_contents_common = ''' + nl_contents_common = """ ! DIMCSL test changes - ''' - append_to_user_nl_files(caseroot = self._case.get_value("CASEROOT"), - component = self.comp, - contents = nl_contents_common) + """ + append_to_user_nl_files( + caseroot=self._case.get_value("CASEROOT"), + component=self.comp, + contents=nl_contents_common, + ) def _case_setup(self, i): # Second append user_nl change sepecific to case-i - append_to_user_nl_files(caseroot = self._case.get_value("CASEROOT"), - component = self.comp, - contents = nl_contents[i]) \ No newline at end of file + append_to_user_nl_files( + caseroot=self._case.get_value("CASEROOT"), + component=self.comp, + contents=nl_contents[i], + ) diff --git a/standalone/build/build_examples-darwin.sh b/standalone/build/build_examples-darwin.sh deleted file mode 100755 index c23e61af..00000000 --- a/standalone/build/build_examples-darwin.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -e -### For NCAR machines, this script should be run as -### $ qcmd -- ./build_examples.sh - -# Save various paths to use as shortcuts -cd ../.. -INTERFACE_ROOT=`pwd -P` -MKMF_ROOT=${INTERFACE_ROOT}/standalone/mkmf -TEMPLATE_DIR=${INTERFACE_ROOT}/standalone/templates -MOM_ROOT=${INTERFACE_ROOT}/MOM6 -cd ../.. -CESM_ROOT=`pwd -P` -SHR_ROOT=${CESM_ROOT}/share -FMS_ROOT=${CESM_ROOT}/libraries/FMS - -COMPILER=gnu - -if [ -e $1 ]; then - BLD_ROOT=${COMPILER} -else - BLD_ROOT=$1 -fi - -# 1) Build FMS -cd ${INTERFACE_ROOT}/standalone/build -mkdir -p ${BLD_ROOT}/FMS -cd ${BLD_ROOT}/FMS -${MKMF_ROOT}/list_paths ${FMS_ROOT}/src -# We need shr_const_mod.F90 and shr_kind_mod.F90 from ${SHR_ROOT}/src -# to build FMS -echo "${SHR_ROOT}/src/shr_kind_mod.F90" >> path_names -echo "${SHR_ROOT}/src/shr_const_mod.F90" >> path_names -${MKMF_ROOT}/mkmf -t ${TEMPLATE_DIR}/homebrew-${COMPILER}.mk -p libfms.a -c "-Duse_libMPI -Duse_netCDF -DSPMD" path_names -make -j2 NETCDF=3 REPRO=1 libfms.a - -# 2) Build MOM6 -cd ${INTERFACE_ROOT}/standalone/build -mkdir -p ${BLD_ROOT}/MOM6 -cd ${BLD_ROOT}/MOM6 -${MKMF_ROOT}/list_paths -l ${MOM_ROOT}/{config_src/infra/FMS2,config_src/memory/dynamic_symmetric,config_src/drivers/solo_driver,../externals/MARBL/src,config_src/external,src/{*,*/*}}/ -${MKMF_ROOT}/mkmf -t ${TEMPLATE_DIR}/homebrew-${COMPILER}.mk -o '-I../FMS' -p MOM6 -l '-L../FMS -lfms' -c '-Duse_libMPI -Duse_netCDF -DSPMD' path_names -make -j2 NETCDF=3 REPRO=1 MOM6 diff --git a/standalone/build/build_examples-ncar.sh b/standalone/build/build_examples.sh similarity index 52% rename from standalone/build/build_examples-ncar.sh rename to standalone/build/build_examples.sh index da4800e9..ccba3a6a 100755 --- a/standalone/build/build_examples-ncar.sh +++ b/standalone/build/build_examples.sh @@ -15,8 +15,56 @@ CESM_ROOT=`pwd -P` SHR_ROOT=${CESM_ROOT}/share FMS_ROOT=${CESM_ROOT}/libraries/FMS -COMPILER=intel -TEMPLATE=${TEMPLATE_DIR}/ncar-${COMPILER}.mk +# Default compiler +COMPILER="intel" +MACHINE="ncar" + +# Parse command line arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + --compiler) + COMPILER="$2" + shift ;; + --machine) + MACHINE="$2" + shift ;; + *) + echo "Unknown parameter passed: $1" + echo "Usage: $0 [--compiler ] [--machine ]" + exit 1 ;; + esac + shift +done +echo "Using compiler: $COMPILER" +echo "Using machine: $MACHINE" + +TEMPLATE=${TEMPLATE_DIR}/${MACHINE}-${COMPILER}.mk + +# Throw error if template does not exist: +if [ ! -f $TEMPLATE ]; then + echo "ERROR: Template file $TEMPLATE does not exist." + echo "Templates are based on the machine and compiler arguments: machine-compiler.mk. Available templates are:" + ls ${TEMPLATE_DIR}/*.mk + echo "Exiting." + exit 1 +fi + +# Set -j option based on the MACHINE argument +case $MACHINE in + "homebrew" ) + JOBS=2 + ;; + "ubuntu" ) + JOBS=4 + ;; + "ncar") + JOBS=36 + ;; + *) + echo "Invalid machine type for make -j option: $MACHINE" + exit 1 + ;; +esac if [ -e $1 ]; then BLD_ROOT=${COMPILER} @@ -25,8 +73,6 @@ else fi # 1) Build FMS - -# (b) build FMS cd ${INTERFACE_ROOT}/standalone/build mkdir -p ${BLD_ROOT}/FMS cd ${BLD_ROOT}/FMS @@ -36,7 +82,7 @@ ${MKMF_ROOT}/list_paths ${FMS_ROOT}/src echo "${SHR_ROOT}/src/shr_kind_mod.F90" >> path_names echo "${SHR_ROOT}/src/shr_const_mod.F90" >> path_names ${MKMF_ROOT}/mkmf -t ${TEMPLATE} -p libfms.a -c "-Duse_libMPI -Duse_netCDF -DSPMD" path_names -make -j36 NETCDF=3 REPRO=1 libfms.a +make -j${JOBS} NETCDF=3 REPRO=1 libfms.a # 2) Build MOM6 cd ${INTERFACE_ROOT}/standalone/build @@ -44,6 +90,6 @@ mkdir -p ${BLD_ROOT}/MOM6 cd ${BLD_ROOT}/MOM6 ${MKMF_ROOT}/list_paths -l ${MOM_ROOT}/{config_src/infra/FMS2,config_src/memory/dynamic_symmetric,config_src/drivers/solo_driver,../externals/MARBL/src,config_src/external,src/{*,*/*}}/ ${MKMF_ROOT}/mkmf -t ${TEMPLATE} -o '-I../FMS' -p MOM6 -l '-L../FMS -lfms' -c '-Duse_libMPI -Duse_netCDF -DSPMD' path_names -make -j36 NETCDF=3 REPRO=1 MOM6 +make -j${JOBS} NETCDF=3 REPRO=1 MOM6 echo "Finished build at `date`" diff --git a/standalone/build/submit_casper_build b/standalone/build/submit_casper_build index a32ac318..6fe28b32 100644 --- a/standalone/build/submit_casper_build +++ b/standalone/build/submit_casper_build @@ -19,4 +19,4 @@ #PBS -m abe ### Run the executable -./build_examples-ncar.sh intel-casper +./build_examples.sh --compiler intel --machine ncar diff --git a/standalone/templates/ncar-gnu.mk b/standalone/templates/ncar-gnu.mk index 7580dfa0..a60e3162 100644 --- a/standalone/templates/ncar-gnu.mk +++ b/standalone/templates/ncar-gnu.mk @@ -21,7 +21,7 @@ MAKEFLAGS += --jobs=$(shell grep '^processor' /proc/cpuinfo | wc -l) FPPFLAGS := -FFLAGS := -fcray-pointer -fdefault-double-8 -fdefault-real-8 -Waliasing -ffree-line-length-none -fno-range-check +FFLAGS := -fcray-pointer -fdefault-double-8 -fdefault-real-8 -Waliasing -ffree-line-length-none -fno-range-check -fallow-argument-mismatch FFLAGS += -I$(shell nc-config --includedir) FFLAGS += $(shell pkg-config --cflags-only-I mpich2-c) FFLAGS_OPT = -O3 @@ -79,7 +79,7 @@ ifeq ($(NETCDF),3) endif endif -LIBS := $(shell nc-config --flibs) $(shell pkg-config --libs mpich2-f90) +LIBS := $(shell nf-config --flibs) $(shell pkg-config --libs mpich2-f90) LDFLAGS += $(LIBS) #--------------------------------------------------------------------------- diff --git a/standalone/templates/ubuntu-gnu.mk b/standalone/templates/ubuntu-gnu.mk new file mode 100644 index 00000000..034ca5ab --- /dev/null +++ b/standalone/templates/ubuntu-gnu.mk @@ -0,0 +1,170 @@ +# template for the GNU fortran compiler for Ubuntu (Used initially for Github Actions) +# (assumes Ubuntu with apt installs of netcdf-bin, libnetcdf-dev, libnetcdff-dev, openmpi-bin, libopenmpi-dev, linux-tools-common) +############ +# commands # +############ +FC = mpif90 +CC = mpicc +CXX = g++ +LD = mpif90 $(MAIN_PROGRAM) + +######### +# flags # +######### +DEBUG = +REPRO = +VERBOSE = +OPENMP = + +MAKEFLAGS += --jobs=2 + +FPPFLAGS := + +FFLAGS := -fcray-pointer -fdefault-double-8 -fdefault-real-8 -Waliasing -ffree-line-length-none -fno-range-check +FFLAGS += -I$(shell nf-config --includedir) +FFLAGS_OPT = -O3 +FFLAGS_REPRO = -O2 -fbounds-check +FFLAGS_DEBUG = -O0 -g -W -fbounds-check -fbacktrace -ffpe-trap=invalid,zero,overflow +FFLAGS_OPENMP = -fopenmp +FFLAGS_VERBOSE = + +CFLAGS := -D__IFC +CFLAGS += -I$(shell nc-config --includedir) +CFLAGS_OPT = -O2 +CFLAGS_OPENMP = -fopenmp +CFLAGS_DEBUG = -O0 -g + +# Optional Testing compile flags. Mutually exclusive from DEBUG, REPRO, and OPT +# *_TEST will match the production if no new option(s) is(are) to be tested. +FFLAGS_TEST = -O2 +CFLAGS_TEST = -O2 + +LDFLAGS := +LDFLAGS_OPENMP := -fopenmp +LDFLAGS_VERBOSE := + +ifneq ($(REPRO),) +CFLAGS += $(CFLAGS_REPRO) +FFLAGS += $(FFLAGS_REPRO) +else ifneq ($(DEBUG),) +CFLAGS += $(CFLAGS_DEBUG) +FFLAGS += $(FFLAGS_DEBUG) +else ifneq ($(TEST),) +CFLAGS += $(CFLAGS_TEST) +FFLAGS += $(FFLAGS_TEST) +else +CFLAGS += $(CFLAGS_OPT) +FFLAGS += $(FFLAGS_OPT) +endif + +ifneq ($(OPENMP),) +CFLAGS += $(CFLAGS_OPENMP) +FFLAGS += $(FFLAGS_OPENMP) +LDFLAGS += $(LDFLAGS_OPENMP) +endif + +ifneq ($(VERBOSE),) +CFLAGS += $(CFLAGS_VERBOSE) +FFLAGS += $(FFLAGS_VERBOSE) +LDFLAGS += $(LDFLAGS_VERBOSE) +endif + +ifeq ($(NETCDF),3) + # add the use_LARGEFILE cppdef + ifneq ($(findstring -Duse_netCDF,$(CPPDEFS)),) + CPPDEFS += -Duse_LARGEFILE + endif +endif + +LIBS := $(shell nc-config --libs) $(shell nf-config --flibs) +LDFLAGS += $(LIBS) + +#--------------------------------------------------------------------------- +# you should never need to change any lines below. + +# see the MIPSPro F90 manual for more details on some of the file extensions +# discussed here. +# this makefile template recognizes fortran sourcefiles with extensions +# .f, .f90, .F, .F90. Given a sourcefile ., where is one of +# the above, this provides a number of default actions: + +# make .opt create an optimization report +# make .o create an object file +# make .s create an assembly listing +# make .x create an executable file, assuming standalone +# source +# make .i create a preprocessed file (for .F) +# make .i90 create a preprocessed file (for .F90) + +# The macro TMPFILES is provided to slate files like the above for removal. + +RM = rm -f +SHELL = /bin/csh -f +TMPFILES = .*.m *.B *.L *.i *.i90 *.l *.s *.mod *.opt + +.SUFFIXES: .F .F90 .H .L .T .f .f90 .h .i .i90 .l .o .s .opt .x + +.f.L: + $(FC) $(FFLAGS) -c -listing $*.f +.f.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f +.f.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f +.f.T: + $(FC) $(FFLAGS) -c -cif $*.f +.f.o: + $(FC) $(FFLAGS) -c $*.f +.f.s: + $(FC) $(FFLAGS) -S $*.f +.f.x: + $(FC) $(FFLAGS) -o $*.x $*.f *.o $(LDFLAGS) +.f90.L: + $(FC) $(FFLAGS) -c -listing $*.f90 +.f90.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f90 +.f90.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f90 +.f90.T: + $(FC) $(FFLAGS) -c -cif $*.f90 +.f90.o: + $(FC) $(FFLAGS) -c $*.f90 +.f90.s: + $(FC) $(FFLAGS) -c -S $*.f90 +.f90.x: + $(FC) $(FFLAGS) -o $*.x $*.f90 *.o $(LDFLAGS) +.F.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F +.F.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F +.F.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F +.F.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F +.F.f: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F > $*.f +.F.i: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F +.F.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F +.F.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F +.F.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F *.o $(LDFLAGS) +.F90.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F90 +.F90.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F90 +.F90.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F90 +.F90.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F90 +.F90.f90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F90 > $*.f90 +.F90.i90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F90 +.F90.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F90 +.F90.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F90 +.F90.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F90 *.o $(LDFLAGS)