From e69287ab4ff1c738109f738ab3cea0084b1e2fd7 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 2 Sep 2020 09:05:44 -0400 Subject: [PATCH 01/23] Autoconf-based build framework This patch is a first draft of an autoconf-based build for MOM6. This is a hybrid solution which relies on mkmf and list_paths to automatically generate the model dependencies, but uses autoconf to determine the necessary compiler flags for building the model. Recommended instructions for testing the build system, as well as instructions for new users, are shown below. ``` # (Optional) Fetch mkmf and build FMS cd deps make -j cd .. # Set up the autoconf build files autoreconf # Configure and build the model in /build mkdir -p build cd build ../configure make -j ``` As with standard autoconf builds, compilers and flags can be configured with prepended arguments, e.g. ``` FC=mpifort FCFLAGS="-g -O0 -Wall -Wextra" ./configure make ``` Introduction of autoconf configuration should not interfere with any existing mkmf-based build procedures. A more detailed discussion is provided below. ---- At minimum, only the following instructions would be required: ``` autoreconf ./configure make ``` but this requires that both mkmf and FMS be accessible in standard searchable directories. A more realistic MOM6-only build would be as shown below ``` autoreconf PATH="path/to/mkmf/bin:${PATH}" \ FCFLAGS="-Ipath/to/fms_mods" \ LDFLAGS="-Lpath/to/fms_lib" \ ./configure make ``` where `path/to/xxx` points to the location of the pre-installed content. To alleviate this issue, a Makefile in the `deps` directory has been provided, which checks out copies of mkmf and FMS and places them in the `deps` directory. If the MOM6 `./configure` script is unable to find mkmf or FMS, then it will automatically continue to search inside of the `deps` directory. ---- The `deps` directory provides templates for an autoconf build of FMS resembling our MOM6 build. The Makefile provides the following rules: `make` or `make all`: Fetch mkmf and FMS, build FMS, install module files to `deps/include` and `libFMS.a` to `deps/lib`. `make clean` Delete the compiled FMS files in `deps/fms/build` but not the installed libraries or module files. `make distclean` Delete all files produced by the Makefile. Much of the FMS source configuration has been moved to the `deps` Makefile. The available hooks and default values are shown below. ``` MKMF_URL ?= https://github.com/NOAA-GFDL/mkmf.git MKMF_COMMIT ?= master FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git FMS_COMMIT ?= 2019.01.03 FCFLAGS_FMS ?= ``` The FCFLAGS_FMS hook is provided to override the default autoconf value, `-g -O2`. Although FMS provides its own automake build framework, the 2019.01.03 release cannot be used with MOM6 due to missing components in its libtool configuration (`random_number`). The build time is also significantly longer due to incorrect dependencies in the automake configuration. Most of the issues describe above have either been or will soon be resolved in newer FMS releases, and we may be able to transition to the FMS automake in a future release. ---- The `.testing` directory has been reworked to use the autoconf builds of MOM6 and FMS, but should otherwise work the same as before. ``` cd .testing make -j make -j test ``` The changes required to use autoconf have been incorporated into the `.testing` Makefile. This can create issues with the management of FMS, which is now configured inside of `deps/Makefile` rather than in `.testing`. Also, a rebuild of FMS will require an explicit wipe of FMS in `deps`, which can be done with the following command. ``` make -C ../deps distclean ``` Platform-specific flags are now managed in the `config.mk` file rather than in a mkmf template. The following hooks are provided, with default values shown. ``` FCFLAGS_DEBUG ?= -g -O0 FCFLAGS_REPRO ?= -g -O2 FCFLAGS_INIT ?= FCFLAGS_COVERAGE ?= ``` The intention is to provide some correspondence to the GFDL DEBUG and REPRO production builds. Any FMS build produced by `make` in `.testing` will use the `FCFLAGS_DEBUG` variable. Although `FCFLAGS_INIT` is intended for intialization, it acts as more of a general-purpose flag which is applied to MOM6 but not FMS. ---- Other points of interest - This build system only uses autoconf. It does not use automake or libtools. - autoconf will determine any necessary flags required for building MOM6, but does not attempt to use optional flags for debugging or performance. Flags required for testing or production builds must still track or otherwise manage their own compiler flags (FCFLAGS, etc). - The MOM6 `./configure` script requires a FMS library and module files as part of its build validation. This is why we must pre-build FMS before calling `./configure`. - FCFLAGS defaults to `-g -O2`. Any explicit setting of FCFLAGS will remove and replace these flags. Other flags, such as `-fdefault-real-8` will be appended as needed and do not need to be managed. - Support M4 macros have been tested on GCC, Intel, PGI, and Cray compilers. The macros can be extended to other compilers and older versions of these compilers if necessary. ---- Known issues - The macro used for the MPI launcher (AX_MPI) can potentially locate a MPIFC (e.g. mpif90) which does not match FC. For example, FC will tend to default to GFortran, but mpif90 may use Intel Fortran. While FC is quickly replaced with MPIFC, there are some initial tests which may fail if FCFLAGS was defined for the non-GFortran compiler. This can be resolved by explicitly setting both FC and FCFLAGS for the same compiler. - Since we use git for both development and distribution, we may want to pre-build the configure script and support files, eliminating the `autoreconf` step. --- .gitignore | 11 +- .testing/.gitignore | 8 +- .testing/Makefile | 211 ++++++++++++--------- .testing/linux-ubuntu-xenial-gnu.mk | 279 ---------------------------- .travis.yml | 27 ++- Makefile.in | 82 ++++++++ configure.ac | 156 ++++++++++++++++ deps/.gitignore | 5 + deps/Makefile | 94 ++++++++++ deps/Makefile.fms.in | 45 +++++ deps/configure.fms.ac | 123 ++++++++++++ m4/ax_fc_allow_arg_mismatch.m4 | 58 ++++++ m4/ax_fc_allow_invalid_boz.m4 | 54 ++++++ m4/ax_fc_check_lib.m4 | 52 ++++++ m4/ax_fc_check_module.m4 | 28 +++ m4/ax_fc_cray_pointer.m4 | 53 ++++++ m4/ax_fc_real8.m4 | 86 +++++++++ m4/ax_mpi.m4 | 176 ++++++++++++++++++ 18 files changed, 1168 insertions(+), 380 deletions(-) delete mode 100644 .testing/linux-ubuntu-xenial-gnu.mk create mode 100644 Makefile.in create mode 100644 configure.ac create mode 100644 deps/.gitignore create mode 100644 deps/Makefile create mode 100644 deps/Makefile.fms.in create mode 100644 deps/configure.fms.ac create mode 100644 m4/ax_fc_allow_arg_mismatch.m4 create mode 100644 m4/ax_fc_allow_invalid_boz.m4 create mode 100644 m4/ax_fc_check_lib.m4 create mode 100644 m4/ax_fc_check_module.m4 create mode 100644 m4/ax_fc_cray_pointer.m4 create mode 100644 m4/ax_fc_real8.m4 create mode 100644 m4/ax_mpi.m4 diff --git a/.gitignore b/.gitignore index e534738ed7..8a79222df4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,12 @@ html *.log MOM6 -build/ -deps/ + +# Autoconf +/aclocal.m4 +/autom4te.cache/ +/config.log +/config.status +/configure +/Makefile +/Makefile.mkmf diff --git a/.testing/.gitignore b/.testing/.gitignore index 441e73b8e8..ec8eae6348 100644 --- a/.testing/.gitignore +++ b/.testing/.gitignore @@ -1,3 +1,5 @@ -config.mk -work/ -results/ +# Test output +/config.mk +/build/ +/work/ +/results/ diff --git a/.testing/Makefile b/.testing/Makefile index 6f3553a694..dd0db892ac 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -4,36 +4,39 @@ SHELL = bash # User-defined configuration -include config.mk -# Default configurations +# Set the MPI launcher here MPIRUN ?= mpirun -DO_REPRO_TESTS ?= true -#--- -# Dependencies -DEPS = deps +# Many compilers (Intel, GCC on ARM64) do not yet produce identical results +# across DEBUG and REPRO builds. For these platforms, set to false +DO_REPRO_TESTS ?= true -# mkmf, list_paths (GFDL build toolchain) -MKMF_URL ?= https://github.com/NOAA-GFDL/mkmf.git -MKMF_COMMIT ?= master -LIST_PATHS := $(abspath $(DEPS)/mkmf/bin/list_paths) -MKMF := $(abspath $(DEPS)/mkmf/bin/mkmf) +# Default target compiler flags +# NOTE: FMS will be built using FCFLAGS_DEBUG +FCFLAGS_DEBUG ?= -g -O0 +FCFLAGS_REPRO ?= -g -O2 +FCFLAGS_INIT ?= +FCFLAGS_COVERAGE ?= +# Addtional notes: +# +# - The default values are simple, minimalist flags, supported by nearly all +# compilers and meant to represent GFDL's canonical DEBUG and REPRO builds. +# +# - These flags should be configured outside of the Makefile, either with +# config.mk or as environment variables. +# +# - FMS cannot be build with the same aggressive initialization flags as MOM6, +# so FCFLAGS_INIT is used to provide additional MOM6 configuration. -# FMS framework -FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git -FMS_COMMIT ?= 2019.01.03 -FMS := $(DEPS)/fms #--- -# Build configuration +# Dependencies +DEPS = ../deps -# Build settings -MKMF_CPP = "-Duse_libMPI -Duse_netCDF -DSPMD" +# mkmf, list_paths (GFDL build toolchain) +LIST_PATHS := $(DEPS)/bin/list_paths +MKMF := $(DEPS)/bin/mkmf -# Environment -# TODO: This info ought to be determined by CMake, automake, etc. -#MKMF_TEMPLATE ?= linux-ubuntu-xenial-gnu.mk -MKMF_TEMPLATE ?= deps/mkmf/templates/ncrc-gnu.mk -#MKMF_TEMPLATE ?= deps/mkmf/templates/ncrc-intel.mk #--- # Test configuration @@ -78,6 +81,7 @@ else TARGET_CODEBASE = endif + # List of source files to link this Makefile's dependencies to model Makefiles # Assumes a depth of two, and the following extensions: F90 inc c h # (1): Root directory @@ -85,13 +89,15 @@ endif SOURCE = \ $(foreach ext,F90 inc c h,$(wildcard $(1)/*/*.$(ext) $(1)/*/*/*.$(ext))) -MOM_SOURCE = $(call SOURCE,../src) $(wildcard ../config_src/solo_driver/*.F90) \ - $(wildcard ../config_src/ext*/*/*.F90) +MOM_SOURCE = $(call SOURCE,../src) \ + $(wildcard ../config_src/solo_driver/*.F90) \ + $(wildcard ../config_src/ext*/*/*.F90) TARGET_SOURCE = $(call SOURCE,build/target_codebase/src) \ $(wildcard build/target_codebase/config_src/solo_driver/*.F90) \ $(wildcard build/target_codebase/config_src/ext*/*.F90) FMS_SOURCE = $(call SOURCE,$(DEPS)/fms/src) + #--- # Python preprocessing environment configuration @@ -126,85 +132,114 @@ build.regressions: $(foreach b,symmetric target,build/$(b)/MOM6) BUILD_TARGETS = MOM6 Makefile path_names .PRECIOUS: $(foreach b,$(BUILDS),$(foreach f,$(BUILD_TARGETS),build/$(b)/$(f))) +# Compiler flags + # Conditionally build symmetric with coverage support -COVFLAG=$(if $(REPORT_COVERAGE),COVERAGE=1,) +COVERAGE=$(if $(REPORT_COVERAGE),"$(FCFLAGS_COVERAGE)",) -build/target/MOM6: MOMFLAGS=NETCDF=3 DEBUG=1 INIT=1 -build/symmetric/MOM6: MOMFLAGS=NETCDF=3 DEBUG=1 INIT=1 $(COVFLAG) -build/asymmetric/MOM6: MOMFLAGS=NETCDF=3 DEBUG=1 INIT=1 -build/repro/MOM6: MOMFLAGS=NETCDF=3 REPRO=1 -build/openmp/MOM6: MOMFLAGS=NETCDF=3 DEBUG=1 OPENMP=1 INIT=1 +# TODO: We should probably build TARGET with the FMS that it was configured +# to use. But for now we use the same FMS over all builds. +FCFLAGS_TARGET_FMS = -I../../../deps/include -L../../../deps/lib +PATH_TARGET = PATH="${PATH}:../../../deps/bin" -build/asymmetric/path_names: GRID_SRC=config_src/dynamic -build/%/path_names: GRID_SRC=config_src/dynamic_symmetric +# Define the build targets in terms of the traditional DEBUG/REPRO/etc labels +FCFLAGS_SYMMETRIC = +ifneq ($(FCFLAGS_DEBUG)$(FCFLAGS_INIT)$(COVERAGE),) + FCFLAGS_SYMMETRIC := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(COVERAGE)" +endif -build/%/MOM6: build/%/Makefile $(FMS)/lib/libfms.a - $(MAKE) -C $(@D) $(MOMFLAGS) $(@F) +FCFLAGS_TARGET = +FCFLAGS_ASYMMETRIC = +FCFLAGS_OPENMP = +ifneq ($(FCFLAGS_DEBUG)$(FCFLAGS_INIT),) + FCFLAGS_TARGET := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(FCFLAGS_TARGET_FMS)" + FCFLAGS_ASYMMETRIC := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT)" + FCFLAGS_OPENMP := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT)" +endif -build/%/Makefile: build/%/path_names - cp $(MKMF_TEMPLATE) $(@D) - cd $(@D) && $(MKMF) \ - -t $(notdir $(MKMF_TEMPLATE)) \ - -o '-I ../../$(DEPS)/fms/build' \ - -p MOM6 \ - -l '../../$(DEPS)/fms/lib/libfms.a' \ - -c $(MKMF_CPP) \ - path_names +FCFLAGS_REPRO_RUN = +ifneq ($(FCFLAGS_REPRO),) + FCFLAGS_REPRO_RUN := FCFLAGS="$(FCFLAGS_REPRO)" +endif -# NOTE: These path_names rules could be merged -build/target/path_names: $(LIST_PATHS) $(TARGET_CODEBASE) $(TARGET_SOURCE) - mkdir -p $(@D) - cd $(@D) && $(LIST_PATHS) -l \ - ../../$(TARGET_CODEBASE)/src \ - ../../$(TARGET_CODEBASE)/config_src/solo_driver \ - ../../$(TARGET_CODEBASE)/config_src/ext* \ - ../../$(TARGET_CODEBASE)/$(GRID_SRC) +# Environment variable configuration +build/symmetric/Makefile: FC_ENV=$(FCFLAGS_SYMMETRIC) +build/asymmetric/Makefile: FC_ENV=$(FCFLAGS_ASYMMETRIC) +build/repro/Makefile: FC_ENV=$(FCFLAGS_REPRO_RUN) +build/openmp/Makefile: FC_ENV=$(FCFLAGS_OPENMP) +build/target/Makefile: FC_ENV=$(FCFLAGS_TARGET) $(PATH_TARGET) -build/%/path_names: $(LIST_PATHS) $(MOM_SOURCE) - mkdir -p $(@D) - cd $(@D) && $(LIST_PATHS) -l \ - ../../../src \ - ../../../config_src/solo_driver \ - ../../../config_src/ext* \ - ../../../$(GRID_SRC) -# Target repository for regression tests -$(TARGET_CODEBASE): - git clone --recursive $(MOM_TARGET_URL) $@ - cd $@ && git checkout $(MOM_TARGET_BRANCH) +# Configure script flags +build/asymmetric/Makefile: AC_FLAGS= +build/openmp/Makefile: AC_FLAGS=--enable-symmetric --enable-openmp +build/target/Makefile: AC_FLAGS=--srcdir=../../$(TARGET_CODEBASE) --enable-symmetric +build/%/Makefile: AC_FLAGS=--enable-symmetric -#---- -# FMS build +# Fetch regression target source code +build/target/Makefile: $(TARGET_CODEBASE) + -$(FMS)/lib/libfms.a: $(FMS)/build/Makefile - mkdir -p $(FMS)/lib - cd $(FMS)/build && $(MAKE) NETCDF=3 DEBUG=1 ../lib/libfms.a +# Define source code dependencies +# NOTE: ./configure is too much, but Makefile is not enough! +# Ideally we would want to re-run both Makefile and mkmf, but our mkmf call +# is inside ./configure, so we must re-run ./configure as well. +$(foreach b,$(filter-out target,$(BUILDS)),build/$(b)/Makefile): $(MOM_SOURCE) +build/target/configure: $(TARGET_SOURCE) -$(FMS)/build/Makefile: $(FMS)/build/path_names - cp $(MKMF_TEMPLATE) $(@D) - cd $(@D) && $(MKMF) \ - -t $(notdir $(MKMF_TEMPLATE)) \ - -p ../lib/libfms.a \ - -c $(MKMF_CPP) \ - path_names -$(FMS)/build/path_names: $(LIST_PATHS) $(FMS)/src $(FMS_SOURCE) +# Build MOM6 +.PRECIOUS: $(foreach b,$(BUILDS),build/$(b)/MOM6) +build/%/MOM6: build/%/Makefile + cd $(@D) && time $(MAKE) -j + + +# Use autoconf to construct the Makefile for each target +.PRECIOUS: $(foreach b,$(BUILDS),build/$(b)/Makefile) +build/%/Makefile: ../configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) - cd $(@D) && $(LIST_PATHS) -l ../src + cd $(@D) \ + && $(FC_ENV) ../../../configure $(AC_FLAGS) \ + || (cat config.log && false) -$(FMS)/src: - git clone $(FMS_URL) $@ - cd $@; git checkout $(FMS_COMMIT) +../configure: ../configure.ac ../Makefile.in ../m4 + autoreconf -i $< + + +# Fetch the regression target codebase +build/target/Makefile: $(TARGET_CODEBASE)/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) + mkdir -p $(@D) + cd $(@D) \ + && $(FC_ENV) ../../$(TARGET_CODEBASE)/configure $(AC_FLAGS) \ + || (cat config.log && false) + + +$(TARGET_CODEBASE)/configure: $(TARGET_CODEBASE) + autoreconf -i $< -#--- -# Build Toolchain -$(LIST_PATHS) $(MKMF): - git clone $(MKMF_URL) $(DEPS)/mkmf - cd $(DEPS)/mkmf; git checkout $(MKMF_COMMIT) +$(TARGET_CODEBASE): + git clone --recursive $(MOM_TARGET_URL) $@ + cd $@ && git checkout $(MOM_TARGET_BRANCH) + # Copy modern autoconf files to target? + cp ../configure.ac $(TARGET_CODEBASE)/ + cp ../Makefile.in $(TARGET_CODEBASE)/ + cp -r ../m4 $(TARGET_CODEBASE)/ + + +# FMS +$(DEPS)/lib/libFMS.a: $(DEPS)/Makefile $(FMS_SOURCE) $(MKMF) $(LIST_PATHS) + FCFLAGS_FMS="$(FCFLAGS_DEBUG)" $(MAKE) -C $(DEPS) lib/libFMS.a + + +# mkmf +$(MKMF) $(LIST_PATHS): $(DEPS)/mkmf + +$(DEPS)/mkmf: $(DEPS)/Makefile + $(MAKE) -C $(DEPS) bin/$(@F) #--- @@ -305,6 +340,7 @@ $(eval $(call CMP_RULE,regression,symmetric target)) # TODO: chksum_diag parsing of restart files + #--- # Test run output files @@ -331,7 +367,7 @@ work/%/$(1)/ocean.stats work/%/$(1)/chksum_diag: build/$(2)/MOM6 mkdir -p $$(@D)/RESTART echo -e "$(4)" > $$(@D)/MOM_override cd $$(@D) \ - && $(5) $(MPIRUN) -n $(6) ../../../$$< 2> std.err > std.out \ + && time $(5) $(MPIRUN) -n $(6) ../../../$$< 2> std.err > std.out \ || !( \ mkdir -p ../../../results/$$*/ ; \ cat std.out | tee ../../../results/$$*/std.$(1).out | tail -20 ; \ @@ -391,7 +427,7 @@ work/%/restart/ocean.stats: build/symmetric/MOM6 && halfperiod=$$(printf "%.f" $$(bc <<< "scale=10; 0.5 * $${daymax} * $${timeunit_int}")) \ && printf "\n&ocean_solo_nml\n seconds = $${halfperiod}\n/\n" >> input.nml # Run the first half-period - cd $(@D) && $(MPIRUN) -n 1 ../../../$< 2> std1.err > std1.out \ + cd $(@D) && time $(MPIRUN) -n 1 ../../../$< 2> std1.err > std1.out \ || !( \ cat std1.out | tee ../../../results/$*/std.restart1.out | tail ; \ cat std1.err | tee ../../../results/$*/std.restart1.err | tail ; \ @@ -402,7 +438,7 @@ work/%/restart/ocean.stats: build/symmetric/MOM6 mkdir $(@D)/RESTART cd $(@D) && sed -i -e "s/input_filename *= *'n'/input_filename = 'r'/g" input.nml # Run the second half-period - cd $(@D) && $(MPIRUN) -n 1 ../../../$< 2> std2.err > std2.out \ + cd $(@D) && time $(MPIRUN) -n 1 ../../../$< 2> std2.err > std2.out \ || !( \ cat std2.out | tee ../../../results/$*/std.restart2.out | tail ; \ cat std2.err | tee ../../../results/$*/std.restart2.err | tail ; \ @@ -446,6 +482,7 @@ clean: clean.stats @[ $$(basename $$(pwd)) = .testing ] rm -rf build + .PHONY: clean.stats clean.stats: @[ $$(basename $$(pwd)) = .testing ] diff --git a/.testing/linux-ubuntu-xenial-gnu.mk b/.testing/linux-ubuntu-xenial-gnu.mk deleted file mode 100644 index 04ba952408..0000000000 --- a/.testing/linux-ubuntu-xenial-gnu.mk +++ /dev/null @@ -1,279 +0,0 @@ -# Template for the GNU Compiler Collection on Xenial version of Ubuntu Linux systems (used by Travis-CI) -# -# Typical use with mkmf -# mkmf -t linux-ubuntu-xenial-gnu.mk -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include - -############ -# Commands Macors -FC = mpif90 -CC = mpicc -LD = mpif90 $(MAIN_PROGRAM) - -####################### -# Build target macros -# -# Macros that modify compiler flags used in the build. Target -# macrose are usually set on the call to make: -# -# make REPRO=on NETCDF=3 -# -# Most target macros are activated when their value is non-blank. -# Some have a single value that is checked. Others will use the -# value of the macro in the compile command. - -DEBUG = # If non-blank, perform a debug build (Cannot be - # mixed with REPRO or TEST) - -REPRO = # If non-blank, perform a build that guarentees - # reprodicuibilty from run to run. Cannot be used - # with DEBUG or TEST - -TEST = # If non-blank, use the compiler options defined in - # the FFLAGS_TEST and CFLAGS_TEST macros. Cannot be - # use with REPRO or DEBUG - -VERBOSE = # If non-blank, add additional verbosity compiler - # options - -OPENMP = # If non-blank, compile with openmp enabled - -NO_OVERRIDE_LIMITS = # If non-blank, do not use the -qoverride-limits - # compiler option. Default behavior is to compile - # with -qoverride-limits. - -NETCDF = # If value is '3' and CPPDEFS contains - # '-Duse_netCDF', then the additional cpp macro - # '-Duse_LARGEFILE' is added to the CPPDEFS macro. - -INCLUDES = # A list of -I Include directories to be added to the - # the compile command. - -SSE = # The SSE options to be used to compile. If blank, - # than use the default SSE settings for the host. - # Current default is to use SSE2. - -COVERAGE = # Add the code coverage compile options. - -INIT = # Enable aggressive initialization - -# Need to use at least GNU Make version 3.81 -need := 3.81 -ok := $(filter $(need),$(firstword $(sort $(MAKE_VERSION) $(need)))) -ifneq ($(need),$(ok)) -$(error Need at least make version $(need). Load module gmake/3.81) -endif - -# REPRO, DEBUG and TEST need to be mutually exclusive of each other. -# Make sure the user hasn't supplied two at the same time -ifdef REPRO -ifneq ($(DEBUG),) -$(error Options REPRO and DEBUG cannot be used together) -else ifneq ($(TEST),) -$(error Options REPRO and TEST cannot be used together) -endif -else ifdef DEBUG -ifneq ($(TEST),) -$(error Options DEBUG and TEST cannot be used together) -endif -endif - -MAKEFLAGS += --jobs=$(shell grep '^processor' /proc/cpuinfo | wc -l) - -# Macro for Fortran preprocessor -FPPFLAGS := $(INCLUDES) -# Fortran Compiler flags for the NetCDF library -FPPFLAGS += $(shell nf-config --fflags) - -# Base set of Fortran compiler flags -FFLAGS := -fcray-pointer -fdefault-double-8 -fdefault-real-8 -Waliasing -ffree-line-length-none -fno-range-check - -# Flags based on perforance target (production (OPT), reproduction (REPRO), or debug (DEBUG) -FFLAGS_OPT = -O3 -FFLAGS_REPRO = -O2 -fbounds-check -FFLAGS_DEBUG = -O0 -g -W -Wno-compare-reals -fbounds-check -fbacktrace -ffpe-trap=invalid,zero,overflow -# Enable aggressive initialization -ifdef INIT -FFLAGS_DEBUG += -finit-real=snan -finit-integer=2147483647 -finit-derived -endif - -# Flags to add additional build options -FFLAGS_OPENMP = -fopenmp -FFLAGS_VERBOSE = -FFLAGS_COVERAGE = --coverage - -# Macro for C preprocessor -CPPFLAGS = $(INCLUDES) -# C Compiler flags for the NetCDF library -CPPFLAGS += $(shell nf-config --cflags) - -# Base set of C compiler flags -CFLAGS := -D__IFC - -# Flags based on perforance target (production (OPT), reproduction (REPRO), or debug (DEBUG) -CFLAGS_OPT = -O2 -CFLAGS_REPRO = -O2 -CFLAGS_DEBUG = -O0 -g - -# Flags to add additional build options -CFLAGS_OPENMP = -fopenmp -CFLAGS_VERBOSE = -CFLAGS_COVERAGE = --coverage - -# 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 = $(FFLAGS_OPT) -CFLAGS_TEST = $(CFLAGS_OPT) - -# Linking flags -LDFLAGS := -LDFLAGS_OPENMP := -fopenmp -LDFLAGS_VERBOSE := -LDFLAGS_COVERAGE := --coverage - -# Start with a blank LIBS -LIBS = -# NetCDF library flags -LIBS += $(shell nf-config --flibs) - -# Get compile flags based on target macros. -ifdef REPRO -CFLAGS += $(CFLAGS_REPRO) -FFLAGS += $(FFLAGS_REPRO) -else ifdef DEBUG -CFLAGS += $(CFLAGS_DEBUG) -FFLAGS += $(FFLAGS_DEBUG) -else ifdef TEST -CFLAGS += $(CFLAGS_TEST) -FFLAGS += $(FFLAGS_TEST) -else -CFLAGS += $(CFLAGS_OPT) -FFLAGS += $(FFLAGS_OPT) -endif - -ifdef OPENMP -CFLAGS += $(CFLAGS_OPENMP) -FFLAGS += $(FFLAGS_OPENMP) -LDFLAGS += $(LDFLAGS_OPENMP) -endif - -ifdef SSE -CFLAGS += $(SSE) -FFLAGS += $(SSE) -endif - -ifdef NO_OVERRIDE_LIMITS -FFLAGS += $(FFLAGS_OVERRIDE_LIMITS) -endif - -ifdef 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 - -ifdef COVERAGE -ifdef BUILDROOT -PROF_DIR=-prof-dir=$(BUILDROOT) -endif -CFLAGS += $(CFLAGS_COVERAGE) $(PROF_DIR) -FFLAGS += $(FFLAGS_COVERAGE) $(PROF_DIR) -LDFLAGS += $(LDFLAGS_COVERAGE) $(PROF_DIR) -endif - -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 -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) diff --git a/.travis.yml b/.travis.yml index 03bdff31dc..89a91d34b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,13 +31,16 @@ jobs: - env: - JOB="x86 Configuration testing" - DO_REGRESSION_TESTS=false - - MKMF_TEMPLATE=linux-ubuntu-xenial-gnu.mk + - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" + - FCFLAGS_REPRO="-g -O2 -fbacktrace" + - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" + - FCFLAGS_COVERAGE="--coverage" script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' - - make all + - time make all - echo -en 'travis_fold:end:script.1\\r' - - make -k -s test + - time make -k -s test - make test.summary # NOTE: Code coverage upload is here to reduce load imbalance @@ -48,15 +51,18 @@ jobs: - JOB="x86 Regression testing" - DO_REGRESSION_TESTS=true - REPORT_COVERAGE=true - - MKMF_TEMPLATE=linux-ubuntu-xenial-gnu.mk - MOM_TARGET_SLUG=${TRAVIS_REPO_SLUG} - MOM_TARGET_LOCAL_BRANCH=${TRAVIS_BRANCH} + - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" + - FCFLAGS_REPRO="-g -O2 -fbacktrace" + - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" + - FCFLAGS_COVERAGE="--coverage" script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' - - make build.regressions + - time make build.regressions - echo -en 'travis_fold:end:script.1\\r' - - make -k -s test.regressions + - time make -k -s test.regressions - make test.summary - if: NOT type = pull_request @@ -77,11 +83,14 @@ jobs: - JOB="ARM64 Configuration testing" - DO_REGRESSION_TESTS=false - DO_REPRO_TESTS=false - - MKMF_TEMPLATE=linux-ubuntu-xenial-gnu.mk + - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" + - FCFLAGS_REPRO="-g -O2 -fbacktrace" + - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" + - FCFLAGS_COVERAGE="--coverage" script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' - - make all + - time make all - echo -en 'travis_fold:end:script.1\\r' - - make -k -s test + - time make -k -s test - make test.summary diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000000..a1b1b9118a --- /dev/null +++ b/Makefile.in @@ -0,0 +1,82 @@ +# Makefile template for MOM6 +# +# Previously this would have been generated by mkmf using a template file. +# +# The proposed autoconf build inverts this approach by constructing the +# information previously stored in the mkmf template, such as compiler names +# and flags, and importing the un-templated mkmf output for its rules and +# dependencies. +# +# While this approach does not eliminate our dependency on mkmf, it does +# promises to eliminate our reliance on platform-specific templates, and +# instead allows us to provide a configure script for determining our compilers +# and flags. As a last resort, we provide hooks to override such settings. + +# NOTE: mkmf conventions are close, but not identical, to autoconf. +# +# CC: C compiler +# CXX: C++ compiler +# FC: Fortran compiler (f77 and f90) +# LD: Linker +# +# CPPDEFS: Preprocessor macros +# CPPFLAGS: C preprocessing flags +# CXXFLAGS: C++ preprocessing flags +# FPPFLAGS: Fortran preprocessing flags +# +# CFLAGS: C compiler flags +# FFLAGS: Fortran compiler flags +# LDFLAGS: Linker flags + libraries +# +# NOTES: +# - FPPFLAGS and FFLAGS always appear as a pair, and autoconf does not use +# FPPFLAGS, so FPPFLAGS does not serve much purpose. +# +# - mkmf's FFLAGS does not distinguish between autoconf's fixed-format +# FFLAGS and free-format FCFLAGS. +# +# - LDFLAGS does not distinguish between autoconf's LDFLAGS and LIBS. +# It also places both after the executable rather than just LIBS. +# +# OTHERFLAGS: Additional flags for all languages (C, C++, Fortran) +# OTHER_CFLAGS: Optional C flags +# OTHER_CXXFLAGS: Optional C++ flags +# OTHER_FFLAGS: Optional Fortran flags +# +# TMPFILES: Placeholder for `make clean` deletion (as `make neat`). + +FC = @FC@ +LD = @FC@ + +CPPDEFS = @DEFS@ +CPPFLAGS = @CPPFLAGS@ +FFLAGS = @FCFLAGS@ +LDFLAGS = @LDFLAGS@ @LIBS@ + +# Gather modulefiles +TMPFILES = $(wildcard *.mod) + +include Makefile.mkmf + + +# Delete any files associated with configuration (including the Makefile). +.PHONY: distclean +distclean: clean + # configure output + rm -f config.log + rm -f config.status + rm -f Makefile + # mkmf output + rm -f path_names + rm -f Makefile.mkmf + + +# This deletes all files generated by autoconf, including configure. +# It is more aggressive than automake's maintainer-clean. +# NOTE: Not a standard GNU target, this is for internal use only. +# Don't be surprised if the name changes or if it disappears someday. +.PHONY: ac-clean +ac-clean: distclean + rm -f aclocal.m4 + rm -rf autom4te.cache + rm -f configure diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000000..2da14c1381 --- /dev/null +++ b/configure.ac @@ -0,0 +1,156 @@ +# Autoconf configuration + +# NOTE: +# - We currently do not use a MOM6 version tag, but this would be one option in +# the future: +# [m4_esyscmd_s([git describe])] +# - Another option is `git rev-parse HEAD` for the full hash. +# - We would probably run this inside of a script to avoid the explicit +# dependency on git. + +AC_INIT( + [MOM6], + [ ], + [https://github.com/NOAA-GFDL/MOM6/issues], + [], + [https://github.com/NOAA-GFDL/MOM6]) + +# Validate srdcir and configure input +AC_CONFIG_SRCDIR([src/core/MOM.F90]) +AC_CONFIG_MACRO_DIR([m4]) + + +# Default to asymmetric grid +# NOTE: --enable is more properly used to add a feature, rather than to select +# a compile-time mode, so this is not exactly being used as intended. +MEM_LAYOUT=${srcdir}/config_src/dynamic +AC_ARG_ENABLE([symmetric], + AS_HELP_STRING([--enable-symmetric], [Enable symmetric grid])) +AS_IF([test "$enable_symmetric" = yes], + [MEM_LAYOUT=${srcdir}/config_src/dynamic_symmetric]) + + +## TODO: Support a user-defined memory header +#AC_CONFIG_HEADERS(["$MEM_LAYOUT/MOM_memory.h"]) + + +# Explicitly assume free-form Fortran +AC_LANG(Fortran) +AC_FC_SRCEXT(f90) + + +# Determine MPI compiler wrappers +# NOTE: +# - AX_MPI invokes AC_PROG_FC, often with gfortran, even if the MPI launcher +# does not use gfortran. +# - This can cause standard AC_PROG_FC tests to fail if FCFLAGS is configured +# with flags from another compiler. +# - I do not yet know how to resolve this possible issue. +AX_MPI([], + [AC_MSG_ERROR([Could not find MPI launcher.])]) + + +# Explicitly replace FC and LD with MPI wrappers +# NOTE: This is yet another attempt to manage the potential mismatches between +# FC and MPIFC. Without this step, the tests below would not use MPIFC. +AC_SUBST(FC, $MPIFC) +AC_SUBST(LD, $MPIFC) + +# Confirm that FC can see the Fortran 90 MPI module. +AX_FC_CHECK_MODULE([mpi], + [], [AC_MSG_ERROR([Could not find MPI Fortran module.])]) + + +# netCDF configuration +AC_PATH_PROG([NC_CONFIG], [nc-config]) +AS_IF([test -n "$NC_CONFIG"], + [CPPFLAGS="$CPPFLAGS -I$($NC_CONFIG --includedir)" + FCFLAGS="$FCFLAGS -I$($NC_CONFIG --includedir)" + LDFLAGS="$LDFLAGS -L$($NC_CONFIG --libdir)"], + [AC_MSG_ERROR([Could not find nc-config.])]) + +AX_FC_CHECK_MODULE([netcdf], + [], [AC_MSG_ERROR([Could not find FMS library.])]) +AX_FC_CHECK_LIB([netcdff], [nf_create], [netcdf], + [], [AC_MSG_ERROR([Could not link netcdff library.])] +) + + +# Force 8-byte reals +AX_FC_REAL8 +AS_IF( + [test "$enable_real8" != no], + [FCFLAGS="$FCFLAGS $REAL8_FCFLAGS"]) + + +# OpenMP configuration +AC_OPENMP +AS_IF( + [test "$enable_openmp" = yes], + [FCFLAGS="$FCFLAGS $OPENMP_FCFLAGS" + LDFLAGS="$LDFLAGS $OPENMP_FCFLAGS"]) + + +# FMS support + +# Test for fms_mod to verify FMS module access +AX_FC_CHECK_MODULE([fms_mod], [], [ + AS_UNSET([ax_fc_cv_mod_fms_mod]) + AX_FC_CHECK_MODULE([fms_mod], + [AC_SUBST([FCFLAGS], ["-I${srcdir}/deps/include $FCFLAGS"])], + [AC_MSG_ERROR([Could not find fms_mod Fortran module.])], + [-I${srcdir}/deps/include]) +]) + +# Test for fms_init to verify FMS library linking +AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], + [], [ + AS_UNSET([ax_fc_cv_lib_FMS_fms_init]) + AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], [ + AC_SUBST([LDFLAGS], ["-L${srcdir}/deps/lib $LDFLAGS"]) + AC_SUBST([LIBS], ["-lFMS $LIBS"]) + ], + [AC_MSG_ERROR([Could not find FMS library.])], + [-L${srcdir}/deps/lib]) + ] +) + + +# Search for mkmf build tools +AC_PATH_PROG([LIST_PATHS], [list_paths]) +AS_IF([test -z "$LIST_PATHS"], [ + AC_PATH_PROG([LIST_PATHS], [list_paths], [], ["$PATH:${srcdir}/deps/bin"]) + AS_IF([test -z "$LIST_PATHS"], + [AC_MSG_ERROR([Could not find list_paths.])], + [AC_SUBST(PATH, ["$PATH:${srcdir}/deps/bin"])]) + ] +) + +AC_PATH_PROG([MKMF], [mkmf]) +AS_IF([test -z "$MKMF"], [ + AC_PATH_PROG([MKMF], [mkmf], [], ["$PATH:${srcdir}/deps/bin"]) + AS_IF([test -z "$MKMF"], + [AC_MSG_ERROR([Could not find mkmf.])], + [AC_SUBST(PATH, ["$PATH:${srcdir}/deps/bin"])]) + ] +) + + +# NOTE: MEM_LAYOUT unneeded if we shift to MOM_memory.h.in template +AC_CONFIG_COMMANDS([path_names], + [list_paths -l \ + ${srcdir}/src \ + ${srcdir}/config_src/solo_driver \ + ${srcdir}/config_src/ext* \ + ${MEM_LAYOUT} +], [MEM_LAYOUT=$MEM_LAYOUT]) + + +AC_CONFIG_COMMANDS([Makefile.mkmf], + [mkmf -p MOM6 -m Makefile.mkmf path_names]) + + +# Prepare output +AC_SUBST(CPPFLAGS) +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/deps/.gitignore b/deps/.gitignore new file mode 100644 index 0000000000..8cfaa6ebcb --- /dev/null +++ b/deps/.gitignore @@ -0,0 +1,5 @@ +/bin/ +/fms/ +/include/ +/lib/ +/mkmf/ diff --git a/deps/Makefile b/deps/Makefile new file mode 100644 index 0000000000..f0a06071b1 --- /dev/null +++ b/deps/Makefile @@ -0,0 +1,94 @@ +SHELL = bash +.SUFFIXES: + +# FMS build configuration +# TODO: Include FC? +FCFLAGS_FMS ?= + +# Only set FCFLAGS if an argument is provided. +FCFLAGS_ENV = +ifneq ($(FCFLAGS_FMS),) + FCFLAGS_ENV := FCFLAGS="$(FCFLAGS_FMS)" +endif + + +# mkmf, list_paths (GFDL build toolchain) +MKMF_URL ?= https://github.com/NOAA-GFDL/mkmf.git +MKMF_COMMIT ?= master + +# FMS framework +FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git +FMS_COMMIT ?= 2019.01.03 + + +# List of source files to link this Makefile's dependencies to model Makefiles +# Assumes a depth of two, and the following extensions: F90 inc c h +# (1): Root directory +# NOTE: extensions could be a second variable +SOURCE = \ + $(foreach ext,F90 inc c h,$(wildcard $(1)/*/*.$(ext) $(1)/*/*/*.$(ext))) + +FMS_SOURCE = $(call SOURCE,fms/src) + + +#--- +# Rules + +.PHONY: all +all: bin/mkmf bin/list_paths lib/libFMS.a + + +#--- +# mkmf checkout + +bin/mkmf bin/list_paths: mkmf + mkdir -p $(@D) + cp $^/$@ $@ + +mkmf: + git clone $(MKMF_URL) $@ + git -C $@ checkout $(MKMF_COMMIT) + + +#--- +# FMS build + +# NOTE: We emulate the automake `make install` stage by storing libFMS.a to +# ${srcdir}/deps/lib and copying module files to ${srcdir}/deps/include. +# This is a flawed approach, since module files are untracked and could be +# handled more safely, but this is adequate for now. + +# TODO: track *.mod copy? +lib/libFMS.a: fms/build/Makefile + mkdir -p {lib,include} + cd fms/build && $(MAKE) -j ../../lib/libFMS.a + cp fms/build/*.mod include + + +# TODO: Include FC, CC, CFLAGS? +fms/build/Makefile: FC_ENV=$(FCFLAGS_ENV) + +fms/build/Makefile: fms/src/configure bin/mkmf bin/list_paths + mkdir -p fms/build + cd $(@D) && $(FC_ENV) ../src/configure --srcdir=../src + + +# TODO: Track m4 macros? +fms/src/configure: fms/src configure.fms.ac Makefile.fms.in $(FMS_SOURCE) + cp configure.fms.ac $ +# Copyright (c) 2008 Julian C. Cummings +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 9 + +AU_ALIAS([ACX_MPI], [AX_MPI]) +AC_DEFUN([AX_MPI], [ +AC_PREREQ(2.50) dnl for AC_LANG_CASE + +AC_LANG_CASE([C], [ + AC_REQUIRE([AC_PROG_CC]) + AC_ARG_VAR(MPICC,[MPI C compiler command]) + AC_CHECK_PROGS(MPICC, mpicc cc hcc mpxlc_r mpxlc mpcc cmpicc, $CC) + ax_mpi_save_CC="$CC" + CC="$MPICC" + AC_SUBST(MPICC) +], +[C++], [ + AC_REQUIRE([AC_PROG_CXX]) + AC_ARG_VAR(MPICXX,[MPI C++ compiler command]) + AC_CHECK_PROGS(MPICXX, mpic++ mpicxx mpiCC hcp mpxlC_r mpxlC mpCC cmpic++, $CXX) + ax_mpi_save_CXX="$CXX" + CXX="$MPICXX" + AC_SUBST(MPICXX) +], +[Fortran 77], [ + AC_REQUIRE([AC_PROG_F77]) + AC_ARG_VAR(MPIF77,[MPI Fortran 77 compiler command]) + AC_CHECK_PROGS(MPIF77, mpif77 hf77 mpxlf_r mpxlf mpf77 cmpifc, $F77) + ax_mpi_save_F77="$F77" + F77="$MPIF77" + AC_SUBST(MPIF77) +], +[Fortran], [ + AC_REQUIRE([AC_PROG_FC]) + AC_ARG_VAR(MPIFC,[MPI Fortran compiler command]) + AC_CHECK_PROGS(MPIFC, mpifort mpif90 ftn mpxlf95_r mpxlf90_r mpxlf95 mpxlf90 mpf90 cmpif90c, $FC) + ax_mpi_save_FC="$FC" + FC="$MPIFC" + AC_SUBST(MPIFC) +]) + +if test x = x"$MPILIBS"; then + AC_LANG_CASE([C], [AC_CHECK_FUNC(MPI_Init, [MPILIBS=" "])], + [C++], [AC_CHECK_FUNC(MPI_Init, [MPILIBS=" "])], + [Fortran 77], [AC_MSG_CHECKING([for MPI_Init]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[ call MPI_Init])],[MPILIBS=" " + AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])], + [Fortran], [AC_MSG_CHECKING([for MPI_Init]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[ call MPI_Init])],[MPILIBS=" " + AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])]) +fi +AC_LANG_CASE([Fortran 77], [ + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(fmpi, MPI_Init, [MPILIBS="-lfmpi"]) + fi + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(fmpich, MPI_Init, [MPILIBS="-lfmpich"]) + fi +], +[Fortran], [ + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(fmpi, MPI_Init, [MPILIBS="-lfmpi"]) + fi + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(mpichf90, MPI_Init, [MPILIBS="-lmpichf90"]) + fi +]) +if test x = x"$MPILIBS"; then + AC_CHECK_LIB(mpi, MPI_Init, [MPILIBS="-lmpi"]) +fi +if test x = x"$MPILIBS"; then + AC_CHECK_LIB(mpich, MPI_Init, [MPILIBS="-lmpich"]) +fi + +dnl We have to use AC_TRY_COMPILE and not AC_CHECK_HEADER because the +dnl latter uses $CPP, not $CC (which may be mpicc). +AC_LANG_CASE([C], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpi.h]) + AC_TRY_COMPILE([#include ],[],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi], +[C++], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpi.h]) + AC_TRY_COMPILE([#include ],[],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi], +[Fortran 77], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpif.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[ include 'mpif.h'])],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi], +[Fortran], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpif.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[ include 'mpif.h'])],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi]) + +AC_LANG_CASE([C], [CC="$ax_mpi_save_CC"], + [C++], [CXX="$ax_mpi_save_CXX"], + [Fortran 77], [F77="$ax_mpi_save_F77"], + [Fortran], [FC="$ax_mpi_save_FC"]) + +AC_SUBST(MPILIBS) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x = x"$MPILIBS"; then + $2 + : +else + ifelse([$1],,[AC_DEFINE(HAVE_MPI,1,[Define if you have the MPI library.])],[$1]) + : +fi +])dnl AX_MPI From f6248cb7c68848acc09cd8a16e03d1253c29791c Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 2 Sep 2020 11:04:51 -0400 Subject: [PATCH 02/23] Minor gitignore update --- .gitignore | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 8a79222df4..ccaecbbead 100644 --- a/.gitignore +++ b/.gitignore @@ -2,14 +2,19 @@ *.swp *~ html -*.log + + +# Build output +*.o +*.mod MOM6 + # Autoconf -/aclocal.m4 -/autom4te.cache/ -/config.log -/config.status -/configure +aclocal.m4 +autom4te.cache/ +config.log +config.status +configure /Makefile -/Makefile.mkmf +Makefile.mkmf From 12a83f79d1c36424b8eac934ac806380b4582842 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 2 Sep 2020 12:12:50 -0400 Subject: [PATCH 03/23] Autoconf: Coverage and target LDFLAGS fixes Minor fixes which include the FCFLAGS coverage flag into LDFLAGS for gcov builds, as well as properly moving the target -L flag out of FCFLAGS and into LDFLAGS. --- .testing/Makefile | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.testing/Makefile b/.testing/Makefile index dd0db892ac..0d9f9d84e2 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -17,7 +17,7 @@ FCFLAGS_DEBUG ?= -g -O0 FCFLAGS_REPRO ?= -g -O2 FCFLAGS_INIT ?= FCFLAGS_COVERAGE ?= -# Addtional notes: +# Additional notes: # # - The default values are simple, minimalist flags, supported by nearly all # compilers and meant to represent GFDL's canonical DEBUG and REPRO builds. @@ -137,11 +137,14 @@ BUILD_TARGETS = MOM6 Makefile path_names # Conditionally build symmetric with coverage support COVERAGE=$(if $(REPORT_COVERAGE),"$(FCFLAGS_COVERAGE)",) +# Explicit FMS link to target build # TODO: We should probably build TARGET with the FMS that it was configured # to use. But for now we use the same FMS over all builds. -FCFLAGS_TARGET_FMS = -I../../../deps/include -L../../../deps/lib +FCFLAGS_TARGET_FMS = -I../../../deps/include +LDFLAGS_TARGET_FMS = -L../../../deps/lib PATH_TARGET = PATH="${PATH}:../../../deps/bin" + # Define the build targets in terms of the traditional DEBUG/REPRO/etc labels FCFLAGS_SYMMETRIC = ifneq ($(FCFLAGS_DEBUG)$(FCFLAGS_INIT)$(COVERAGE),) @@ -155,6 +158,8 @@ ifneq ($(FCFLAGS_DEBUG)$(FCFLAGS_INIT),) FCFLAGS_TARGET := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(FCFLAGS_TARGET_FMS)" FCFLAGS_ASYMMETRIC := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT)" FCFLAGS_OPENMP := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT)" +else + FCFLAGS_TARGET := FCFLAGS="$(FCFLAGS_TARGET_FMS)" endif FCFLAGS_REPRO_RUN = @@ -162,13 +167,19 @@ ifneq ($(FCFLAGS_REPRO),) FCFLAGS_REPRO_RUN := FCFLAGS="$(FCFLAGS_REPRO)" endif +LDFLAGS_SYMMETRIC = +ifneq ($(COVERAGE),) + LDFLAGS_SYMMETRIC := LDFLAGS="$(COVERAGE)" +endif +LDFLAGS_TARGET := LDFLAGS="$(LDFLAGS_TARGET_FMS)" + # Environment variable configuration -build/symmetric/Makefile: FC_ENV=$(FCFLAGS_SYMMETRIC) +build/symmetric/Makefile: FC_ENV=$(FCFLAGS_SYMMETRIC) $(LDFLAGS_SYMMETRIC) build/asymmetric/Makefile: FC_ENV=$(FCFLAGS_ASYMMETRIC) build/repro/Makefile: FC_ENV=$(FCFLAGS_REPRO_RUN) build/openmp/Makefile: FC_ENV=$(FCFLAGS_OPENMP) -build/target/Makefile: FC_ENV=$(FCFLAGS_TARGET) $(PATH_TARGET) +build/target/Makefile: FC_ENV=$(FCFLAGS_TARGET) $(LDFLAGS_TARGET) $(PATH_TARGET) # Configure script flags From bde93fb2502745916c8b69795037f6c5195aaee1 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 2 Sep 2020 14:07:50 -0400 Subject: [PATCH 04/23] Testing: Adding message to report codecov report upload --- .testing/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.testing/Makefile b/.testing/Makefile index 0d9f9d84e2..a15994a58b 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -298,6 +298,7 @@ run.openmp: $(foreach c,$(CONFIGS),work/$(c)/openmp/ocean.stats) # Color highlights for test results RED=\033[0;31m GREEN=\033[0;32m +MAGENTA=\033[0;35m RESET=\033[0m DONE=${GREEN}DONE${RESET} @@ -391,7 +392,8 @@ work/%/$(1)/ocean.stats work/%/$(1)/chksum_diag: build/$(2)/MOM6 mkdir -p results/$$* ; \ bash <(curl -s https://codecov.io/bash) -n $$@ \ > work/$$*/codecov.$(1).out \ - 2> work/$$*/codecov.$(1).err ; \ + 2> work/$$*/codecov.$(1).err \ + && echo -e "${MAGENTA}Report uploaded to codecov.${RESET}"; \ fi endef From ff451d700eaf5a82d39ef2ab755711c6191a7118 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 2 Sep 2020 17:50:44 -0400 Subject: [PATCH 05/23] Travis: Environment variable globals; Timer log Several build environment variables were redefined globally to be used across all jobs, rather than repeating over every job. The timer output was also redefined to be single line, rather than four, to reduce logging output. --- .travis.yml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 89a91d34b4..0dc3d1edf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,15 @@ addons: - python3 python3-dev python3-venv python3-pip - bc +# Environment variables +env: + global: + - TIMEFORMAT: "Time: %lR (user: %lU, sys: %lS)" + - FCFLAGS_DEBUG: "-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" + - FCFLAGS_REPRO: "-g -O2 -fbacktrace" + - FCFLAGS_INIT: "-finit-real=snan -finit-integer=2147483647 -finit-derived" + - FCFLAGS_COVERAGE: "--coverage" + jobs: include: - env: JOB="Code compliance" @@ -29,12 +38,8 @@ jobs: - test ! -s doxy_errors - env: - - JOB="x86 Configuration testing" + - JOB="x86 verification testing" - DO_REGRESSION_TESTS=false - - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" - - FCFLAGS_REPRO="-g -O2 -fbacktrace" - - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" - - FCFLAGS_COVERAGE="--coverage" script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' @@ -53,10 +58,6 @@ jobs: - REPORT_COVERAGE=true - MOM_TARGET_SLUG=${TRAVIS_REPO_SLUG} - MOM_TARGET_LOCAL_BRANCH=${TRAVIS_BRANCH} - - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" - - FCFLAGS_REPRO="-g -O2 -fbacktrace" - - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" - - FCFLAGS_COVERAGE="--coverage" script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' @@ -70,7 +71,6 @@ jobs: - JOB="Coverage upload" - REPORT_COVERAGE=true - DO_REGRESSION_TESTS=false - - MKMF_TEMPLATE=linux-ubuntu-xenial-gnu.mk script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' @@ -80,13 +80,9 @@ jobs: - arch: arm64 env: - - JOB="ARM64 Configuration testing" + - JOB="ARM64 verification testing" - DO_REGRESSION_TESTS=false - DO_REPRO_TESTS=false - - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" - - FCFLAGS_REPRO="-g -O2 -fbacktrace" - - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" - - FCFLAGS_COVERAGE="--coverage" script: - cd .testing - echo 'Build executables...' && echo -en 'travis_fold:start:script.1\\r' From d186229a4389feabaa4ba2b57e171f3622aae34e Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 2 Sep 2020 18:55:06 -0400 Subject: [PATCH 06/23] Travis: Fixing global environment variables --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0dc3d1edf1..3fd729f8d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,11 +20,11 @@ addons: # Environment variables env: global: - - TIMEFORMAT: "Time: %lR (user: %lU, sys: %lS)" - - FCFLAGS_DEBUG: "-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" - - FCFLAGS_REPRO: "-g -O2 -fbacktrace" - - FCFLAGS_INIT: "-finit-real=snan -finit-integer=2147483647 -finit-derived" - - FCFLAGS_COVERAGE: "--coverage" + - TIMEFORMAT="Time: %lR (user: %lU, sys: %lS)" + - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" + - FCFLAGS_REPRO="-g -O2 -fbacktrace" + - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" + - FCFLAGS_COVERAGE="--coverage" jobs: include: From 2a5e3005ed07df4a91de72060c2f7500e0fd83cb Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 9 Sep 2020 14:07:57 -0400 Subject: [PATCH 07/23] Moving autoconf tools to /ac directory Because autoconf can cause fear and anger in some users, the configuration files have now been delegated to a subdirectory, ac, which can be invoked from an arbitrary directory. This required some unconventional constructs in the file, but they have luckily been relegated to a few introductory statements, and the bulk of the code is unchanged. The only pervasive change is the explicit references to the ac directory, particularly ac/deps. .testing also had to be updated to accommodate the autoconf changes. --- .testing/Makefile | 21 ++++++------ Makefile.in => ac/Makefile.in | 0 configure.ac => ac/configure.ac | 40 ++++++++++++++++------- {deps => ac/deps}/.gitignore | 0 {deps => ac/deps}/Makefile | 0 {deps => ac/deps}/Makefile.fms.in | 0 {deps => ac/deps}/configure.fms.ac | 0 {m4 => ac/m4}/ax_fc_allow_arg_mismatch.m4 | 0 {m4 => ac/m4}/ax_fc_allow_invalid_boz.m4 | 0 {m4 => ac/m4}/ax_fc_check_lib.m4 | 0 {m4 => ac/m4}/ax_fc_check_module.m4 | 0 {m4 => ac/m4}/ax_fc_cray_pointer.m4 | 0 {m4 => ac/m4}/ax_fc_real8.m4 | 0 {m4 => ac/m4}/ax_mpi.m4 | 0 14 files changed, 40 insertions(+), 21 deletions(-) rename Makefile.in => ac/Makefile.in (100%) rename configure.ac => ac/configure.ac (75%) rename {deps => ac/deps}/.gitignore (100%) rename {deps => ac/deps}/Makefile (100%) rename {deps => ac/deps}/Makefile.fms.in (100%) rename {deps => ac/deps}/configure.fms.ac (100%) rename {m4 => ac/m4}/ax_fc_allow_arg_mismatch.m4 (100%) rename {m4 => ac/m4}/ax_fc_allow_invalid_boz.m4 (100%) rename {m4 => ac/m4}/ax_fc_check_lib.m4 (100%) rename {m4 => ac/m4}/ax_fc_check_module.m4 (100%) rename {m4 => ac/m4}/ax_fc_cray_pointer.m4 (100%) rename {m4 => ac/m4}/ax_fc_real8.m4 (100%) rename {m4 => ac/m4}/ax_mpi.m4 (100%) diff --git a/.testing/Makefile b/.testing/Makefile index a15994a58b..c91dcc0a97 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -31,7 +31,7 @@ FCFLAGS_COVERAGE ?= #--- # Dependencies -DEPS = ../deps +DEPS = ../ac/deps # mkmf, list_paths (GFDL build toolchain) LIST_PATHS := $(DEPS)/bin/list_paths @@ -140,9 +140,9 @@ COVERAGE=$(if $(REPORT_COVERAGE),"$(FCFLAGS_COVERAGE)",) # Explicit FMS link to target build # TODO: We should probably build TARGET with the FMS that it was configured # to use. But for now we use the same FMS over all builds. -FCFLAGS_TARGET_FMS = -I../../../deps/include -LDFLAGS_TARGET_FMS = -L../../../deps/lib -PATH_TARGET = PATH="${PATH}:../../../deps/bin" +FCFLAGS_TARGET_FMS = -I../../$(DEPS)/include +LDFLAGS_TARGET_FMS = -L../../$(DEPS)/lib +PATH_TARGET = PATH="${PATH}:../../$(DEPS)/bin" # Define the build targets in terms of the traditional DEBUG/REPRO/etc labels @@ -209,14 +209,15 @@ build/%/MOM6: build/%/Makefile # Use autoconf to construct the Makefile for each target .PRECIOUS: $(foreach b,$(BUILDS),build/$(b)/Makefile) -build/%/Makefile: ../configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) +build/%/Makefile: ../ac/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) cd $(@D) \ - && $(FC_ENV) ../../../configure $(AC_FLAGS) \ + && $(FC_ENV) ../../../ac/configure $(AC_FLAGS) \ || (cat config.log && false) -../configure: ../configure.ac ../Makefile.in ../m4 +# TODO: Replace m4 with *.m4 macros +../ac/configure: ../ac/configure.ac ../ac/Makefile.in ../ac/m4 autoreconf -i $< @@ -236,9 +237,9 @@ $(TARGET_CODEBASE): git clone --recursive $(MOM_TARGET_URL) $@ cd $@ && git checkout $(MOM_TARGET_BRANCH) # Copy modern autoconf files to target? - cp ../configure.ac $(TARGET_CODEBASE)/ - cp ../Makefile.in $(TARGET_CODEBASE)/ - cp -r ../m4 $(TARGET_CODEBASE)/ + cp ../ac/configure.ac $(TARGET_CODEBASE)/ + cp ../ac/Makefile.in $(TARGET_CODEBASE)/ + cp -r ../ac/m4 $(TARGET_CODEBASE)/ # FMS diff --git a/Makefile.in b/ac/Makefile.in similarity index 100% rename from Makefile.in rename to ac/Makefile.in diff --git a/configure.ac b/ac/configure.ac similarity index 75% rename from configure.ac rename to ac/configure.ac index 2da14c1381..73340ba250 100644 --- a/configure.ac +++ b/ac/configure.ac @@ -15,9 +15,26 @@ AC_INIT( [], [https://github.com/NOAA-GFDL/MOM6]) +#--- +# NOTE: For the autoconf-adverse, the configuration files and autoreconf output +# are kept in the `ac` directory. +# +# This breaks the convention where configure.ac resides in the top directory. +# +# As a result, $srcdir initially points to the `ac` directory, rather than the +# top directory of the codebase. +# +# In order to balance this, we up-path (../) srcdir and point AC_CONFIG_SRCDIR +# to srcdir and point AC_CONFIG_SRCDIR to the parent directory. +# +# Someday we may revert this and work from the top-level directory. But for +# now we will compartment autoconf to a subdirectory. +#--- + # Validate srdcir and configure input -AC_CONFIG_SRCDIR([src/core/MOM.F90]) +AC_CONFIG_SRCDIR([../src/core/MOM.F90]) AC_CONFIG_MACRO_DIR([m4]) +srcdir=$srcdir/.. # Default to asymmetric grid @@ -30,7 +47,8 @@ AS_IF([test "$enable_symmetric" = yes], [MEM_LAYOUT=${srcdir}/config_src/dynamic_symmetric]) -## TODO: Support a user-defined memory header +# TODO: Rather than point to a pre-configured header file, autoconf could be +# used to configure a header based on a template. #AC_CONFIG_HEADERS(["$MEM_LAYOUT/MOM_memory.h"]) @@ -97,9 +115,9 @@ AS_IF( AX_FC_CHECK_MODULE([fms_mod], [], [ AS_UNSET([ax_fc_cv_mod_fms_mod]) AX_FC_CHECK_MODULE([fms_mod], - [AC_SUBST([FCFLAGS], ["-I${srcdir}/deps/include $FCFLAGS"])], + [AC_SUBST([FCFLAGS], ["-I${srcdir}/ac/deps/include $FCFLAGS"])], [AC_MSG_ERROR([Could not find fms_mod Fortran module.])], - [-I${srcdir}/deps/include]) + [-I${srcdir}/ac/deps/include]) ]) # Test for fms_init to verify FMS library linking @@ -107,11 +125,11 @@ AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], [], [ AS_UNSET([ax_fc_cv_lib_FMS_fms_init]) AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], [ - AC_SUBST([LDFLAGS], ["-L${srcdir}/deps/lib $LDFLAGS"]) + AC_SUBST([LDFLAGS], ["-L${srcdir}/ac/deps/lib $LDFLAGS"]) AC_SUBST([LIBS], ["-lFMS $LIBS"]) ], [AC_MSG_ERROR([Could not find FMS library.])], - [-L${srcdir}/deps/lib]) + [-L${srcdir}/ac/deps/lib]) ] ) @@ -119,19 +137,19 @@ AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], # Search for mkmf build tools AC_PATH_PROG([LIST_PATHS], [list_paths]) AS_IF([test -z "$LIST_PATHS"], [ - AC_PATH_PROG([LIST_PATHS], [list_paths], [], ["$PATH:${srcdir}/deps/bin"]) + AC_PATH_PROG([LIST_PATHS], [list_paths], [], ["$PATH:${srcdir}/ac/deps/bin"]) AS_IF([test -z "$LIST_PATHS"], [AC_MSG_ERROR([Could not find list_paths.])], - [AC_SUBST(PATH, ["$PATH:${srcdir}/deps/bin"])]) + [AC_SUBST(PATH, ["$PATH:${srcdir}/ac/deps/bin"])]) ] ) AC_PATH_PROG([MKMF], [mkmf]) AS_IF([test -z "$MKMF"], [ - AC_PATH_PROG([MKMF], [mkmf], [], ["$PATH:${srcdir}/deps/bin"]) + AC_PATH_PROG([MKMF], [mkmf], [], ["$PATH:${srcdir}/ac/deps/bin"]) AS_IF([test -z "$MKMF"], [AC_MSG_ERROR([Could not find mkmf.])], - [AC_SUBST(PATH, ["$PATH:${srcdir}/deps/bin"])]) + [AC_SUBST(PATH, ["$PATH:${srcdir}/ac/deps/bin"])]) ] ) @@ -152,5 +170,5 @@ AC_CONFIG_COMMANDS([Makefile.mkmf], # Prepare output AC_SUBST(CPPFLAGS) -AC_CONFIG_FILES(Makefile) +AC_CONFIG_FILES([Makefile:${srcdir}/ac/Makefile.in]) AC_OUTPUT diff --git a/deps/.gitignore b/ac/deps/.gitignore similarity index 100% rename from deps/.gitignore rename to ac/deps/.gitignore diff --git a/deps/Makefile b/ac/deps/Makefile similarity index 100% rename from deps/Makefile rename to ac/deps/Makefile diff --git a/deps/Makefile.fms.in b/ac/deps/Makefile.fms.in similarity index 100% rename from deps/Makefile.fms.in rename to ac/deps/Makefile.fms.in diff --git a/deps/configure.fms.ac b/ac/deps/configure.fms.ac similarity index 100% rename from deps/configure.fms.ac rename to ac/deps/configure.fms.ac diff --git a/m4/ax_fc_allow_arg_mismatch.m4 b/ac/m4/ax_fc_allow_arg_mismatch.m4 similarity index 100% rename from m4/ax_fc_allow_arg_mismatch.m4 rename to ac/m4/ax_fc_allow_arg_mismatch.m4 diff --git a/m4/ax_fc_allow_invalid_boz.m4 b/ac/m4/ax_fc_allow_invalid_boz.m4 similarity index 100% rename from m4/ax_fc_allow_invalid_boz.m4 rename to ac/m4/ax_fc_allow_invalid_boz.m4 diff --git a/m4/ax_fc_check_lib.m4 b/ac/m4/ax_fc_check_lib.m4 similarity index 100% rename from m4/ax_fc_check_lib.m4 rename to ac/m4/ax_fc_check_lib.m4 diff --git a/m4/ax_fc_check_module.m4 b/ac/m4/ax_fc_check_module.m4 similarity index 100% rename from m4/ax_fc_check_module.m4 rename to ac/m4/ax_fc_check_module.m4 diff --git a/m4/ax_fc_cray_pointer.m4 b/ac/m4/ax_fc_cray_pointer.m4 similarity index 100% rename from m4/ax_fc_cray_pointer.m4 rename to ac/m4/ax_fc_cray_pointer.m4 diff --git a/m4/ax_fc_real8.m4 b/ac/m4/ax_fc_real8.m4 similarity index 100% rename from m4/ax_fc_real8.m4 rename to ac/m4/ax_fc_real8.m4 diff --git a/m4/ax_mpi.m4 b/ac/m4/ax_mpi.m4 similarity index 100% rename from m4/ax_mpi.m4 rename to ac/m4/ax_mpi.m4 From ffeb747ed0d4d0ade97db4873cb3e7644156d0f8 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 9 Sep 2020 16:37:59 -0400 Subject: [PATCH 08/23] Autoconf: FMS build adjustment Modified FMS to build libFMS.a in its build directory, rather than to just target the eventual destination of it (../../lib/libFMS.a). This is because other builds (particularly .testing) may prefer a different destination. --- ac/deps/Makefile | 6 ++++-- ac/deps/Makefile.fms.in | 3 +++ ac/deps/configure.fms.ac | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ac/deps/Makefile b/ac/deps/Makefile index f0a06071b1..6571a4b8db 100644 --- a/ac/deps/Makefile +++ b/ac/deps/Makefile @@ -59,11 +59,13 @@ mkmf: # handled more safely, but this is adequate for now. # TODO: track *.mod copy? -lib/libFMS.a: fms/build/Makefile +lib/libFMS.a: fms/build/libFMS.a fms/build/Makefile mkdir -p {lib,include} - cd fms/build && $(MAKE) -j ../../lib/libFMS.a + cp fms/build/libFMS.a lib/libFMS.a cp fms/build/*.mod include +fms/build/libFMS.a: fms/build/Makefile + make -C fms/build libFMS.a # TODO: Include FC, CC, CFLAGS? fms/build/Makefile: FC_ENV=$(FCFLAGS_ENV) diff --git a/ac/deps/Makefile.fms.in b/ac/deps/Makefile.fms.in index 7fda994c8c..694ad8e0b0 100644 --- a/ac/deps/Makefile.fms.in +++ b/ac/deps/Makefile.fms.in @@ -42,4 +42,7 @@ CPPFLAGS = @CPPFLAGS@ FFLAGS = @FCFLAGS@ LDFLAGS = @LDFLAGS@ +# Gather modulefiles +TMPFILES = $(wildcard *.mod) + include Makefile.mkmf diff --git a/ac/deps/configure.fms.ac b/ac/deps/configure.fms.ac index 7b7e6748bf..76bb39bf31 100644 --- a/ac/deps/configure.fms.ac +++ b/ac/deps/configure.fms.ac @@ -113,7 +113,7 @@ AC_CONFIG_COMMANDS([path_names], AC_CONFIG_COMMANDS([mkmf], - [${MKMF} -p ../../lib/libFMS.a -m Makefile.mkmf path_names], + [${MKMF} -p libFMS.a -m Makefile.mkmf path_names], [MKMF=${MKMF}]) From 5fb8ea502781cc930d5714dcf08f8c67cf473e55 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Thu, 10 Sep 2020 22:59:50 -0400 Subject: [PATCH 09/23] Autoconf: .testing now builds its own FMS .testing no longer relies on the top-level ac/deps to build and hold its FMS repository. It now checks out its own source and builds its own FMS library exclusively for testing. Also fixed a few dependency bugs in the FMS makefile (and probably in .testing as well). Finally, the m4 macros for FMS were copied into deps, rather than sharing with the top-level m4 macros, allowing it to exist more independently. (I will prune the FMS-specific macros from ac/m4 in a future commit.) --- .testing/.gitignore | 1 + .testing/Makefile | 107 ++++++++------- ac/deps/Makefile | 36 +++-- ac/deps/configure.fms.ac | 1 - ac/deps/m4/ax_fc_allow_arg_mismatch.m4 | 58 ++++++++ ac/deps/m4/ax_fc_allow_invalid_boz.m4 | 54 ++++++++ ac/deps/m4/ax_fc_check_lib.m4 | 52 ++++++++ ac/deps/m4/ax_fc_check_module.m4 | 28 ++++ ac/deps/m4/ax_fc_cray_pointer.m4 | 53 ++++++++ ac/deps/m4/ax_fc_real8.m4 | 86 ++++++++++++ ac/deps/m4/ax_mpi.m4 | 176 +++++++++++++++++++++++++ 11 files changed, 588 insertions(+), 64 deletions(-) create mode 100644 ac/deps/m4/ax_fc_allow_arg_mismatch.m4 create mode 100644 ac/deps/m4/ax_fc_allow_invalid_boz.m4 create mode 100644 ac/deps/m4/ax_fc_check_lib.m4 create mode 100644 ac/deps/m4/ax_fc_check_module.m4 create mode 100644 ac/deps/m4/ax_fc_cray_pointer.m4 create mode 100644 ac/deps/m4/ax_fc_real8.m4 create mode 100644 ac/deps/m4/ax_mpi.m4 diff --git a/.testing/.gitignore b/.testing/.gitignore index ec8eae6348..488edabfe8 100644 --- a/.testing/.gitignore +++ b/.testing/.gitignore @@ -3,3 +3,4 @@ /build/ /work/ /results/ +/deps/ diff --git a/.testing/Makefile b/.testing/Makefile index c91dcc0a97..299bcad730 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -31,7 +31,7 @@ FCFLAGS_COVERAGE ?= #--- # Dependencies -DEPS = ../ac/deps +DEPS = deps # mkmf, list_paths (GFDL build toolchain) LIST_PATHS := $(DEPS)/bin/list_paths @@ -137,60 +137,43 @@ BUILD_TARGETS = MOM6 Makefile path_names # Conditionally build symmetric with coverage support COVERAGE=$(if $(REPORT_COVERAGE),"$(FCFLAGS_COVERAGE)",) -# Explicit FMS link to target build +# .testing dependencies # TODO: We should probably build TARGET with the FMS that it was configured # to use. But for now we use the same FMS over all builds. -FCFLAGS_TARGET_FMS = -I../../$(DEPS)/include -LDFLAGS_TARGET_FMS = -L../../$(DEPS)/lib -PATH_TARGET = PATH="${PATH}:../../$(DEPS)/bin" +FCFLAGS_FMS = -I../../$(DEPS)/include +LDFLAGS_FMS = -L../../$(DEPS)/lib +PATH_FMS = PATH="${PATH}:../../$(DEPS)/bin" # Define the build targets in terms of the traditional DEBUG/REPRO/etc labels -FCFLAGS_SYMMETRIC = -ifneq ($(FCFLAGS_DEBUG)$(FCFLAGS_INIT)$(COVERAGE),) - FCFLAGS_SYMMETRIC := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(COVERAGE)" -endif +SYMMETRIC_FCFLAGS := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(COVERAGE) $(FCFLAGS_FMS)" +ASYMMETRIC_FCFLAGS := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(FCFLAGS_FMS)" +REPRO_FCFLAGS := FCFLAGS="$(FCFLAGS_REPRO) $(FCFLAGS_FMS)" +OPENMP_FCFLAGS := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(FCFLAGS_FMS)" +TARGET_FCFLAGS := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(FCFLAGS_FMS)" -FCFLAGS_TARGET = -FCFLAGS_ASYMMETRIC = -FCFLAGS_OPENMP = -ifneq ($(FCFLAGS_DEBUG)$(FCFLAGS_INIT),) - FCFLAGS_TARGET := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT) $(FCFLAGS_TARGET_FMS)" - FCFLAGS_ASYMMETRIC := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT)" - FCFLAGS_OPENMP := FCFLAGS="$(FCFLAGS_DEBUG) $(FCFLAGS_INIT)" -else - FCFLAGS_TARGET := FCFLAGS="$(FCFLAGS_TARGET_FMS)" -endif - -FCFLAGS_REPRO_RUN = -ifneq ($(FCFLAGS_REPRO),) - FCFLAGS_REPRO_RUN := FCFLAGS="$(FCFLAGS_REPRO)" -endif - -LDFLAGS_SYMMETRIC = -ifneq ($(COVERAGE),) - LDFLAGS_SYMMETRIC := LDFLAGS="$(COVERAGE)" -endif -LDFLAGS_TARGET := LDFLAGS="$(LDFLAGS_TARGET_FMS)" +MOM_LDFLAGS := LDFLAGS="$(LDFLAGS_FMS)" +SYMMETRIC_LDFLAGS := LDFLAGS="$(COVERAGE) $(LDFLAGS_FMS)" # Environment variable configuration -build/symmetric/Makefile: FC_ENV=$(FCFLAGS_SYMMETRIC) $(LDFLAGS_SYMMETRIC) -build/asymmetric/Makefile: FC_ENV=$(FCFLAGS_ASYMMETRIC) -build/repro/Makefile: FC_ENV=$(FCFLAGS_REPRO_RUN) -build/openmp/Makefile: FC_ENV=$(FCFLAGS_OPENMP) -build/target/Makefile: FC_ENV=$(FCFLAGS_TARGET) $(LDFLAGS_TARGET) $(PATH_TARGET) +build/symmetric/Makefile: MOM_ENV=$(PATH_FMS) $(SYMMETRIC_FCFLAGS) $(SYMMETRIC_LDFLAGS) +build/asymmetric/Makefile: MOM_ENV=$(PATH_FMS) $(ASYMMETRIC_FCFLAGS) $(MOM_LDFLAGS) +build/repro/Makefile: MOM_ENV=$(PATH_FMS) $(REPRO_FCFLAGS) $(MOM_LDFLAGS) +build/openmp/Makefile: MOM_ENV=$(PATH_FMS) $(OPENMP_FCFLAGS) $(MOM_LDFLAGS) +build/target/Makefile: MOM_ENV=$(PATH_FMS) $(TARGET_FCFLAGS) $(MOM_LDFLAGS) # Configure script flags -build/asymmetric/Makefile: AC_FLAGS= -build/openmp/Makefile: AC_FLAGS=--enable-symmetric --enable-openmp -build/target/Makefile: AC_FLAGS=--srcdir=../../$(TARGET_CODEBASE) --enable-symmetric -build/%/Makefile: AC_FLAGS=--enable-symmetric +build/symmetric/Makefile: MOM_ACFLAGS=--enable-symmetric +build/asymmetric/Makefile: MOM_ACFLAGS= +build/repro/Makefile: MOM_ACFLAGS=--enable-symmetric +build/openmp/Makefile: MOM_ACFLAGS=--enable-symmetric --enable-openmp +build/target/Makefile: MOM_ACFLAGS=--srcdir=../../$(TARGET_CODEBASE) --enable-symmetric # Fetch regression target source code -build/target/Makefile: $(TARGET_CODEBASE) +build/target/Makefile: | $(TARGET_CODEBASE) # Define source code dependencies @@ -209,23 +192,22 @@ build/%/MOM6: build/%/Makefile # Use autoconf to construct the Makefile for each target .PRECIOUS: $(foreach b,$(BUILDS),build/$(b)/Makefile) -build/%/Makefile: ../ac/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) +build/%/Makefile: ../ac/configure ../ac/Makefile.in $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) cd $(@D) \ - && $(FC_ENV) ../../../ac/configure $(AC_FLAGS) \ + && $(MOM_ENV) ../../../ac/configure $(MOM_ACFLAGS) \ || (cat config.log && false) -# TODO: Replace m4 with *.m4 macros -../ac/configure: ../ac/configure.ac ../ac/Makefile.in ../ac/m4 +../ac/configure: ../ac/configure.ac ../ac/m4 autoreconf -i $< # Fetch the regression target codebase -build/target/Makefile: $(TARGET_CODEBASE)/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) +build/target/Makefile: $(TARGET_CODEBASE)/configure build/fms/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) cd $(@D) \ - && $(FC_ENV) ../../$(TARGET_CODEBASE)/configure $(AC_FLAGS) \ + && $(MOM_ENV) ../../$(TARGET_CODEBASE)/configure $(MOM_ACFLAGS) \ || (cat config.log && false) @@ -242,17 +224,42 @@ $(TARGET_CODEBASE): cp -r ../ac/m4 $(TARGET_CODEBASE)/ +#--- # FMS -$(DEPS)/lib/libFMS.a: $(DEPS)/Makefile $(FMS_SOURCE) $(MKMF) $(LIST_PATHS) - FCFLAGS_FMS="$(FCFLAGS_DEBUG)" $(MAKE) -C $(DEPS) lib/libFMS.a +# TODO: *.mod dependencies? +$(DEPS)/lib/libFMS.a: $(DEPS)/fms/build/libFMS.a + $(MAKE) -C $(DEPS) lib/libFMS.a + +$(DEPS)/fms/build/libFMS.a: $(DEPS)/fms/build/Makefile + $(MAKE) -C $(DEPS) fms/build/libFMS.a + +$(DEPS)/fms/build/Makefile: $(DEPS)/fms/src/configure $(DEPS)/Makefile.fms.in $(MKMF) $(LIST_PATHS) + PATH_ENV="${PATH}:../../bin" FCFLAGS_ENV="$(FCFLAGS_DEBUG)" $(MAKE) -C $(DEPS) fms/build/Makefile + +$(DEPS)/Makefile.fms.in: ../ac/deps/Makefile.fms.in + cp $< $(DEPS) + +# TODO: m4 dependencies? +$(DEPS)/fms/src/configure: ../ac/deps/configure.fms.ac $(DEPS)/Makefile $(FMS_SOURCE) | $(DEPS)/fms/src + cp ../ac/deps/configure.fms.ac $(DEPS) + cp -r ../ac/deps/m4 $(DEPS) + $(MAKE) -C $(DEPS) fms/src/configure + +$(DEPS)/fms/src: $(DEPS)/Makefile + make -C $(DEPS) fms/src # mkmf $(MKMF) $(LIST_PATHS): $(DEPS)/mkmf + $(MAKE) -C $(DEPS) bin/$(@F) $(DEPS)/mkmf: $(DEPS)/Makefile - $(MAKE) -C $(DEPS) bin/$(@F) + $(MAKE) -C $(DEPS) mkmf +# Dependency init +$(DEPS)/Makefile: ../ac/deps/Makefile + mkdir -p $(@D) + cp $< $@ #--- # Python preprocessing @@ -266,7 +273,7 @@ work/local-env: && pip3 install numpy \ && pip3 install netCDF4 -#---- +#--- # Testing .PHONY: test diff --git a/ac/deps/Makefile b/ac/deps/Makefile index 6571a4b8db..91fe343047 100644 --- a/ac/deps/Makefile +++ b/ac/deps/Makefile @@ -2,13 +2,20 @@ SHELL = bash .SUFFIXES: # FMS build configuration -# TODO: Include FC? -FCFLAGS_FMS ?= +PATH_ENV ?= +FCFLAGS_ENV ?= # Only set FCFLAGS if an argument is provided. -FCFLAGS_ENV = -ifneq ($(FCFLAGS_FMS),) - FCFLAGS_ENV := FCFLAGS="$(FCFLAGS_FMS)" +FMS_FCFLAGS = +ifneq ($(FCFLAGS_ENV),) + FMS_FCFLAGS := FCFLAGS="$(FCFLAGS_ENV)" +endif + + +# Ditto for path +FMS_PATH = +ifneq ($(PATH_ENV),) + FMS_PATH := PATH="$(PATH_ENV)" endif @@ -64,25 +71,26 @@ lib/libFMS.a: fms/build/libFMS.a fms/build/Makefile cp fms/build/libFMS.a lib/libFMS.a cp fms/build/*.mod include + fms/build/libFMS.a: fms/build/Makefile make -C fms/build libFMS.a + # TODO: Include FC, CC, CFLAGS? -fms/build/Makefile: FC_ENV=$(FCFLAGS_ENV) +fms/build/Makefile: FMS_ENV=$(FMS_PATH) $(FMS_FCFLAGS) -fms/build/Makefile: fms/src/configure bin/mkmf bin/list_paths +fms/build/Makefile: Makefile.fms.in fms/src/configure bin/mkmf bin/list_paths mkdir -p fms/build - cd $(@D) && $(FC_ENV) ../src/configure --srcdir=../src + cp Makefile.fms.in fms/src/Makefile.in + cd $(@D) && $(FMS_ENV) ../src/configure --srcdir=../src # TODO: Track m4 macros? -fms/src/configure: fms/src configure.fms.ac Makefile.fms.in $(FMS_SOURCE) - cp configure.fms.ac $ +# Copyright (c) 2008 Julian C. Cummings +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 9 + +AU_ALIAS([ACX_MPI], [AX_MPI]) +AC_DEFUN([AX_MPI], [ +AC_PREREQ(2.50) dnl for AC_LANG_CASE + +AC_LANG_CASE([C], [ + AC_REQUIRE([AC_PROG_CC]) + AC_ARG_VAR(MPICC,[MPI C compiler command]) + AC_CHECK_PROGS(MPICC, mpicc cc hcc mpxlc_r mpxlc mpcc cmpicc, $CC) + ax_mpi_save_CC="$CC" + CC="$MPICC" + AC_SUBST(MPICC) +], +[C++], [ + AC_REQUIRE([AC_PROG_CXX]) + AC_ARG_VAR(MPICXX,[MPI C++ compiler command]) + AC_CHECK_PROGS(MPICXX, mpic++ mpicxx mpiCC hcp mpxlC_r mpxlC mpCC cmpic++, $CXX) + ax_mpi_save_CXX="$CXX" + CXX="$MPICXX" + AC_SUBST(MPICXX) +], +[Fortran 77], [ + AC_REQUIRE([AC_PROG_F77]) + AC_ARG_VAR(MPIF77,[MPI Fortran 77 compiler command]) + AC_CHECK_PROGS(MPIF77, mpif77 hf77 mpxlf_r mpxlf mpf77 cmpifc, $F77) + ax_mpi_save_F77="$F77" + F77="$MPIF77" + AC_SUBST(MPIF77) +], +[Fortran], [ + AC_REQUIRE([AC_PROG_FC]) + AC_ARG_VAR(MPIFC,[MPI Fortran compiler command]) + AC_CHECK_PROGS(MPIFC, mpifort mpif90 ftn mpxlf95_r mpxlf90_r mpxlf95 mpxlf90 mpf90 cmpif90c, $FC) + ax_mpi_save_FC="$FC" + FC="$MPIFC" + AC_SUBST(MPIFC) +]) + +if test x = x"$MPILIBS"; then + AC_LANG_CASE([C], [AC_CHECK_FUNC(MPI_Init, [MPILIBS=" "])], + [C++], [AC_CHECK_FUNC(MPI_Init, [MPILIBS=" "])], + [Fortran 77], [AC_MSG_CHECKING([for MPI_Init]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[ call MPI_Init])],[MPILIBS=" " + AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])], + [Fortran], [AC_MSG_CHECKING([for MPI_Init]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[ call MPI_Init])],[MPILIBS=" " + AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])]) +fi +AC_LANG_CASE([Fortran 77], [ + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(fmpi, MPI_Init, [MPILIBS="-lfmpi"]) + fi + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(fmpich, MPI_Init, [MPILIBS="-lfmpich"]) + fi +], +[Fortran], [ + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(fmpi, MPI_Init, [MPILIBS="-lfmpi"]) + fi + if test x = x"$MPILIBS"; then + AC_CHECK_LIB(mpichf90, MPI_Init, [MPILIBS="-lmpichf90"]) + fi +]) +if test x = x"$MPILIBS"; then + AC_CHECK_LIB(mpi, MPI_Init, [MPILIBS="-lmpi"]) +fi +if test x = x"$MPILIBS"; then + AC_CHECK_LIB(mpich, MPI_Init, [MPILIBS="-lmpich"]) +fi + +dnl We have to use AC_TRY_COMPILE and not AC_CHECK_HEADER because the +dnl latter uses $CPP, not $CC (which may be mpicc). +AC_LANG_CASE([C], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpi.h]) + AC_TRY_COMPILE([#include ],[],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi], +[C++], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpi.h]) + AC_TRY_COMPILE([#include ],[],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi], +[Fortran 77], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpif.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[ include 'mpif.h'])],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi], +[Fortran], [if test x != x"$MPILIBS"; then + AC_MSG_CHECKING([for mpif.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[ include 'mpif.h'])],[AC_MSG_RESULT(yes)], [MPILIBS="" + AC_MSG_RESULT(no)]) +fi]) + +AC_LANG_CASE([C], [CC="$ax_mpi_save_CC"], + [C++], [CXX="$ax_mpi_save_CXX"], + [Fortran 77], [F77="$ax_mpi_save_F77"], + [Fortran], [FC="$ax_mpi_save_FC"]) + +AC_SUBST(MPILIBS) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x = x"$MPILIBS"; then + $2 + : +else + ifelse([$1],,[AC_DEFINE(HAVE_MPI,1,[Define if you have the MPI library.])],[$1]) + : +fi +])dnl AX_MPI From 32b47bbe4537204fcecbf347a00962b18b67db67 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Fri, 11 Sep 2020 16:14:17 -0400 Subject: [PATCH 10/23] Autoconf: Cray ptr update; macro cleanup The AX_FC_CRAY_POINTER macro was heavily updated to better use the intrinsic Autoconf and M4 macros, as well as to introduce both pass/fail macros and an additional PGI test (which doesn't seem needed but *shrug*). Additional processing is no longer needed when invoking this macro. It now automatically applies the Cray pointer flags to FCFLAGS if invoked, and it now automatically aborts of such macros are not supported, although both of these operations can be overridden if necessary. Several FMS macros unused by MOM6 were also removed from the MOM6 m4 macro folder. --- ac/deps/configure.fms.ac | 5 --- ac/deps/m4/ax_fc_cray_pointer.m4 | 75 ++++++++++++++++--------------- ac/m4/ax_fc_allow_arg_mismatch.m4 | 58 ------------------------ ac/m4/ax_fc_allow_invalid_boz.m4 | 54 ---------------------- ac/m4/ax_fc_cray_pointer.m4 | 53 ---------------------- 5 files changed, 38 insertions(+), 207 deletions(-) delete mode 100644 ac/m4/ax_fc_allow_arg_mismatch.m4 delete mode 100644 ac/m4/ax_fc_allow_invalid_boz.m4 delete mode 100644 ac/m4/ax_fc_cray_pointer.m4 diff --git a/ac/deps/configure.fms.ac b/ac/deps/configure.fms.ac index aaa1e86764..79f59d95c2 100644 --- a/ac/deps/configure.fms.ac +++ b/ac/deps/configure.fms.ac @@ -52,11 +52,6 @@ AC_DEFINE([use_netCDF]) # Enable Cray pointers AX_FC_CRAY_POINTER -AS_IF([test "$enable_cray_ptr" != no], - [FCFLAGS="$FCFLAGS $CRAY_POINTER_FCFLAGS"], - [AC_MSG_ERROR(["$FC cannot support Cray pointers"])] -) - # Force 8-byte reals AX_FC_REAL8 diff --git a/ac/deps/m4/ax_fc_cray_pointer.m4 b/ac/deps/m4/ax_fc_cray_pointer.m4 index a00b10edf6..0b52325baa 100644 --- a/ac/deps/m4/ax_fc_cray_pointer.m4 +++ b/ac/deps/m4/ax_fc_cray_pointer.m4 @@ -1,4 +1,4 @@ -dnl Test if Cray pointers are supported. +dnl AX_FC_CRAY_POINTER([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE]) dnl dnl This macro tests if any flags are required to enable Cray pointers. dnl @@ -6,48 +6,49 @@ dnl Cray pointers provided a means for more direct access to memory. Since dnl such references can potentially violate certain requirements of the dnl language standard, they are typically considered a vendor extension. dnl -dnl Most compilers provide these in some form. As far as I can tell, only GNU -dnl explicitly requires a flag. Known tests are shown below, but additional -dnl feedback is required to fill this out. +dnl Most compilers provide these in some form. A partial list of supported +dnl flags are shown below, but additional feedback is required for other +dnl compilers. dnl -dnl Flags +dnl The known flags are: dnl GCC -fcray-pointer dnl Intel Fortran none -dnl PGI Fortran none +dnl PGI Fortran -Mcray=pointer dnl Cray Fortran none dnl -AC_DEFUN([AX_FC_CRAY_POINTER], - [CRAY_POINTER_FCFLAGS= - AC_CACHE_CHECK([for $FC option to support Cray pointers], - [ac_cv_prog_fc_cray_ptr], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([], [ - integer aptr(2) - pointer (iptr, aptr) - ])], - [ac_cv_prog_fc_cray_ptr='none needed'], - [ac_cv_prog_fc_cray_ptr='unsupported' - for ac_option in -fcray-pointer; do - ac_save_FCFLAGS=$FCFLAGS - FCFLAGS="$FCFLAGS $ac_option" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([], [ - integer aptr(2) - pointer (iptr, aptr) - ])], - [ac_cv_prog_fc_cray_ptr=$ac_option] - ) - FCFLAGS=$ac_save_FCFLAGS - if test "$ac_cv_prog_fc_cray_ptr" != unsupported; then - break - fi - done]) +AC_DEFUN([AX_FC_CRAY_POINTER], [ + AC_LANG_ASSERT([Fortran]) + AC_MSG_CHECKING([for $FC option to support Cray pointers]) + AC_CACHE_VAL([ac_cv_fc_cray_ptr], [ + ac_cv_fc_cray_ptr='unknown' + ac_save_FCFLAGS=$FCFLAGS + for ac_option in none -fcray-pointer -Mcray=pointer; do + test "$ac_option" != none && FCFLAGS="$ac_save_FCFLAGS $ac_option" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [ + integer aptr(2) + pointer (iptr, aptr) + ])], + [ac_cv_fc_cray_ptr=$ac_option], + ) + FCFLAGS=$ac_save_FCFLAGS + AS_IF([test "$ac_cv_fc_cray_ptr" != unknown], [break]) + done ]) - case $ac_cv_prog_fc_cray_ptr in #( - "none needed" | unsupported) - ;; #( + case "$ac_cv_fc_cray_ptr" in + none) + AC_MSG_RESULT([none needed]) ;; + unknown) + AC_MSG_RESULT([unsupported]) ;; *) - CRAY_POINTER_FCFLAGS=$ac_cv_prog_fc_cray_ptr ;; + AC_MSG_RESULT([$ac_cv_fc_cray_ptr]) ;; esac - AC_SUBST(CRAY_POINTER_FCFLAGS) + AS_IF([test "$ac_cv_fc_cray_ptr" != unknown], [ + m4_default([$1], [ + AS_IF([test "$ac_cv_fc_cray_ptr" != none], + [FCFLAGS="$FCFLAGS $ac_cv_fc_cray_ptr"] + ) + ])], + [m4_default([$2], [AC_MSG_ERROR(["$FC does not support Cray pointers"])])] + ) ]) diff --git a/ac/m4/ax_fc_allow_arg_mismatch.m4 b/ac/m4/ax_fc_allow_arg_mismatch.m4 deleted file mode 100644 index cffa302c66..0000000000 --- a/ac/m4/ax_fc_allow_arg_mismatch.m4 +++ /dev/null @@ -1,58 +0,0 @@ -dnl Test if mismatched function arguments are permitted. -dnl -dnl This macro tests if a flag is required to enable mismatched functions in -dnl a single translation unit (aka file). -dnl -dnl If a compiler encounters two undefined programs with different input -dnl argument types, then it may regard this as a mismatch which requires action -dnl from the user. A common example is a procedure which may be called with -dnl a variable of either an integer or a real type. -dnl -dnl This can happen, for example, if one is relying on an interface to resolve -dnl such differences, but one is also relying on a legacy header interface via -dnl `#include` rather than an explicit module which includes the complete -dnl interface specification. -dnl -dnl No modern project is expected to see these issues, but this is helpful for -dnl older projects which used legacy headers. -dnl -dnl Flags: -dnl GNU: -fallow-argument-mismatch -dnl -AC_DEFUN([AX_FC_ALLOW_ARG_MISMATCH], - [ALLOW_ARG_MISMATCH_FCFLAGS= - AC_CACHE_CHECK( - [for $FC option to support mismatched procedure arguments], - [ac_cv_prog_fc_arg_mismatch], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([], [ - call f(1) - call f(1.0) - ])], - [ac_cv_prog_fc_arg_mismatch='none needed'], - [ac_cv_prog_fc_arg_mismatch='unsupported' - for ac_option in -fallow-argument-mismatch; do - ac_save_FCFLAGS=$FCFLAGS - FCFLAGS="$FCFLAGS $ac_option" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([], [ - call f(1) - call f(1.0) - ])], - [ac_cv_prog_fc_arg_mismatch=$ac_option] - ) - FCFLAGS=$ac_save_FCFLAGS - if test "$ac_cv_prog_fc_arg_mismatch" != unsupported; then - break - fi - done]) - ] - ) - case $ac_cv_prog_fc_arg_mismatch in #( - "none needed" | unsupported) - ;; #( - *) - ALLOW_ARG_MISMATCH_FCFLAGS=$ac_cv_prog_fc_arg_mismatch ;; - esac - AC_SUBST(ALLOW_ARG_MISMATCH_FCFLAGS) -]) diff --git a/ac/m4/ax_fc_allow_invalid_boz.m4 b/ac/m4/ax_fc_allow_invalid_boz.m4 deleted file mode 100644 index 5d4521b5fb..0000000000 --- a/ac/m4/ax_fc_allow_invalid_boz.m4 +++ /dev/null @@ -1,54 +0,0 @@ -dnl Test if BOZ literal assignment is supported. -dnl -dnl This macro tests if a flag is required to enable BOZ literal assignments -dnl for variables. -dnl -dnl BOZ literals (e.g. Z'FFFF') are typeless, and formally cannot be assigned -dnl to typed variables. Nonetheless, few compilers forbid such operations, -dnl despite the potential pitfalls around interpreting such values. -dnl -dnl As of version 10.1, gfortran now forbids such assignments and requires a -dnl flag to convert the raised errors into warnings. -dnl -dnl While the best solution is to replace such assignments with proper -dnl conversion functions, this test is useful to accommodate older projects. -dnl -dnl Flags: -dnl GNU: -fallow-invalid-boz -AC_DEFUN([AX_FC_ALLOW_INVALID_BOZ], - [ALLOW_INVALID_BOZ_FCFLAGS= - AC_CACHE_CHECK( - [for $FC option to support invalid BOZ assignment], - [ac_cv_prog_fc_invalid_boz], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([], [ - integer n - n = z'ff' - ])], - [ac_cv_prog_fc_invalid_boz='none needed'], - [ac_cv_prog_fc_invalid_boz='unsupported' - for ac_option in -fallow-invalid-boz; do - ac_save_FCFLAGS=$FCFLAGS - FCFLAGS="$FCFLAGS $ac_option" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([], [ - integer n - n = z'ff' - ])], - [ac_cv_prog_fc_invalid_boz=$ac_option] - ) - FCFLAGS=$ac_save_FCFLAGS - if test "$ac_cv_prog_fc_invalid_boz" != unsupported; then - break - fi - done]) - ] - ) - case $ac_cv_prog_fc_invalid_boz in #( - "none needed" | unsupported) - ;; #( - *) - ALLOW_INVALID_BOZ_FCFLAGS=$ac_cv_prog_fc_invalid_boz ;; - esac - AC_SUBST(ALLOW_INVALID_BOZ_FCFLAGS)] -) diff --git a/ac/m4/ax_fc_cray_pointer.m4 b/ac/m4/ax_fc_cray_pointer.m4 deleted file mode 100644 index a00b10edf6..0000000000 --- a/ac/m4/ax_fc_cray_pointer.m4 +++ /dev/null @@ -1,53 +0,0 @@ -dnl Test if Cray pointers are supported. -dnl -dnl This macro tests if any flags are required to enable Cray pointers. -dnl -dnl Cray pointers provided a means for more direct access to memory. Since -dnl such references can potentially violate certain requirements of the -dnl language standard, they are typically considered a vendor extension. -dnl -dnl Most compilers provide these in some form. As far as I can tell, only GNU -dnl explicitly requires a flag. Known tests are shown below, but additional -dnl feedback is required to fill this out. -dnl -dnl Flags -dnl GCC -fcray-pointer -dnl Intel Fortran none -dnl PGI Fortran none -dnl Cray Fortran none -dnl -AC_DEFUN([AX_FC_CRAY_POINTER], - [CRAY_POINTER_FCFLAGS= - AC_CACHE_CHECK([for $FC option to support Cray pointers], - [ac_cv_prog_fc_cray_ptr], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([], [ - integer aptr(2) - pointer (iptr, aptr) - ])], - [ac_cv_prog_fc_cray_ptr='none needed'], - [ac_cv_prog_fc_cray_ptr='unsupported' - for ac_option in -fcray-pointer; do - ac_save_FCFLAGS=$FCFLAGS - FCFLAGS="$FCFLAGS $ac_option" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([], [ - integer aptr(2) - pointer (iptr, aptr) - ])], - [ac_cv_prog_fc_cray_ptr=$ac_option] - ) - FCFLAGS=$ac_save_FCFLAGS - if test "$ac_cv_prog_fc_cray_ptr" != unsupported; then - break - fi - done]) - ]) - case $ac_cv_prog_fc_cray_ptr in #( - "none needed" | unsupported) - ;; #( - *) - CRAY_POINTER_FCFLAGS=$ac_cv_prog_fc_cray_ptr ;; - esac - AC_SUBST(CRAY_POINTER_FCFLAGS) -]) From 6a8a699616c9e3d1535d62b108bfc3a2ad378721 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Mon, 14 Sep 2020 17:05:18 -0400 Subject: [PATCH 11/23] Autoconf: Travis fix; Cray ptr macro update Resolved some bad string parsing issues of the Travis environment variables. Thanks to Inspector Adcroft for discovering this error. Further cleanup of the Cray pointer test macro, should now be very close to conformant Autoconf M4 format. --- .travis.yml | 10 +++++----- ac/deps/m4/ax_fc_cray_pointer.m4 | 31 ++++++++++++++----------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3fd729f8d1..8987c6e3ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,11 +20,11 @@ addons: # Environment variables env: global: - - TIMEFORMAT="Time: %lR (user: %lU, sys: %lS)" - - FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" - - FCFLAGS_REPRO="-g -O2 -fbacktrace" - - FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" - - FCFLAGS_COVERAGE="--coverage" + - TIMEFORMAT: "\"Time: %lR (user: %lU, sys: %lS)\"" + - FCFLAGS_DEBUG: "\"-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds\"" + - FCFLAGS_REPRO: "\"-g -O2 -fbacktrace\"" + - FCFLAGS_INIT: "\"-finit-real=snan -finit-integer=2147483647 -finit-derived\"" + - FCFLAGS_COVERAGE: "\"--coverage\"" jobs: include: diff --git a/ac/deps/m4/ax_fc_cray_pointer.m4 b/ac/deps/m4/ax_fc_cray_pointer.m4 index 0b52325baa..a9f5d9bbe3 100644 --- a/ac/deps/m4/ax_fc_cray_pointer.m4 +++ b/ac/deps/m4/ax_fc_cray_pointer.m4 @@ -19,34 +19,31 @@ dnl AC_DEFUN([AX_FC_CRAY_POINTER], [ AC_LANG_ASSERT([Fortran]) AC_MSG_CHECKING([for $FC option to support Cray pointers]) - AC_CACHE_VAL([ac_cv_fc_cray_ptr], [ - ac_cv_fc_cray_ptr='unknown' + AC_CACHE_VAL([ac_cv_prog_fc_cray_ptr], [ + ac_cv_prog_fc_cray_ptr='unknown' ac_save_FCFLAGS=$FCFLAGS for ac_option in none -fcray-pointer -Mcray=pointer; do test "$ac_option" != none && FCFLAGS="$ac_save_FCFLAGS $ac_option" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [ - integer aptr(2) - pointer (iptr, aptr) + integer aptr(2) + pointer (iptr, aptr) ])], - [ac_cv_fc_cray_ptr=$ac_option], + [ac_cv_prog_fc_cray_ptr=$ac_option], ) FCFLAGS=$ac_save_FCFLAGS - AS_IF([test "$ac_cv_fc_cray_ptr" != unknown], [break]) + AS_IF([test "$ac_cv_prog_fc_cray_ptr" != unknown], [break]) done ]) - case "$ac_cv_fc_cray_ptr" in - none) - AC_MSG_RESULT([none needed]) ;; - unknown) - AC_MSG_RESULT([unsupported]) ;; - *) - AC_MSG_RESULT([$ac_cv_fc_cray_ptr]) ;; - esac - AS_IF([test "$ac_cv_fc_cray_ptr" != unknown], [ + AS_CASE([ac_cv_prog_fc_cray_ptr], + [none], [AC_MSG_RESULT([none_needed])], + [unknown], [AC_MSG_RESULT([unsupported])], + [AC_MSG_RESULT([$ac_cv_prog_fc_cray_ptr])] + ) + AS_IF([test "$ac_cv_prog_fc_cray_ptr" != unknown], [ m4_default([$1], [ - AS_IF([test "$ac_cv_fc_cray_ptr" != none], - [FCFLAGS="$FCFLAGS $ac_cv_fc_cray_ptr"] + AS_IF([test "$ac_cv_prog_fc_cray_ptr" != none], + [FCFLAGS="$FCFLAGS $ac_cv_prog_fc_cray_ptr"] ) ])], [m4_default([$2], [AC_MSG_ERROR(["$FC does not support Cray pointers"])])] From 2ed83644b0c7a77eb9f698db3b9213125f15035b Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Mon, 14 Sep 2020 17:31:17 -0400 Subject: [PATCH 12/23] Testing: Fixing bug in target Makefile --- .testing/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.testing/Makefile b/.testing/Makefile index 299bcad730..d438c9ef9e 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -204,7 +204,7 @@ build/%/Makefile: ../ac/configure ../ac/Makefile.in $(DEPS)/lib/libFMS.a $(MKMF) # Fetch the regression target codebase -build/target/Makefile: $(TARGET_CODEBASE)/configure build/fms/libFMS.a $(MKMF) $(LIST_PATHS) +build/target/Makefile: $(TARGET_CODEBASE)/configure $(DEPS)/lib/fms/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) cd $(@D) \ && $(MOM_ENV) ../../$(TARGET_CODEBASE)/configure $(MOM_ACFLAGS) \ From ce6843bde131d60f8d92fe706cc82524d7557a4e Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Mon, 14 Sep 2020 17:41:47 -0400 Subject: [PATCH 13/23] Fixed FMS lib typo in target --- .testing/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.testing/Makefile b/.testing/Makefile index d438c9ef9e..af758163a2 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -204,7 +204,7 @@ build/%/Makefile: ../ac/configure ../ac/Makefile.in $(DEPS)/lib/libFMS.a $(MKMF) # Fetch the regression target codebase -build/target/Makefile: $(TARGET_CODEBASE)/configure $(DEPS)/lib/fms/libFMS.a $(MKMF) $(LIST_PATHS) +build/target/Makefile: $(TARGET_CODEBASE)/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) cd $(@D) \ && $(MOM_ENV) ../../$(TARGET_CODEBASE)/configure $(MOM_ACFLAGS) \ From 4296d6dd555aba57d6289ab0e93ea0435734ebba Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Mon, 14 Sep 2020 19:02:41 -0400 Subject: [PATCH 14/23] Autoconf: Fixed several target build errors --- .testing/Makefile | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.testing/Makefile b/.testing/Makefile index af758163a2..da6cef9f7b 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -169,7 +169,7 @@ build/symmetric/Makefile: MOM_ACFLAGS=--enable-symmetric build/asymmetric/Makefile: MOM_ACFLAGS= build/repro/Makefile: MOM_ACFLAGS=--enable-symmetric build/openmp/Makefile: MOM_ACFLAGS=--enable-symmetric --enable-openmp -build/target/Makefile: MOM_ACFLAGS=--srcdir=../../$(TARGET_CODEBASE) --enable-symmetric +build/target/Makefile: MOM_ACFLAGS=--enable-symmetric # Fetch regression target source code @@ -204,24 +204,23 @@ build/%/Makefile: ../ac/configure ../ac/Makefile.in $(DEPS)/lib/libFMS.a $(MKMF) # Fetch the regression target codebase -build/target/Makefile: $(TARGET_CODEBASE)/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) +build/target/Makefile: $(TARGET_CODEBASE)/ac/configure $(DEPS)/lib/libFMS.a $(MKMF) $(LIST_PATHS) mkdir -p $(@D) cd $(@D) \ - && $(MOM_ENV) ../../$(TARGET_CODEBASE)/configure $(MOM_ACFLAGS) \ + && $(MOM_ENV) ../../$(TARGET_CODEBASE)/ac/configure $(MOM_ACFLAGS) \ || (cat config.log && false) -$(TARGET_CODEBASE)/configure: $(TARGET_CODEBASE) - autoreconf -i $< +$(TARGET_CODEBASE)/ac/configure: $(TARGET_CODEBASE) + autoreconf -i $ Date: Tue, 15 Sep 2020 16:14:53 -0400 Subject: [PATCH 15/23] Testing: Minor dependency bugfix in Makefile --- .testing/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.testing/Makefile b/.testing/Makefile index da6cef9f7b..327a7d457e 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -236,7 +236,7 @@ $(DEPS)/fms/build/libFMS.a: $(DEPS)/fms/build/Makefile $(DEPS)/fms/build/Makefile: $(DEPS)/fms/src/configure $(DEPS)/Makefile.fms.in $(MKMF) $(LIST_PATHS) PATH_ENV="${PATH}:../../bin" FCFLAGS_ENV="$(FCFLAGS_DEBUG)" $(MAKE) -C $(DEPS) fms/build/Makefile -$(DEPS)/Makefile.fms.in: ../ac/deps/Makefile.fms.in +$(DEPS)/Makefile.fms.in: ../ac/deps/Makefile.fms.in $(DEPS)/Makefile cp $< $(DEPS) # TODO: m4 dependencies? From 275b99308feb8417cb0fe27cfa0158db58b7c9c0 Mon Sep 17 00:00:00 2001 From: x Date: Wed, 16 Sep 2020 12:49:48 -0400 Subject: [PATCH 16/23] Autoconf: macOS support; Makefile fixes This patch adds additional support for building FMS in deps on macOS machines, specifically related to affinity. Much of this can be phased out when we upgrade our target FMS from 2019.01.03 to a newer version. Additional dependency errors in .testing/Makefile have also been fixed related to building of the virtual Python environment. --- .testing/Makefile | 12 ++++++------ ac/deps/configure.fms.ac | 42 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/.testing/Makefile b/.testing/Makefile index 327a7d457e..3991e2d7fb 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -25,7 +25,7 @@ FCFLAGS_COVERAGE ?= # - These flags should be configured outside of the Makefile, either with # config.mk or as environment variables. # -# - FMS cannot be build with the same aggressive initialization flags as MOM6, +# - FMS cannot be built with the same aggressive initialization flags as MOM6, # so FCFLAGS_INIT is used to provide additional MOM6 configuration. @@ -125,7 +125,7 @@ endif # Rules .PHONY: all build.regressions -all: $(foreach b,$(BUILDS),build/$(b)/MOM6) $(VENV_PATH) +all: $(foreach b,$(BUILDS),build/$(b)/MOM6) build.regressions: $(foreach b,symmetric target,build/$(b)/MOM6) # Executable @@ -371,11 +371,11 @@ $(eval $(call CMP_RULE,regression,symmetric target)) # $(5): Environment variables # $(6): Number of MPI ranks define STAT_RULE -work/%/$(1)/ocean.stats work/%/$(1)/chksum_diag: build/$(2)/MOM6 +work/%/$(1)/ocean.stats work/%/$(1)/chksum_diag: build/$(2)/MOM6 $(VENV_PATH) @echo "Running test $$*.$(1)..." if [ $(3) ]; then find build/$(2) -name *.gcda -exec rm -f '{}' \; ; fi mkdir -p $$(@D) - cp -rL $$*/* $$(@D) + cp -RL $$*/* $$(@D) if [ -f $$(@D)/Makefile ]; then \ $$(VENV_ACTIVATE) \ && cd $$(@D) \ @@ -425,10 +425,10 @@ $(eval $(call STAT_RULE,dim.r,symmetric,,R_RESCALE_POWER=11,,1)) # Restart tests require significant preprocessing, and are handled separately. -work/%/restart/ocean.stats: build/symmetric/MOM6 +work/%/restart/ocean.stats: build/symmetric/MOM6 $(VENV_PATH) rm -rf $(@D) mkdir -p $(@D) - cp -rL $*/* $(@D) + cp -RL $*/* $(@D) if [ -f $(@D)/Makefile ]; then \ $(VENV_ACTIVATE) \ && cd work/$*/restart \ diff --git a/ac/deps/configure.fms.ac b/ac/deps/configure.fms.ac index 79f59d95c2..1d66194c81 100644 --- a/ac/deps/configure.fms.ac +++ b/ac/deps/configure.fms.ac @@ -13,8 +13,44 @@ AC_PROG_CC AX_MPI CC=$MPICC -# FMS: Check if Linux gettid is avaiable -AC_CHECK_FUNCS([gettid]) +# FMS configuration + +# Linux and OSX have a gettid system call, but it is not implemented in older +# glibc implementations. When unavailable, a native syscall is used. +# +# On Linux, this is defined in unistd.h as __NR_gettid, and FMS is hard-coded +# to use this value. In OS X, this is defined in sys/syscall.h as SYS_gettid, +# so we override this macro if __NR_gettid is unavailable. +AC_CHECK_FUNCS([gettid], [], [ + AC_MSG_CHECKING([if __NR_gettid must be redefined]) + AC_CACHE_VAL([ac_cv_cc_nr_gettid], [ + ac_cv_cc_nr_gettid='unknown' + for nr_gettid in __NR_gettid SYS_gettid; do + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ +#include +#include + ], [syscall($nr_gettid)] + )], [ac_cv_cc_nr_gettid=$nr_gettid] + ) + AS_IF([test "$ac_cv_cc_nr_gettid" != unknown], [break]) + done + ]) + AS_CASE([ac_cv_cc_nr_gettid], + [__NR_gettid], [AC_MSG_RESULT([none needed])], + [AC_MSG_RESULT([$ac_cv_cc_nr_gettid])] + ) + AS_IF([test "$ac_cv_cc_nr_gettid" != unknown], [ + AS_IF([test "$ac_cv_cc_nr_gettid" != __NR_gettid], + [AC_DEFINE_UNQUOTED([__NR_gettid], [$ac_cv_cc_nr_gettid])] + )], [ + AC_MSG_ERROR(["Could not find the gettid syscall ID"]) + ]) +]) + + +# FMS 2019.01.03 uses __APPLE__ to disable Linux CPU affinity calls. +AC_CHECK_FUNCS([sched_getaffinity], [], [AC_DEFINE([__APPLE__])]) # Standard Fortran configuration @@ -53,6 +89,7 @@ AC_DEFINE([use_netCDF]) # Enable Cray pointers AX_FC_CRAY_POINTER + # Force 8-byte reals AX_FC_REAL8 AS_IF( @@ -75,6 +112,7 @@ AC_FC_LINE_LENGTH([unlimited]) AX_FC_ALLOW_INVALID_BOZ FCFLAGS="$FCFLAGS $ALLOW_INVALID_BOZ_FCFLAGS" + # Allow argument mismatch (for functions lacking interfaces) AX_FC_ALLOW_ARG_MISMATCH FCFLAGS="$FCFLAGS $ALLOW_ARG_MISMATCH_FCFLAGS" From 039a75dba6f84459ba73234c846ed936c8b3d4eb Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 16 Sep 2020 22:25:27 -0400 Subject: [PATCH 17/23] Autoconf: Default updates autoconf now defaults to using symmetric grids, rather than asymmetric grids. The DEBUG/REPRO build comparison is now disabled on default, since many platforms do not produce equivalent results. If this situation improves, then it can be re-enabled. --- .testing/Makefile | 23 ++++++++++++----------- .travis.yml | 1 + ac/Makefile.in | 18 +++++++----------- ac/configure.ac | 14 +++++++------- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/.testing/Makefile b/.testing/Makefile index bcce1c6290..6ea2d18370 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -7,10 +7,6 @@ SHELL = bash # Set the MPI launcher here MPIRUN ?= mpirun -# Many compilers (Intel, GCC on ARM64) do not yet produce identical results -# across DEBUG and REPRO builds. For these platforms, set to false -DO_REPRO_TESTS ?= true - # Default target compiler flags # NOTE: FMS will be built using FCFLAGS_DEBUG FCFLAGS_DEBUG ?= -g -O0 @@ -20,7 +16,7 @@ FCFLAGS_COVERAGE ?= # Additional notes: # # - The default values are simple, minimalist flags, supported by nearly all -# compilers and meant to represent GFDL's canonical DEBUG and REPRO builds. +# compilers which are comparable to GFDL's canonical DEBUG and REPRO builds. # # - These flags should be configured outside of the Makefile, either with # config.mk or as environment variables. @@ -28,6 +24,11 @@ FCFLAGS_COVERAGE ?= # - FMS cannot be built with the same aggressive initialization flags as MOM6, # so FCFLAGS_INIT is used to provide additional MOM6 configuration. +# Set to `true` to require identical results from DEBUG and REPRO builds +DO_REPRO_TESTS ?= + +# Many compilers (Intel, GCC on ARM64) do not yet produce identical results +# across DEBUG and REPRO builds (as defined below), so we disable on default. #--- # Dependencies @@ -165,11 +166,11 @@ build/target/Makefile: MOM_ENV=$(PATH_FMS) $(TARGET_FCFLAGS) $(MOM_LDFLAGS) # Configure script flags -build/symmetric/Makefile: MOM_ACFLAGS=--enable-symmetric -build/asymmetric/Makefile: MOM_ACFLAGS= -build/repro/Makefile: MOM_ACFLAGS=--enable-symmetric -build/openmp/Makefile: MOM_ACFLAGS=--enable-symmetric --enable-openmp -build/target/Makefile: MOM_ACFLAGS=--enable-symmetric +build/symmetric/Makefile: MOM_ACFLAGS= +build/asymmetric/Makefile: MOM_ACFLAGS=--enable-asymmetric +build/repro/Makefile: MOM_ACFLAGS= +build/openmp/Makefile: MOM_ACFLAGS=--enable-openmp +build/target/Makefile: MOM_ACFLAGS= # Fetch regression target source code @@ -378,7 +379,7 @@ $(foreach d,$(DIMS),$(eval $(call CMP_RULE,dim.$(d),symmetric dim.$(d)))) (diff $^ | tee results/$*/chksum_diag.regression.diff | head) ; \ echo -e "$(FAIL): Diagnostics $*.regression.diag have changed." \ ) - diff $^ || echo -e "$(WARN): New diagnostics in $<" + @diff $^ || echo -e "$(WARN): New diagnostics in $<" @echo -e "$(PASS): Diagnostics $*.regression.diag agree." diff --git a/.travis.yml b/.travis.yml index 8987c6e3ff..22c497f916 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ env: - FCFLAGS_REPRO: "\"-g -O2 -fbacktrace\"" - FCFLAGS_INIT: "\"-finit-real=snan -finit-integer=2147483647 -finit-derived\"" - FCFLAGS_COVERAGE: "\"--coverage\"" + - DO_REPRO_TESTS: true jobs: include: diff --git a/ac/Makefile.in b/ac/Makefile.in index a1b1b9118a..81d9f9a8e4 100644 --- a/ac/Makefile.in +++ b/ac/Makefile.in @@ -1,18 +1,14 @@ # Makefile template for MOM6 # -# Previously this would have been generated by mkmf using a template file. +# Compiler flags are configured by autoconf's configure script. # -# The proposed autoconf build inverts this approach by constructing the -# information previously stored in the mkmf template, such as compiler names -# and flags, and importing the un-templated mkmf output for its rules and -# dependencies. +# Source code dependencies are configured by mkmf and list_paths, specified in +# the `Makefile.mkmf` file. # -# While this approach does not eliminate our dependency on mkmf, it does -# promises to eliminate our reliance on platform-specific templates, and -# instead allows us to provide a configure script for determining our compilers -# and flags. As a last resort, we provide hooks to override such settings. - -# NOTE: mkmf conventions are close, but not identical, to autoconf. +# mkmf conventions are close, but not identical, to autoconf. We attempt to +# map the autoconf variables to the mkmf variables. +# +# The following variables are used by Makefiles generated by mkmf. # # CC: C compiler # CXX: C++ compiler diff --git a/ac/configure.ac b/ac/configure.ac index 73340ba250..ee6b76dacb 100644 --- a/ac/configure.ac +++ b/ac/configure.ac @@ -28,7 +28,7 @@ AC_INIT( # to srcdir and point AC_CONFIG_SRCDIR to the parent directory. # # Someday we may revert this and work from the top-level directory. But for -# now we will compartment autoconf to a subdirectory. +# now we will isolate autoconf to a subdirectory. #--- # Validate srdcir and configure input @@ -37,14 +37,14 @@ AC_CONFIG_MACRO_DIR([m4]) srcdir=$srcdir/.. -# Default to asymmetric grid +# Default to symmetric grid # NOTE: --enable is more properly used to add a feature, rather than to select # a compile-time mode, so this is not exactly being used as intended. -MEM_LAYOUT=${srcdir}/config_src/dynamic -AC_ARG_ENABLE([symmetric], - AS_HELP_STRING([--enable-symmetric], [Enable symmetric grid])) -AS_IF([test "$enable_symmetric" = yes], - [MEM_LAYOUT=${srcdir}/config_src/dynamic_symmetric]) +MEM_LAYOUT=${srcdir}/config_src/dynamic_symmetric +AC_ARG_ENABLE([asymmetric], + AS_HELP_STRING([--enable-asymmetric], [Use the asymmetric grid])) +AS_IF([test "$enable_asymmetric" = yes], + [MEM_LAYOUT=${srcdir}/config_src/dynamic]) # TODO: Rather than point to a pre-configured header file, autoconf could be From c518096609a57d6921fb981e7f0c96d20cdd2e12 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Thu, 17 Sep 2020 12:58:13 -0400 Subject: [PATCH 18/23] Testing: Updated the README --- .testing/README.md | 212 +++++++++++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 83 deletions(-) diff --git a/.testing/README.md b/.testing/README.md index abad08ada8..5e1a088725 100644 --- a/.testing/README.md +++ b/.testing/README.md @@ -2,30 +2,43 @@ This directory contains the Makefile and test configurations used to evaluate submissions to the MOM6 codebase. The tests are designed to run either locally -or in a Travis-CI. +or in a CI environment such as Travis. ## Overview This section gives a very brief overview of the test suite and how to use it. -To build and run the model tests +To build and run the model tests: ``` make make test ``` +Users may wish to use `make -j` in place of `make` to enable parallel builds. -Regression testing is disabled on default. To include regression tests: +For new users, the default configuration should be suitable for most platforms. +If not, then the following options may need to be configured. + +`MPIRUN` (*default:* `mpirun`) + + Name of the MPI launcher. Often this is `mpirun` or `mpiexec` but may all + need to run through a scheduler, e.g. `srun` if using Slurm. + +`DO_REGRESSION_TESTS` (*default: none*) + + Set to `true` to compare output with `dev/gfdl`. + +`DO_REPRO_TESTS` (*default: none*) + + Set to `true` to compare DEBUG and REPRO builds, which typically correspond + to unoptimized and optimized builds. See TODO for more information. + +These settings can either be specified at the command line, as shown below. ``` make DO_REGRESSION_TESTS=true make test DO_REGRESSION_TESTS=true ``` - -On platforms other than Gaea, a MKMF build template may be required. To -specify the path to the template: -``` -make MKMF_TEMPLATE=/path/to/template.mk -``` +or saved to `config.mk`. To run individual classes of tests, use the subclass name: ``` @@ -33,11 +46,11 @@ make test.grids make test.layouts make DO_REGRESSION_TESTS=true test.regressions ``` - To test an individual test configuration (TC): ``` make tc0.grid ``` +See "Tests" and "Test Configurations" for the complete list of tests. The rest of the document describes the test suite in more detail, including names and descriptions of the test classes and configurations. @@ -45,21 +58,86 @@ names and descriptions of the test classes and configurations. ## Testing overview -The test suite consists of many comparisons of model output for different model -configurations when subjected to relevant numerical and mathematical -transformations, such as grid layout or dimensional rescaling, for which the -model output should be invariant. If the model state is unchanged after each -transformation, then the test is reported as passing. Any discrepancy in the -model state causes the test to fail. +The test suite checks for numerical consistency of the model output of +different model configurations when subjected to relevant numerical and +mathematical transformations, such as grid layout or dimensional rescaling. If +the model state is unchanged after each transformation, then the test is +reported as passing. Any discrepancy in the model state causes the test to +fail. Model state is currently defined by the `ocean.stats` output file, which reports the total energy (per unit mass) at machine precision alongside similar global metrics, such as mass or mean sea level, at lower precision. -Checksums for every available diagnostic are also compared and the Makefile -will report any differences, but such differences are not yet considered a fail -condition. +Diagnostics are based on the MOM checksum function, which includes the mean, +minimum, and maximum values as well as a bitcount in the physical domain (i.e. +excluding halos), as saved to the `chksum_diag` output file. + +Additional diagnostics do not report as a fail, and are not tracked by any CIs, +but the test will report a warning to the user. + + +## Build configuration + +The test suite defines a DEBUG and a REPRO build, which resemble targets used +at GFDL. The DEBUG build is intended for detecting potential errors and +troubleshooting, while the REPRO build has typically been optimized for +production runs. + +Ideally, the DEBUG and REPRO runs will produce identical results, although this +is often not the case for many compilers and platforms. The `DO_REPRO_TEST` +flag is used to test DEBUG/REPRO equivalency. + +The following options are provided to configure your compiler flags. + +`FCFLAGS_DEBUG` (*default:* `-g -O0`) + + Specify the flags used in the DEBUG build. These are the flags used for all + tests excepting the REPRO builds. They are also used to build the FMS + library. + + These should be used to enable settings favorable to debugging, such as no + optimizations, backtraces, range checking, and warning. + + For more aggressive flags which cannot be used with FMS, see `FCFLAGS_INIT`. + +`FCFLAGS_REPRO:` (*default:* `-g -O2`) + + Specify the optimized reproducible run, typically used in production runs. + + Ideally, this should consist of optimization flags which improve peformance + but do not change model output. In practice, this is difficult to achieve. + +`FCFLAGS_INIT` (*default: none*) + + This flag was historically used to specify variable initialization, such as + nonzero integers or floating point values, and is still generally used for + this purpose. + + As implemented, it is used for all MOM6 builds. It is not used for FMS + builds, so can also act as a debugging flag independent of FMS. + +`FCFLAGS_COVERAGE` (*default: none*) + + This flag is used to define a build which supports some sort of code + coverage, often one which is handled by the CI. + For many compilers, this is `--coverage`, and is applied to both the + compiler (`FCFLAGS`) and linker (`LDFLAGS`). + +Example values used by GFDL and Travis for the GFortran compiler are shown +below. +``` +FCFLAGS_DEBUG="-g -O0 -Wextra -Wno-compare-reals -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds" +FCFLAGS_REPRO="-g -O2 -fbacktrace" +FCFLAGS_INIT="-finit-real=snan -finit-integer=2147483647 -finit-derived" +FCFLAGS_COVERAGE="--coverage" +``` + +Note that the default values for these flags are very minimal, in order to +ensure compatibility over the largest possible range of compilers. + +Like all configuration variables, these can be specified in a `config.mk` file. ## Building the executables @@ -73,64 +151,51 @@ configuration uses the symmetric grid in the debug-compile mode, with optimizations disabled and stronger quality controls. The following executables will be created: -- `build/symmetric/MOM6`: Symmetric grid configuration (extended grids along - western and/or southern boundaries). This is the default configuration. +- `build/symmetric/MOM6`: Symmetric grid configuration (i.e. extended grids + along western and/or southern boundaries for selected fields). This is the + default configuration. - `build/asymmetric/MOM6`: Non-symmetric grid (equal-sized grids) - `build/repro/MOM6`: Optimized reproducible mode -- (optional) `build/target/MOM6`: A reference build for regression testing +- `build/target/MOM6`: A reference build for regression testing -The `target` build is only created when the `DO_REGRESSION_TESTS` flag is set -to `true`: -``` -make DO_REGRESSION_TESTS=true -``` -When set, the build will check out a second copy of the repository from a -specified URL and branch given by `MOM_TARGET_URL` and `MOM_TARGET_BRANCH`, -respectively. The code is checked out into the `TARGET_CODEBASE` directory. +- `build/openmp/MOM6`: OpenMP-enabled build -The current default settings are +The `target` and `repro` builds are only created when their respective tests +are set to `true`. + +### Regression testing + +When regression tests are enabled, the Makefile will check out a second copy of +the repository from a specified URL and branch given by `MOM_TARGET_URL` and +`MOM_TARGET_BRANCH`, respectively. The code is checked out into the +`TARGET_CODEBASE` directory. + +The default settings, with resolved values as comments, are shown below. ``` MOM_TARGET_SLUG = NOAA-GFDL/MOM6 MOM_TARGET_URL = https://github.com/$(MOM_TARGET_SLUG) -# = https://github.com/NOAA-GFDL/MOM6 + #= https://github.com/NOAA-GFDL/MOM6 MOM_TARGET_LOCAL_BRANCH = dev/gfdl MOM_TARGET_BRANCH = origin/$(MOM_TARGET_LOCAL_BRANCH) -# = origin/dev/gfdl + #= origin/dev/gfdl TARGET_CODEBASE = $(BUILD)/target_codebase ``` These default values can be configured to target a particular development branch. - -#### MKMF template - -The MKMF build toolchain requires a template file when building the model. The -default template, `ncrc-gnu.mk`, is part of the MKMF repository, but has been -specifically configured for use on NOAA's Gaea computer, and other institutes -will require their own template files. - -The template can be specified as a Make flag. -``` -make MKMF_TEMPLATE=/path/to/template.mk -``` -The `linux-ubuntu-xenial-gnu.mk` template is provided in the `.testing` -directory, and is intended for Travis-CI builds, but may also be a good -reference point for other Linux distributions. - -In the future, this step may be replaced with a more generalized build system, -such as CMake or automake. +Currently the target can only be specifed by branch name, rather than hash. ## Tests -Using `test` will run through the test suite. +Using `test` will run through the full test suite. ``` make test ``` -This will run through the following tests: +The tests are gathered into the following groups. - `test.regressions`: Regression tests relative to a code state (when enabled) - `test.grids`: Symmetric vs nonsymmetric grids @@ -140,13 +205,7 @@ This will run through the following tests: - `test.nans`: NaN initialization of allocated arrays - `test.dims`: Dimensional scaling (length, time, thickness, depth) -To enable the regression tests, use `DO_REGRESSION_TEST=true`. -``` -make test DO_REGRESSION_TESTS=true -``` - -Each test can also be run individually. For example, the following command -will only run the grid tests. +Each group of tests can also be run individually. ``` make test.grids ``` @@ -157,15 +216,15 @@ fail if the answers differ from this build. ## Test configurations -The following test configurations (TCs) are supported: +The following model test configurations (TCs) are supported: -- tc0: Unit testing of various model components, based on `unit_tests` -- tc1: A low-resolution version of the `benchmark` configuration - - tc1.a: Use the un-split mode with Runge-Kutta 3 time integration - - tc1.b: Use the un-split mode with Runge-Kutta 2 time integration -- tc2: An ALE configuration based on tc1 with tides - - tc2.a: Use sigma, PPM_H4 and no tides -- tc3: An open-boundary condition (OBC) test based on `circle_obcs` +- `tc0`: Unit testing of various model components, based on `unit_tests` +- `tc1`: A low-resolution version of the `benchmark` configuration + - `tc1.a`: Use the un-split mode with Runge-Kutta 3 time integration + - `tc1.b`: Use the un-split mode with Runge-Kutta 2 time integration +- `tc2`: An ALE configuration based on tc1 with tides + - `tc2.a`: Use sigma, PPM_H4 and no tides +- `tc3`: An open-boundary condition (OBC) test based on `circle_obcs` ## Code coverage @@ -194,6 +253,8 @@ suite is triggered and the code changes are tested. When the tests are run on Travis, the following variables are re-defined: +- `DO_REPRO_TESTS` is set to `true` for all tests. + - `DO_REGRESSION_TESTS` is set to `true` for a PR submission, and is unset for code pushes. @@ -209,18 +270,3 @@ When the tests are run on Travis, the following variables are re-defined: a PR, this is the name of the branch which is receiving the PR. - `REPORT_COVERAGE` is set to `true`. - -## Running under slurm - -By default the executables are invoked using `mpirun`. Under slurm you might need to -use `srun` (such as on GFDL's gaea HPC): -``` -make MPIRUN=srun test -``` - -For convenience you can provide some macro in the file `config.mk`. For example, on -gaea, to be able to run `make test -s -j` you will find putting the line -``` -MPIRUN = srun -mblock --exclusive -``` -in `config.mk` very useful. From b01af9d2e4ff6575a0c416c3cc338de6f66ba0c4 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Thu, 17 Sep 2020 15:53:41 -0400 Subject: [PATCH 19/23] Autoconf: Documentation, make ac-clean fix Added several documentation READMEs to using the autoconf build. Also added some changes to the Makefile template so that `make ac-clean` wiped out the autoconf output (configure, aclocal.m4, autom4te.cache). --- README.md | 16 ++++- ac/Makefile.in | 6 +- ac/README.md | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 4 deletions(-) create mode 100644 ac/README.md diff --git a/README.md b/README.md index 3e4ff016e3..842186ceb1 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,14 @@ This is the MOM6 source code. + # Where to find information Start at the [MOM6-examples wiki](https://github.com/NOAA-GFDL/MOM6-examples/wiki) which has installation instructions. [Source code documentation](http://mom6.readthedocs.io/) is hosted on read the docs. + # What files are what The top level directory structure groups source code and input files as follow: @@ -23,7 +25,19 @@ The top level directory structure groups source code and input files as follow: | ```src/``` | Contains the source code for MOM6 that is always compiled. | | ```config_src/``` | Contains optional source code depending on mode and configuration such as dynamic-memory versus static, ocean-only versus coupled. | | ```pkg/``` | Contains third party (non-MOM6 or FMS) code that is compiled into MOM6. | -| ```docs/``` | Workspace for generated documentation. | +| ```docs/``` | Workspace for generated documentation. See [docs/README.md](docs/README.md) | +| ```.testing/``` | COntains the verification test suite. See [.testing/README.md](testing/README.md) | +| ```ac/``` | Contains the autoconf build configuration files. See [ac/README.md](ac/README.md) | + + +# Quick start guide + +To quickly get started and build an ocean-only MOM6 executable, see the +[autoconf README](ac/README.md). + +For setting up an experiment, or building an executable for coupled modeling, +consult the [MOM6-examples wiki](https://github.com/NOAA-GFDL/MOM6-examples/wiki). + # Disclaimer diff --git a/ac/Makefile.in b/ac/Makefile.in index 81d9f9a8e4..ce8173e6f1 100644 --- a/ac/Makefile.in +++ b/ac/Makefile.in @@ -73,6 +73,6 @@ distclean: clean # Don't be surprised if the name changes or if it disappears someday. .PHONY: ac-clean ac-clean: distclean - rm -f aclocal.m4 - rm -rf autom4te.cache - rm -f configure + rm -f @srcdir@/ac/aclocal.m4 + rm -rf @srcdir@/ac/autom4te.cache + rm -f @srcdir@/ac/configure diff --git a/ac/README.md b/ac/README.md new file mode 100644 index 0000000000..5cc14b448b --- /dev/null +++ b/ac/README.md @@ -0,0 +1,177 @@ +# Autoconf Build Configuration + +This directory contains the configuration files required to build MOM6 using +autoconf. + +Note that a top-level `./configure` is not contained in the repository, and the +instruction below will generate this script in the `ac` directory. + + +# Requirements + +The following tools and libraries must be installed on your system. + +* autoconf +* Fortran compiler (e.g. gfortran) +* MPI (e.g. Open MPI, MPICH) +* netCDF, with Fortran support + +On some platforms, such as macOS, the autoconf package may also require an +installation of automake. + +Some packages such as netCDF may require an additional packages for Fortran +support. + + +# Quick start guide + +The following instructions will allow a new user to quickly create a MOM6 +executable for ocean-only simulations. + +A separate Makefile in `ac/deps/` is provided to gather and build any GFDL +dependencies. +``` +cd ac/deps +make -j +``` +This will fetch the `mkmf` tool and build the `libFMS` library. + +To build MOM6, first generate the autconf `configure` script. +``` +cd ac +autoreconf +``` +Then select your build directory, e.g. `./build`, run the configure script, and +build the model. +``` +mkdir -p build +cd build +../ac/configure +make -j +``` +This will create the MOM6 executable in the build directory. + +This executable is only useable for ocean-only simulations, and still requires +the necessary experiment configuration files, such as `input.nml` and +`MOM_input`. For more information, consult the +[MOM6-examples wiki](https://github.com/NOAA-GFDL/MOM6-examples/wiki). + + +# Build rules + +The Makefile produced by autoconf provides the following rules. + +``make`` + + Build the MOM6 executable. + +``make clean`` + + Delete the executable and any object and module files, but preserve the + autoconf output. + +``make distclean`` + + Delete all of the files above, as well as any files generated by + `./configure`. Note that this will delete the Makefile containing this rule. + +``make ac-clean`` + + Delete all of the files above, including `./configure` and any other files + created by `autoconf`. As with `make distclean`, this will also delete the + Makefile containing this rule. + + +# Build configuration settings + +Autoconf will resolve most model depenencies, and includes the standard set +of configuration options, such as `FC` or `FCFLAGS`. The MOM6-specific +`configure` script settings are described below. + +`--enable-asymmetric` + + The MOM6 executable is configured to use symmetric grids by default. + + Use the flag above to compile using uniform asymmetric grids. + + Symmetric grids are defined such that the fields for every C-grid cell are + fully specified by their local values. In particular, quantities such as + velocities or vorticity will be defined along the boundaries of the domain. + + Use of symmetric grids simplifies calculations, but also results in + nonuniform domain sizes for different fields, and slightly greater storage + since the additional values can be considered redundant. + +`--enable-openmp` + + Use this flag to enable OpenMP in the build. + +`--disable-real-8` + + While MOM6 does not explicitly use double-precision reals, most of the + algorithms are designed and tested under this assumption. + + This flag may be used to disable these flags, causing the compiler to use the + default size (usually single-precision), although there is no guarantee that + the model will be useable. + +For the complete list of settings, run `./configure --help`. + + +# GFDL Dependencies + +This section briefly describes the management of GFDL dependencies `mkmf` and +FMS. + +The `configure` script will first check if the compiler flags (`FCFLAGS`, +`LDFLAGS`, etc.) can find `mkmf` and the FMS library. If unavailable, then it +will search in the local `ac/deps` library. If still unavailable, because it +has not yet been built, then the build will abort. + +Running `make -C ac/deps` will ensure that the libraries are available. But if +the user wishes to target an external FMS library, then they should add the +appropriate `FCFLAGS` and `LDFLAGS` to find the library. + +Similar options are provided for `mkmf` with respect to `PATH`, although it +is usually not necessary to use an external `mkmf` script. + +Some configuration options are provided by the `ac/deps` Makefile: + +`PATH_ENV` + + This variable will override the value of `PATH` when building the dependencies. + +`FCFLAGS_ENV` + + Used to override the default autoconf flags, `-g -O2`. This is useful if, + for example, one wants to build with `-O0` to speed up the build time. + +`MKMF_URL` (*default:* https://github.com/NOAA-GFDL/mkmf.git) +`MKMF_COMMIT`(*default:* `master`) +`FMS_URL` (*default:* https://github.com/NOAA-GFDL/FMS.git) +`FMS_COMMIT` (*default:* `2019.01.03`) + + These are used to specify where to check out the source code for each + respective project. + + +# Known issues / Future development + +## MPI configuration + +There are minor issues with the MPI configuration macro, where it may locate an +MPI launcher based on a compiler which does not match the corresponding +compiler, `FC`, which will tend to default to GFortran. + +This is usually not an issue, but can cause confusion when the `FCFLAGS` were +configured for the launcher but do not work with `FC`, whose value is only used +in the initial `configure` testing. + +To resolve this, ensure that `FC` and `FCFLAGS` are specified for the same +compiler. + +## Coupled builds + +The autoconf build is currently only capable of building ocean-only +executables, and cannot yet be build as a standalone library. This is planned +to be addressed in a future release. From 255ee70da0d20a4ab127d6fc515ff5176d4691ac Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Thu, 17 Sep 2020 16:41:29 -0400 Subject: [PATCH 20/23] Autoconf/Testing README proofreading --- .testing/README.md | 52 +++++++++++++----------- ac/README.md | 99 +++++++++++++++++++++++++--------------------- 2 files changed, 81 insertions(+), 70 deletions(-) diff --git a/.testing/README.md b/.testing/README.md index 5e1a088725..adc56e56cd 100644 --- a/.testing/README.md +++ b/.testing/README.md @@ -11,11 +11,9 @@ This section gives a very brief overview of the test suite and how to use it. To build and run the model tests: ``` -make -make test +make -j +make -j test ``` -Users may wish to use `make -j` in place of `make` to enable parallel builds. - For new users, the default configuration should be suitable for most platforms. If not, then the following options may need to be configured. @@ -33,12 +31,12 @@ If not, then the following options may need to be configured. Set to `true` to compare DEBUG and REPRO builds, which typically correspond to unoptimized and optimized builds. See TODO for more information. -These settings can either be specified at the command line, as shown below. +These settings can either be specified at the command line, as shown below ``` make DO_REGRESSION_TESTS=true make test DO_REGRESSION_TESTS=true ``` -or saved to `config.mk`. +or saved in a configuration file, `config.mk`. To run individual classes of tests, use the subclass name: ``` @@ -58,7 +56,7 @@ names and descriptions of the test classes and configurations. ## Testing overview -The test suite checks for numerical consistency of the model output of +The test suite checks for numerical consistency of the model output across different model configurations when subjected to relevant numerical and mathematical transformations, such as grid layout or dimensional rescaling. If the model state is unchanged after each transformation, then the test is @@ -67,14 +65,11 @@ fail. Model state is currently defined by the `ocean.stats` output file, which reports the total energy (per unit mass) at machine precision alongside similar -global metrics, such as mass or mean sea level, at lower precision. +global metrics at lower precision, such as mass or mean sea level. Diagnostics are based on the MOM checksum function, which includes the mean, -minimum, and maximum values as well as a bitcount in the physical domain (i.e. -excluding halos), as saved to the `chksum_diag` output file. - -Additional diagnostics do not report as a fail, and are not tracked by any CIs, -but the test will report a warning to the user. +minimum, and maximum values, alongside a bitcount checksum, in the physical +domain, which are saved in the `chksum_diag` output file. ## Build configuration @@ -97,16 +92,18 @@ The following options are provided to configure your compiler flags. library. These should be used to enable settings favorable to debugging, such as no - optimizations, backtraces, range checking, and warning. + optimizations, backtraces, range checking, and warnings. - For more aggressive flags which cannot be used with FMS, see `FCFLAGS_INIT`. + For more aggressive debugging flags which cannot be used with FMS, see + `FCFLAGS_INIT`. `FCFLAGS_REPRO:` (*default:* `-g -O2`) Specify the optimized reproducible run, typically used in production runs. Ideally, this should consist of optimization flags which improve peformance - but do not change model output. In practice, this is difficult to achieve. + but do not change model output. In practice, this is difficult to achieve, + and should only used in certain environments. `FCFLAGS_INIT` (*default: none*) @@ -122,7 +119,7 @@ The following options are provided to configure your compiler flags. This flag is used to define a build which supports some sort of code coverage, often one which is handled by the CI. - For many compilers, this is `--coverage`, and is applied to both the + For many compilers, this is set to `--coverage`, and is applied to both the compiler (`FCFLAGS`) and linker (`LDFLAGS`). Example values used by GFDL and Travis for the GFortran compiler are shown @@ -139,6 +136,7 @@ ensure compatibility over the largest possible range of compilers. Like all configuration variables, these can be specified in a `config.mk` file. + ## Building the executables Run `make` to build the test executables. @@ -149,7 +147,7 @@ This will fetch the MKMF build toolchain, fetch and compile the FMS framework library, and compile the executables used in the test suite. The default configuration uses the symmetric grid in the debug-compile mode, with optimizations disabled and stronger quality controls. The following -executables will be created: +executables will be created. - `build/symmetric/MOM6`: Symmetric grid configuration (i.e. extended grids along western and/or southern boundaries for selected fields). This is the @@ -166,6 +164,7 @@ executables will be created: The `target` and `repro` builds are only created when their respective tests are set to `true`. + ### Regression testing When regression tests are enabled, the Makefile will check out a second copy of @@ -188,6 +187,9 @@ branch. Currently the target can only be specifed by branch name, rather than hash. +New diagnostics do not report as a fail, and are not tracked by any CIs, but +the test will report a warning to the user. + ## Tests @@ -205,7 +207,8 @@ The tests are gathered into the following groups. - `test.nans`: NaN initialization of allocated arrays - `test.dims`: Dimensional scaling (length, time, thickness, depth) -Each group of tests can also be run individually. +Each group of tests can also be run individually, such as in the following +example. ``` make test.grids ``` @@ -216,7 +219,8 @@ fail if the answers differ from this build. ## Test configurations -The following model test configurations (TCs) are supported: +The following model test configurations (TCs) are supported, and are based on +configurations in the MOM6-examples repository. - `tc0`: Unit testing of various model components, based on `unit_tests` - `tc1`: A low-resolution version of the `benchmark` configuration @@ -229,13 +233,13 @@ The following model test configurations (TCs) are supported: ## Code coverage -Code coverage reports the lines of code which have been tested, and can -explicitly demonstrate when a particular operation is untested. +Code coverage reports the lines of code which have been tested, and can be used +to determine if a particular section is untested. Coverage is measured using `gcov` and is reported for TCs using the `symmetric` executable. -Coverage reporting is optionally sent to the `codecov.io` site. +Coverage reporting is optionally uploaded to the `codecov.io` site. ``` https://codecov.io/gh/NOAA-GFDL/MOM6 ``` @@ -243,7 +247,7 @@ This is disabled on default, but can be enabled by the `REPORT_COVERAGE` flag. ``` make test REPORT_COVERAGE=true ``` -Note that any uploads will require a valid token generated by CodeCov. +Note that any uploads will require a valid CodeCov token. ## Running on Travis diff --git a/ac/README.md b/ac/README.md index 5cc14b448b..d02f793a86 100644 --- a/ac/README.md +++ b/ac/README.md @@ -1,7 +1,7 @@ # Autoconf Build Configuration This directory contains the configuration files required to build MOM6 using -autoconf. +Autoconf. Note that a top-level `./configure` is not contained in the repository, and the instruction below will generate this script in the `ac` directory. @@ -11,13 +11,13 @@ instruction below will generate this script in the `ac` directory. The following tools and libraries must be installed on your system. -* autoconf -* Fortran compiler (e.g. gfortran) +* Autoconf +* Fortran compiler (e.g. GFortran) * MPI (e.g. Open MPI, MPICH) * netCDF, with Fortran support -On some platforms, such as macOS, the autoconf package may also require an -installation of automake. +On some platforms, such as macOS, the Autoconf package may also require an +installation of Automake. Some packages such as netCDF may require an additional packages for Fortran support. @@ -28,38 +28,41 @@ support. The following instructions will allow a new user to quickly create a MOM6 executable for ocean-only simulations. +Each set of instructions is meant to be run from the root directory of the +repository. + A separate Makefile in `ac/deps/` is provided to gather and build any GFDL dependencies. ``` -cd ac/deps -make -j +$ cd ac/deps +$ make -j ``` -This will fetch the `mkmf` tool and build the `libFMS` library. +This will fetch the `mkmf` tool and build the FMS library. -To build MOM6, first generate the autconf `configure` script. +To build MOM6, first generate the Autoconf `configure` script. ``` -cd ac -autoreconf +$ cd ac +$ autoreconf ``` Then select your build directory, e.g. `./build`, run the configure script, and build the model. ``` -mkdir -p build -cd build -../ac/configure -make -j +$ mkdir -p build +$ cd build +$ ../ac/configure +$ make -j ``` This will create the MOM6 executable in the build directory. -This executable is only useable for ocean-only simulations, and still requires -the necessary experiment configuration files, such as `input.nml` and -`MOM_input`. For more information, consult the +This executable is only useable for ocean-only simulations, and cannot be used +for coupled modeling. It also requires the necessary experiment configuration +files, such as `input.nml` and `MOM_input`. For more information, consult the [MOM6-examples wiki](https://github.com/NOAA-GFDL/MOM6-examples/wiki). # Build rules -The Makefile produced by autoconf provides the following rules. +The Makefile produced by Autoconf provides the following rules. ``make`` @@ -68,7 +71,7 @@ The Makefile produced by autoconf provides the following rules. ``make clean`` Delete the executable and any object and module files, but preserve the - autoconf output. + Autoconf output. ``make distclean`` @@ -78,27 +81,27 @@ The Makefile produced by autoconf provides the following rules. ``make ac-clean`` Delete all of the files above, including `./configure` and any other files - created by `autoconf`. As with `make distclean`, this will also delete the + created by `autoreconf`. As with `make distclean`, this will also delete the Makefile containing this rule. # Build configuration settings -Autoconf will resolve most model depenencies, and includes the standard set -of configuration options, such as `FC` or `FCFLAGS`. The MOM6-specific -`configure` script settings are described below. +Autoconf will resolve most model dependencies, and includes the standard set of +configuration options, such as `FC` or `FCFLAGS`. The `configure` settings +specific to MOM6 are described below. `--enable-asymmetric` The MOM6 executable is configured to use symmetric grids by default. - Use the flag above to compile using uniform asymmetric grids. + Use the flag above to compile using uniform (asymmetric) grids. Symmetric grids are defined such that the fields for every C-grid cell are fully specified by their local values. In particular, quantities such as - velocities or vorticity will be defined along the boundaries of the domain. + velocities or vorticity are defined along the boundaries of the domain. - Use of symmetric grids simplifies calculations, but also results in + Use of symmetric grids simplifies many calculations, but also results in nonuniform domain sizes for different fields, and slightly greater storage since the additional values can be considered redundant. @@ -108,12 +111,13 @@ of configuration options, such as `FC` or `FCFLAGS`. The MOM6-specific `--disable-real-8` - While MOM6 does not explicitly use double-precision reals, most of the - algorithms are designed and tested under this assumption. + While MOM6 does not explicitly use double precision reals, most of the + algorithms are designed and tested under this assumption, and the default + configuration is to enforce 8-byte reals. - This flag may be used to disable these flags, causing the compiler to use the - default size (usually single-precision), although there is no guarantee that - the model will be useable. + This flag may be used to relax this requirement, causing the compiler to use + the default size (usually single precision reals), although there is no + guarantee that the model will be usable. For the complete list of settings, run `./configure --help`. @@ -123,10 +127,10 @@ For the complete list of settings, run `./configure --help`. This section briefly describes the management of GFDL dependencies `mkmf` and FMS. -The `configure` script will first check if the compiler flags (`FCFLAGS`, -`LDFLAGS`, etc.) can find `mkmf` and the FMS library. If unavailable, then it -will search in the local `ac/deps` library. If still unavailable, because it -has not yet been built, then the build will abort. +The `configure` script will first check if the compiler and its configured +flags (`FCFLAGS`, `LDFLAGS`, etc.) can find `mkmf` and the FMS library. If +unavailable, then it will search in the local `ac/deps` library. If still +unavailable, then the build will abort. Running `make -C ac/deps` will ensure that the libraries are available. But if the user wishes to target an external FMS library, then they should add the @@ -143,7 +147,7 @@ Some configuration options are provided by the `ac/deps` Makefile: `FCFLAGS_ENV` - Used to override the default autoconf flags, `-g -O2`. This is useful if, + Used to override the default Autoconf flags, `-g -O2`. This is useful if, for example, one wants to build with `-O0` to speed up the build time. `MKMF_URL` (*default:* https://github.com/NOAA-GFDL/mkmf.git) @@ -154,24 +158,27 @@ Some configuration options are provided by the `ac/deps` Makefile: These are used to specify where to check out the source code for each respective project. +Additional hooks for FMS builds do not yet exist, but can be added if +necessary. + # Known issues / Future development ## MPI configuration -There are minor issues with the MPI configuration macro, where it may locate an -MPI launcher based on a compiler which does not match the corresponding -compiler, `FC`, which will tend to default to GFortran. +There are minor issues with the MPI configuration macro, where it may use an +MPI build wrapper (e.g. `mpifort`) whose underlying compiler does not match +the `FC` compiler, which will often be auto-configured to `gfortran`. -This is usually not an issue, but can cause confusion when the `FCFLAGS` were -configured for the launcher but do not work with `FC`, whose value is only used -in the initial `configure` testing. +This is usually not an issue, but can cause confusion if `FCFLAGS` is +configured for the MPI wrapper but is incompatible with the `FC` compiler. To resolve this, ensure that `FC` and `FCFLAGS` are specified for the same compiler. + ## Coupled builds -The autoconf build is currently only capable of building ocean-only -executables, and cannot yet be build as a standalone library. This is planned -to be addressed in a future release. +The Autoconf build is currently only capable of building ocean-only +executables, and cannot yet be build as part of a coupled more, nor as a +standalone library. This is planned to be addressed in a future release. From 3f176cca0d831f748cd69a4b3721df53038853d1 Mon Sep 17 00:00:00 2001 From: Alistair Adcroft Date: Thu, 17 Sep 2020 17:18:31 -0400 Subject: [PATCH 21/23] Corrected minor typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 842186ceb1..17cf0310db 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ The top level directory structure groups source code and input files as follow: | ```config_src/``` | Contains optional source code depending on mode and configuration such as dynamic-memory versus static, ocean-only versus coupled. | | ```pkg/``` | Contains third party (non-MOM6 or FMS) code that is compiled into MOM6. | | ```docs/``` | Workspace for generated documentation. See [docs/README.md](docs/README.md) | -| ```.testing/``` | COntains the verification test suite. See [.testing/README.md](testing/README.md) | +| ```.testing/``` | Contains the verification test suite. See [.testing/README.md](testing/README.md) | | ```ac/``` | Contains the autoconf build configuration files. See [ac/README.md](ac/README.md) | From 500a960fee973c95c7b3d862d5ee8faaf666229a Mon Sep 17 00:00:00 2001 From: Alistair Adcroft Date: Thu, 17 Sep 2020 17:20:32 -0400 Subject: [PATCH 22/23] Fixed typo replacing "more" with "model" Pointed out by @raphaeldussin --- ac/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ac/README.md b/ac/README.md index d02f793a86..a708979572 100644 --- a/ac/README.md +++ b/ac/README.md @@ -180,5 +180,5 @@ compiler. ## Coupled builds The Autoconf build is currently only capable of building ocean-only -executables, and cannot yet be build as part of a coupled more, nor as a +executables, and cannot yet be build as part of a coupled model, nor as a standalone library. This is planned to be addressed in a future release. From f0201a45a0f02bc8050129b3e7b580b87350f429 Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Thu, 17 Sep 2020 17:50:21 -0400 Subject: [PATCH 23/23] Update README.md Typo fix --- ac/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ac/README.md b/ac/README.md index a708979572..12cfbf2b00 100644 --- a/ac/README.md +++ b/ac/README.md @@ -180,5 +180,5 @@ compiler. ## Coupled builds The Autoconf build is currently only capable of building ocean-only -executables, and cannot yet be build as part of a coupled model, nor as a +executables, and cannot yet be built as part of a coupled model, nor as a standalone library. This is planned to be addressed in a future release.