Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure UM via models #139

Merged
merged 17 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions packages/um/model/vn13/rose-app.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Based on [email protected]/rose-stem/app/fcm_make_um/rose-app.conf
#meta=um-fcm-make/vn13.0

[env]
COUPLER=none
DR_HOOK=false
casim_rev=
casim_sources=
compile_atmos=preprocess-atmos build-atmos
!!compile_createbc=preprocess-createbc build-createbc
!!compile_crmstyle_coarse_grid=preprocess-crmstyle_coarse_grid build-crmstyle_coarse_grid
!!compile_pptoanc=preprocess-pptoanc build-pptoanc
compile_recon=preprocess-recon build-recon
!!compile_scm=preprocess-scm build-scm
!!compile_sstpert_lib=preprocess-sstpert_lib build-sstpert_lib
!!compile_wafccb_lib=preprocess-wafccb_lib build-wafccb_lib
config_revision=
config_root_path=fcm:um.xm_tr
config_type=atmos
eccodes=false
extract=extract
fcflags_overrides=
gwd_ussp_precision=double
jules_rev=
jules_sources=
land_surface_model=jules
ldflags_overrides_prefix=
ldflags_overrides_suffix=
ls_precipitation_precision=double
mirror=mirror
mpp_version=1C
netcdf=false
openmp=false
optimisation_level=safe
platagnostic=false
platform_config_dir=
portio_version=2A
prebuild=
!!recon_mpi=parallel
shumlib_rev=
shumlib_sources=
socrates_rev=
socrates_sources=
stash_version=1A
thread_utils=false
timer_version=3A
ukca_rev=
ukca_sources=
um_rev=
um_sources=
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ netcdf=true
openmp=true
optimisation_level=safe
platagnostic=false
platform_config_dir=nci-x86-ifort
platform_config_dir=
portio_version=2A
prebuild=
!!recon_mpi=parallel
Expand Down
49 changes: 49 additions & 0 deletions packages/um/model/vn13p5-rns/rose-app.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#meta=um-fcm-make/vn13.5

[env]
COUPLER=none
DR_HOOK=false
casim_rev=um13.5
casim_sources=fcm:casim.xm/branches/dev/paulfield/vn1.3_drop_agg_limit_and_switch@11187
compile_atmos=preprocess-atmos build-atmos
!!compile_createbc=preprocess-createbc build-createbc
!!compile_crmstyle_coarse_grid=preprocess-crmstyle_coarse_grid build-crmstyle_coarse_grid
!!compile_pptoanc=preprocess-pptoanc build-pptoanc
compile_recon=preprocess-recon build-recon
!!compile_scm=preprocess-scm build-scm
!!compile_sstpert_lib=preprocess-sstpert_lib build-sstpert_lib
!!compile_wafccb_lib=preprocess-wafccb_lib build-wafccb_lib
[email protected]
config_root_path=fcm:um.xm_tr
config_type=atmos
eccodes=true
extract=extract
fcflags_overrides=
gwd_ussp_precision=double
jules_rev=um13.5
jules_sources=
land_surface_model=jules
ldflags_overrides_prefix=
ldflags_overrides_suffix=
ls_precipitation_precision=double
mirror=mirror
mpp_version=1C
netcdf=true
openmp=true
optimisation_level=safe
platagnostic=false
platform_config_dir=
portio_version=2A
prebuild=
!!recon_mpi=parallel
shumlib_rev=um13.5
shumlib_sources=
socrates_rev=um13.5
socrates_sources=
stash_version=1A
thread_utils=false
timer_version=3A
ukca_rev=um13.5
ukca_sources=
um_rev=vn13.5
um_sources=fcm:um.xm/branches/dev/paulfield/vn13.5_casim_package_switches@124474
214 changes: 190 additions & 24 deletions packages/um/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import configparser
from spack.package import *
import llnl.util.tty as tty

