Skip to content

Commit 1cd2736

Browse files
authored
Support for enabling optional MPAS features through CIME (#351)
### Tag name (required for release branches): None ### Originator(s): kuanchihwang ### Descriptions (include the issue title, and the keyword ['closes', 'fixes', 'resolves'] followed by the issue number): This PR refactors the build system of MPAS dycore. Build performance has been improved. PIO version selection is now more robust. The availability of optional MPAS features is now determined by querying relevant configuration options from CIME rather than being hard-coded. MPAS dycore is in double precision mode by default. Users can choose to enable single precision mode by running: ```bash ./xmlchange --append CAM_CONFIG_OPTS="--dyn-kind REAL32" ``` Closes #347. ### Describe any changes made to the build system: See above. ### Describe any changes made to the namelist: None ### List any changes to the defaults for the input datasets (e.g., boundary datasets): None ### List all files eliminated and why: None ### List all files added and what they do: None ### List all existing files that have been modified, and describe the changes: * `M cime_config/buildlib` * Support for enabling optional MPAS features through CIME * Remove trailing spaces * `M src/dynamics/mpas/assets/Makefile.in.CESM` * Avoid using recursively expanded variables * Make PIO version selection more robust * Support for enabling optional MPAS features through CIME ### Regression tests: No changes to any existing tests with respect to the last baseline, `sima0_03_000`. * SMS_Ln9.ne5pg3_ne5pg3_mg37.FCAM7.derecho_gnu.cam-outfrq_se_cslam_analy_ic (Overall: FAIL) * SMS_Ln9.ne5pg3_ne5pg3_mg37.FCAM7.derecho_intel.cam-outfrq_se_cslam_analy_ic (Overall: FAIL) * Existing test failures
1 parent 8b4d541 commit 1cd2736

File tree

2 files changed

+87
-52
lines changed

2 files changed

+87
-52
lines changed

cime_config/buildlib

+21-9
Original file line numberDiff line numberDiff line change
@@ -147,28 +147,40 @@ def _build_cam():
147147
# build the library
148148
#-------------------------------------------------------
149149

150-
# If dynamical core is MPAS, setup its build infrastructure so it can be built along with CAM below.
151-
if dycore == "mpas":
152-
_setup_mpas(case)
153-
154150
complib = os.path.join(libroot, "libatm.a")
155151
makefile = os.path.join(casetools, "Makefile")
156152

157153
cmd = f"{gmake} complib -j {gmake_j} MODEL=cam COMPLIB={complib}"
158-
cmd += f" -f {makefile} {get_standard_makefile_args(case)} "
154+
cmd += f" -f {makefile} {get_standard_makefile_args(case)}"
159155

160156
# Add C Pre-Processor (CPP) definitions, if present:
161157
if config.cpp_defs:
162158
ccpp_defs_str = ' '.join(config.cpp_defs)
163159
cmd += f" USER_CPPDEFS='{ccpp_defs_str}'"
164160

161+
# If dynamical core is MPAS, prepare its build infrastructure so it can be built along with CAM-SIMA below.
162+
if dycore == "mpas":
163+
_prepare_mpas(case)
164+
165+
optional_mpas_features = []
166+
167+
if case.get_value("USE_ESMF_LIB"):
168+
optional_mpas_features.append("+ESMF_LIBRARY")
169+
optional_mpas_features.append("+PERF_MOD_LIBRARY")
170+
171+
if config.get_value("dyn_kind") == "REAL32":
172+
optional_mpas_features.append("+SINGLE_PRECISION")
173+
174+
if len(optional_mpas_features) > 0:
175+
cmd += " OPTIONAL_MPAS_FEATURES=\"" + " ".join(optional_mpas_features) + "\""
176+
165177
retcode, out, err = run_cmd(cmd)
166-
_LOGGER.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n", cmd, out, err)
178+
_LOGGER.info("Command %s:\n\nstdout:\n%s\n\nstderr:\n%s\n", cmd, out, err)
167179
expect(retcode == 0, f"Command {cmd} failed with rc={retcode}")
168180

169-
def _setup_mpas(case: Case) -> None:
181+
def _prepare_mpas(case: Case) -> None:
170182
"""
171-
Setup MPAS build infrastructure.
183+
Prepare MPAS build infrastructure.
172184
"""
173185

174186
atm_src_root = os.path.normpath(case.get_value("COMP_ROOT_DIR_ATM"))
@@ -177,7 +189,7 @@ def _setup_mpas(case: Case) -> None:
177189
mpas_dycore_src_root = os.path.join(atm_src_root, "src", "dynamics", "mpas", "dycore", "src")
178190
mpas_dycore_bld_root = os.path.join(atm_bld_root, "mpas")
179191

180-
# Make sure `mpas_dycore_src_root` exists. If not, it is likely that `./manage_externals/checkout_externals` did not succeed.
192+
# Make sure `mpas_dycore_src_root` exists. If not, it is likely that `./bin/git-fleximod update` did not succeed.
181193
if os.path.isfile(mpas_dycore_src_root):
182194
raise FileExistsError(1, "Unexpected file", mpas_dycore_src_root)
183195

src/dynamics/mpas/assets/Makefile.in.CESM

+66-43
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,82 @@
1+
# `LIBROOT` is defined by CIME under normal circumstances.
12
ifeq ($(strip $(LIBROOT)),)
23
$(warning `LIBROOT` should not be empty. Defaulting to `..`)
34

4-
LIBROOT = ..
5+
LIBROOT := ..
56
endif
67

8+
# `SRCROOT` is defined by CIME under normal circumstances.
79
ifeq ($(strip $(SRCROOT)),)
810
$(warning `SRCROOT` should not be empty. Defaulting to `..`)
911

10-
SRCROOT = ..
11-
MPAS_SRC_ROOT = $(SRCROOT)
12+
SRCROOT := ..
13+
MPAS_SRC_ROOT := $(SRCROOT)
1214
else
13-
MPAS_SRC_ROOT = $(SRCROOT)/src/dynamics/mpas/dycore
15+
MPAS_SRC_ROOT := $(SRCROOT)/src/dynamics/mpas/dycore
16+
endif
17+
18+
# `PIO_VERSION` is defined by CIME under normal circumstances.
19+
ifeq ($(filter 1 2,$(PIO_VERSION)),)
20+
$(warning `PIO_VERSION` should have a value of `1` or `2`. Defaulting to `2`)
21+
22+
PIO_VERSION := 2
1423
endif
1524

1625
#
1726
# Define and export variables used by MPAS build infrastructure.
1827
#
1928

20-
export CP = cp -afv
21-
export LN = ln -fsv
22-
export MKDIR = mkdir -pv
23-
export RM = rm -frv
29+
export CP := cp -afv
30+
export LN := ln -fsv
31+
export MKDIR := mkdir -pv
32+
export RM := rm -frv
2433

2534
# Constants.
26-
export AUTOCLEAN = false
27-
export BUILD_TARGET = N/A
28-
export CORE = atmosphere
29-
export EXE_NAME = atmosphere_model
30-
export GEN_F90 = false
31-
export GIT_VERSION = $(shell git -C "$(MPAS_SRC_ROOT)" describe --always --dirty --tags || echo "N/A")
32-
export NAMELIST_SUFFIX = atmosphere
35+
export AUTOCLEAN := false
36+
export BUILD_TARGET := N/A
37+
export CORE := atmosphere
38+
export EXE_NAME := atmosphere_model
39+
export GEN_F90 := false
40+
export GIT_VERSION := $(shell git -C "$(MPAS_SRC_ROOT)" describe --always --dirty --tags || echo "N/A")
41+
export NAMELIST_SUFFIX := atmosphere
3342

3443
# Customize variables (e.g., build options) for use with CESM.
35-
export AR := ar
36-
export ARFLAGS := -M
37-
export CPP := cpp -P -traditional
38-
export CPPFLAGS := -D_MPI \
39-
-DMPAS_BUILD_TARGET="$(BUILD_TARGET)" \
40-
-DMPAS_CAM_DYCORE \
41-
-DMPAS_EXE_NAME="$(EXE_NAME)" \
42-
-DMPAS_EXTERNAL_ESMF_LIB \
43-
-DMPAS_GIT_VERSION="$(GIT_VERSION)" \
44-
-DMPAS_NAMELIST_SUFFIX="$(NAMELIST_SUFFIX)" \
45-
-DMPAS_NATIVE_TIMERS \
46-
-DMPAS_NO_ESMF_INIT \
47-
-DMPAS_PIO_SUPPORT
48-
# `PIODEF` is defined by CIME Makefile (i.e., `cime/CIME/Tools/Makefile`). Its value can be empty or `-DUSE_PIO2`.
49-
ifneq ($(strip $(PIODEF)),)
50-
export CPPFLAGS += $(strip $(PIODEF))
44+
export AR := ar
45+
export ARFLAGS := -M
46+
export CPP := cpp -P -traditional
47+
export CPPFLAGS := -D_MPI \
48+
-DMPAS_BUILD_TARGET="$(BUILD_TARGET)" \
49+
-DMPAS_CAM_DYCORE \
50+
-DMPAS_EXE_NAME="$(EXE_NAME)" \
51+
-DMPAS_GIT_VERSION="$(GIT_VERSION)" \
52+
-DMPAS_NAMELIST_SUFFIX="$(NAMELIST_SUFFIX)" \
53+
-DMPAS_PIO_SUPPORT
54+
ifeq ($(strip $(PIO_VERSION)),2)
55+
export CPPFLAGS += -DUSE_PIO2
56+
endif
57+
export LINKER := $(strip $(FC))
58+
export SCC := $(strip $(CC))
59+
export SCXX := $(strip $(CXX))
60+
export SFC := $(strip $(FC))
61+
62+
# Check for optional features.
63+
is-enabled = $(if $(filter +$(1),$(sort $(strip $(OPTIONAL_MPAS_FEATURES)))),true,false)
64+
65+
ifeq ($(call is-enabled,ESMF_LIBRARY),true)
66+
export CPPFLAGS += -DMPAS_EXTERNAL_ESMF_LIB \
67+
-DMPAS_NO_ESMF_INIT
68+
endif
69+
ifeq ($(call is-enabled,MPI_F08_INTERFACE),true)
70+
export CPPFLAGS += -DMPAS_USE_MPI_F08
71+
endif
72+
ifeq ($(call is-enabled,PERF_MOD_LIBRARY),true)
73+
export CPPFLAGS += -DMPAS_PERF_MOD_TIMERS
74+
else
75+
export CPPFLAGS += -DMPAS_NATIVE_TIMERS
76+
endif
77+
ifeq ($(call is-enabled,SINGLE_PRECISION),true)
78+
export CPPFLAGS += -DSINGLE_PRECISION
5179
endif
52-
# Uncomment below for MPI Fortran 2008 interface support. There is currently no corresponding option in CIME to enable this.
53-
# export CPPFLAGS += -DMPAS_USE_MPI_F08
54-
# Uncomment below for single precision mode support. There is currently no corresponding option in CIME to enable this.
55-
# export CPPFLAGS += -DSINGLE_PRECISION
56-
export LINKER := $(strip $(FC))
57-
export SCC := $(strip $(CC))
58-
export SCXX := $(strip $(CXX))
59-
export SFC := $(strip $(FC))
6080

6181
#
6282
# Targets.
@@ -67,12 +87,12 @@ all:
6787
@echo 'Supplemental Makefile for MPAS Dynamical Core in CESM'
6888
@echo ''
6989
@echo 'MPAS will be built as a static library located at `$${LIBROOT}/libmpas.a`.'
70-
@echo 'Users are responsible to provide all necessary build options via environment variables or command line arguments.'
90+
@echo 'Users are responsible for providing all necessary build options via environment variables or command line arguments.'
7191
@echo ''
7292
@echo 'Usage hints:'
73-
@echo ' `make libmpas-prepare ESM="CESM" LIBROOT="..." SRCROOT="..."`'
74-
@echo ' `make libmpas-build ESM="CESM" LIBROOT="..." SRCROOT="..."`'
75-
@echo ' `make libmpas-clean ESM="CESM" LIBROOT="..." SRCROOT="..."`'
93+
@echo ' `make libmpas-prepare ESM="CESM" LIBROOT="..." SRCROOT="..." PIO_VERSION="1|2"`'
94+
@echo ' `make libmpas-build ESM="CESM" LIBROOT="..." SRCROOT="..." PIO_VERSION="1|2"`'
95+
@echo ' `make libmpas-clean ESM="CESM" LIBROOT="..." SRCROOT="..." PIO_VERSION="1|2"`'
7696

7797
.PHONY: libmpas-prepare
7898
libmpas-prepare: libmpas-apply-patch libmpas-archiver-script.txt libmpas-preview
@@ -135,6 +155,9 @@ libmpas-clean: clean
135155

136156
.PHONY: externals
137157
externals: $(AUTOCLEAN_DEPS)
158+
ifeq ($(call is-enabled,ESMF_LIBRARY),false)
159+
( cd external; $(MAKE) FC="$(FC)" SFC="$(SFC)" CC="$(CC)" SCC="$(SCC)" FFLAGS="$(FFLAGS)" CFLAGS="$(CFLAGS)" CPP="$(CPP)" NETCDF="$(NETCDF)" CORE="$(CORE)" esmf_time )
160+
endif
138161
( cd external; $(MAKE) FC="$(FC)" SFC="$(SFC)" CC="$(CC)" SCC="$(SCC)" FFLAGS="$(FFLAGS)" CFLAGS="$(CFLAGS)" CPP="$(CPP)" NETCDF="$(NETCDF)" CORE="$(CORE)" ezxml-lib )
139162

140163
.PHONY: subdrv

0 commit comments

Comments
 (0)