class Um(Package):
"""
Expand All @@ -17,24 +18,96 @@ class Um(Package):
homepage = "https://code.metoffice.gov.uk/trac/um"
svn = "file:///g/data/ki32/mosrs/um/main/trunk"

# See 'fcm kp fcm:um.xm' for release versions
version("13.0", revision=111272, preferred=True)
version("13.1", revision=114076)
version("13.2", revision=116723)
version("13.3", revision=118802)
version("13.4", revision=120750)
version("13.5", revision=123226)
version("13.6", revision=124981)
# See 'fcm kp fcm:um.xm' for release versions.
_revision = {
"13.0": 111272,
"13.1": 114076,
"13.2": 116723,
"13.3": 118802,
"13.4": 120750,
"13.5": 123226,
"13.6": 124981}

version("13.0", revision=_revision["13.0"], preferred=True)
for v in range(1, 7):
_version = f"13.{str(v)}"
version(_version, revision=_revision[_version])

maintainers("penguian")

variant("optim", default="safe", description="Optimization level",
values=("debug", "high", "rigorous", "safe"), multi=False)
variant("platform", default="nci-x86-ifort", description="Site platform",
values=("nci-x86-ifort", "vm-x86-gnu"), multi=False)
variant("model", default="vn13", description="Model configuration.",
values=("vn13", "vn13p0-rns", "vn13p5-rns"), multi=False)

variant("optim", default="none", description="Optimization level",
values=("none", "debug", "high", "rigorous", "safe"), multi=False)
variant("site_platform", default="nci-x86-ifort", description="Site platform",
values="*", multi=False)

# Boolean variants have their default values set here because
# Spack does not have 3-value True, False, None logic.
_bool_off_variants = (
"DR_HOOK",
"platagnostic",
"thread_utils")
for b in _bool_off_variants:
variant(b, default=False, description=b, multi=False)

_bool_on_variants = (
"eccodes",
"netcdf",
"openmp")
for b in _bool_on_variants:
variant(b, default=True, description=b, multi=False)

_bool_variants = _bool_off_variants + _bool_on_variants

# String variants have their default values set to "none" here.
# The real default is set by the model.
_str_variants = (
"casim_rev",
"casim_sources",
"compile_atmos",
"compile_createbc",
"compile_crmstyle_coarse_grid",
"compile_pptoanc",
"compile_recon",
"compile_scm",
"compile_sstpert_lib",
"compile_wafccb_lib",
"config_revision",
"config_root_path",
"config_type",
"COUPLER",
"extract",
"fcflags_overrides",
"gwd_ussp_precision",
"jules_rev",
"jules_sources",
"land_surface_model",
"ldflags_overrides_prefix",
"ldflags_overrides_suffix",
"ls_precipitation_precision",
"mirror",
"mpp_version",
"portio_version",
"prebuild",
"recon_mpi",
"shumlib_rev",
"shumlib_sources",
"socrates_rev",
"socrates_sources",
"stash_version",
"timer_version",
"ukca_sources",
"ukca_rev",
"um_sources")
for v in _str_variants:
variant(v, default="none", description=v, values="*", multi=False)

# The 'site=nci-gadi' variant of fcm defines the keywords
# used by the FCM configuration of UM.
depends_on("fcm site=nci-gadi", type="build")

depends_on("fcm", type="build")
# For GCOM versions, see
# https://code.metoffice.gov.uk/trac/gcom/wiki/Gcom_meto_installed_versions
depends_on("[email protected]", when="@:13.0", type=("build", "link"))
Expand All @@ -43,8 +116,10 @@ class Um(Package):
depends_on("[email protected]", when="@13.3", type=("build", "link"))
depends_on("[email protected]", when="@13.4", type=("build", "link"))
depends_on("[email protected]:", when="@13.5:", type=("build", "link"))
depends_on("eccodes +fortran +netcdf", type=("build", "link", "run"))
depends_on("[email protected]", type=("build", "link", "run"))
depends_on("eccodes +fortran +netcdf", type=("build", "link", "run"),
when="+eccodes")
depends_on("[email protected]", type=("build", "link", "run"),
when="+netcdf")

phases = ["build", "install"]

Expand Down Expand Up @@ -95,24 +170,114 @@ def setup_build_environment(self, env):

# Use rose-app.conf to set config options.
config = configparser.ConfigParser()
config.read(join_path(self.package_dir, "rose-app.conf"))
# Ensure that keys are case sensitive.
# https://docs.python.org/3/library/configparser.html#customizing-parser-behaviour
config.optionxform = lambda option: option
model = spec.variants["model"].value
config_file = join_path(
self.package_dir,
"model",
model,
"rose-app.conf")
config.read(config_file)

# Modify the config as per points 8 and 9 of
# https://metomi.github.io/rose/2019.01.8/html/api/configuration/rose-configuration-format.html
config_env = dict()
for key in config["env"]:
if len(key) > 0 and key[0] != '!':
value = config["env"][key].replace("\n=", "\n")
env.set(key, value)
config_env[key] = config["env"][key].replace("\n=", "\n")

# Override some specific environment variables
env.set("optimisation_level", spec.variants["optim"].value)
env.set("platform_config_dir", spec.variants["platform"].value)
env.set("um_rev", f"vn{spec.version}")
# Override the environment variables corresponding to
# the optim and site_platform variants.
optim = spec.variants["optim"].value
if optim != "none":
config_env["optimisation_level"] = optim
site_platform = spec.variants["site_platform"].value
if site_platform != "none":
if "platform_config_dir" in config_env:
platform_config_dir = config_env["platform_config_dir"]
if (platform_config_dir != "" and
platform_config_dir != site_platform):
tty.info(
f"The {model} model uses "
f"platform_config_dir={platform_config_dir} but "
f"the spec calls for "
f"platform_config_dir={site_platform}. "
f"The value {site_platform} will be used.")
# Always use platform_config_dir based on site_platform
config_env["platform_config_dir"] = site_platform

# Override the model UM revision based on the spec UM version.
model_um_rev = config_env["um_rev"]
spec_um_rev = f"vn{spec.version}"
if model_um_rev != spec_um_rev:
if model_um_rev != "":
tty.warn(
f"The {model} model uses um_rev={model_um_rev} but "
f"the spec calls for um_rev={spec_um_rev}. "
f"Revision {spec_um_rev} will be used.")
# Always use the UM revision based on the spec UM version.
config_env["um_rev"] = spec_um_rev

# Overide the model component revisions only when
# the model leaves the revision unspecified.
components = ["casim", "jules", "shumlib", "socrates", "ukca"]
for comp in components:
env.set(f"{comp}_rev", f"um{spec.version}")
model_comp_rev = config_env[f"{comp}_rev"]
spec_comp_rev = f"um{spec.version}"
if model_comp_rev != spec_comp_rev:
if model_comp_rev == "":
config_env[f"{comp}_rev"] = spec_comp_rev
else:
tty.warn(
f"The {model} model uses {comp}_rev={model_comp_rev} but "
f"the spec calls for {comp}_rev={spec_comp_rev}. "
f"Revision {model_comp_rev} will be used.")

# Override those environment variables corresponding to a bool variant.
bool_to_str = lambda b: "true" if b else "false"
for b in self._bool_variants:
if b not in config_env:
tty.warn(
f"The {model} model does not specify {b}. "
f"The value {spec_b_value} will be used.")
else:
model_b_value = config_env[b]
spec_b_value = bool_to_str(spec.variants[b].value)
if model_b_value != spec_b_value:
tty.info(
f"The {model} model uses {b}={model_b_value} but "
f"the spec calls for {b}={spec_b_value}. "
f"The value {spec_b_value} will be used.")
config_env[b] = spec_b_value

# Override those environment variables where a string variant is specified.
for v in self._str_variants:
spec_v_value = spec.variants[v].value
if spec_v_value != "none":
if v not in config_env:
tty.warn(
f"The {model} model does not specify {v}. "
f"The value {spec_v_value} will be used.")
else:
model_v_value = config_env[v]
if model_v_value != "" and model_v_value != spec_v_value:
tty.info(
f"The {model} model uses {v}={model_v_value} but "
f"the spec calls for {v}={spec_v_value}. "
f"The value {spec_v_value} will be used.")
config_env[v] = spec_v_value

# Get the linker arguments for some dependencies.
for fcm_libname in ["eccodes", "netcdf"]:
linker_args = self._get_linker_args(spec, fcm_libname)
env.set(f"ldflags_{fcm_libname}_on", linker_args)
config_env[f"ldflags_{fcm_libname}_on"] = linker_args
penguian marked this conversation as resolved.
Show resolved Hide resolved

# Set environment variables based on config_env.
for key in config_env:
tty.debug(f"{key}={config_env[key]}")
env.set(key, config_env[key])


def _build_dir(self):
Expand Down Expand Up @@ -149,3 +314,4 @@ def install(self, spec, prefix):
install_bin_dir = join_path(prefix, bin_dir)
mkdirp(install_bin_dir)
install_tree(build_bin_dir, install_bin_dir)

Loading