
* Style: black 23, skip magic trailing commas * isort should use same line length as black * Fix unused import * Update version of black used in CI * Update new packages * Update new packages
172 lines
6.1 KiB
Python
172 lines
6.1 KiB
Python
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
|
#
|
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
|
import os
|
|
|
|
from spack.package import *
|
|
from spack.util.executable import Executable
|
|
|
|
|
|
class MpasModel(MakefilePackage):
|
|
"""The Model for Prediction Across Scales (MPAS) is a collaborative
|
|
project for developing atmosphere, ocean and other earth-system
|
|
simulation components for use in climate, regional climate and weather
|
|
studies."""
|
|
|
|
homepage = "https://mpas-dev.github.io/"
|
|
url = "https://github.com/MPAS-Dev/MPAS-Model/archive/v7.0.tar.gz"
|
|
maintainers("t-brown")
|
|
|
|
version("7.3", sha256="a6a9570911b47aa3607036c1ab5a9ae770f9f3a85cea2710f08bb3b35c08facf")
|
|
version("7.2", sha256="3158c22e4a33ae00ce20b65f6ad189c0b7839587dee124d685b02f9df9cf27a7")
|
|
version("7.1", sha256="9b5c181b7d0163ae33d24d7a79ede6990495134b58cf4500ba5c8c94192102bc")
|
|
version("7.0", sha256="f898ce257e66cff9e29320458870570e55721d16cb000de7f2cc27de7fdef14f")
|
|
version("6.3", sha256="e7f1d9ebfeb6ada37d42a286aaedb2e69335cbc857049dc5c5544bb51e7a8db8")
|
|
version("6.2", sha256="2a81825a62a468bf5c56ef9d9677aa2eb88acf78d4f996cb49a7db98b94a6b16")
|
|
|
|
# These targets are defined in the Makefile. Some can be auto-detected by the
|
|
# compiler name, others need to be explicitly set.
|
|
make_target = [
|
|
"xlf",
|
|
"ftn",
|
|
"titan-cray",
|
|
"pgi",
|
|
"pgi-nersc",
|
|
"pgi-llnl",
|
|
"ifort",
|
|
"ifort-scorep",
|
|
"ifort-gcc",
|
|
"gfortran",
|
|
"gfortran-clang",
|
|
"g95",
|
|
"pathscale-nersc",
|
|
"cray-nersc",
|
|
"gnu-nersc",
|
|
"intel-nersc",
|
|
"bluegene",
|
|
"llvm",
|
|
]
|
|
variant(
|
|
"make_target",
|
|
default="none",
|
|
description="Predefined targets in the MPAS Makefile.",
|
|
values=make_target.extend("none"),
|
|
multi=False,
|
|
)
|
|
variant(
|
|
"precision",
|
|
default="double",
|
|
description="MPAS will be built with double/single precision reals.",
|
|
values=("double", "single"),
|
|
multi=False,
|
|
)
|
|
|
|
depends_on("mpi")
|
|
depends_on("parallelio")
|
|
|
|
patch("makefile.patch", when="@7.0")
|
|
|
|
parallel = False
|
|
|
|
resource(
|
|
when="@6.2:6.3",
|
|
name="MPAS-Data",
|
|
git="https://github.com/MPAS-Dev/MPAS-Data.git",
|
|
commit="33561790de8b43087ab850be833f51a4e605f1bb",
|
|
)
|
|
resource(
|
|
when="@7.0:", name="MPAS-Data", git="https://github.com/MPAS-Dev/MPAS-Data.git", tag="v7.0"
|
|
)
|
|
|
|
def patch_makefile(self, action, targets):
|
|
"""Patch predefined flags in Makefile.
|
|
MPAS Makefile uses strings rather Makefile variables for its compiler flags.
|
|
This patch substitutes the strings with flags set in `target:`."""
|
|
|
|
# Target `all:` does not contain any strings with compiler flags
|
|
if action == "all":
|
|
return
|
|
|
|
sed = Executable("sed")
|
|
for target in targets:
|
|
key = target.split("=")[0]
|
|
sed(
|
|
"-i",
|
|
"-e",
|
|
"/^" + action + ":.*$/,/^$/s?" + key + '.*\\" \\\\?' + target + '\\" \\\\?1',
|
|
"Makefile",
|
|
)
|
|
|
|
def target(self, model, action):
|
|
spec = self.spec
|
|
satisfies = spec.satisfies
|
|
fflags = [self.compiler.openmp_flag]
|
|
cppflags = ["-D_MPI"]
|
|
if satisfies("%gcc"):
|
|
fflags.extend(
|
|
[
|
|
"-ffree-line-length-none",
|
|
"-fconvert=big-endian",
|
|
"-ffree-form",
|
|
"-fdefault-real-8",
|
|
"-fdefault-double-8",
|
|
]
|
|
)
|
|
cppflags.append("-DUNDERSCORE")
|
|
elif satisfies("%fj"):
|
|
fflags.extend(["-Free", "-Fwide", "-CcdRR8"])
|
|
elif satisfies("%intel"):
|
|
fflags.extend(["-convert big_endian", "-FR"])
|
|
if satisfies("precision=double"):
|
|
fflags.extend(["-r8"])
|
|
|
|
cppflags.append("-DUNDERSCORE")
|
|
targets = [
|
|
"FC_PARALLEL={0}".format(spec["mpi"].mpifc),
|
|
"CC_PARALLEL={0}".format(spec["mpi"].mpicc),
|
|
"CXX_PARALLEL={0}".format(spec["mpi"].mpicxx),
|
|
"FC_SERIAL={0}".format(spack_fc),
|
|
"CC_SERIAL={0}".format(spack_cc),
|
|
"CXX_SERIAL={0}".format(spack_cxx),
|
|
"CFLAGS_OMP={0}".format(self.compiler.openmp_flag),
|
|
"FFLAGS_OMP={0}".format(" ".join(fflags)),
|
|
"CPPFLAGS={0}".format(" ".join(cppflags)),
|
|
"PIO={0}".format(spec["parallelio"].prefix),
|
|
"NETCDF={0}".format(spec["netcdf-c"].prefix),
|
|
"NETCDFF={0}".format(spec["netcdf-fortran"].prefix),
|
|
]
|
|
if satisfies("^parallelio+pnetcdf"):
|
|
targets.append("PNETCDF={0}".format(spec["parallel-netcdf"].prefix))
|
|
if self.spec.variants["precision"]:
|
|
targets.extend(["PRECISION={0}".format(self.spec.variants["precision"].value)])
|
|
|
|
if action == "all":
|
|
# First try to guess by compiler name
|
|
if os.path.basename(spack_fc) in self.make_target:
|
|
action = os.path.basename(spack_fc)
|
|
# Then overwrite with the optional variant if set
|
|
if self.spec.variants["make_target"].value != "none":
|
|
action = self.spec.variants["make_target"].value
|
|
|
|
targets.extend(
|
|
["USE_PIO2=true", "CPP_FLAGS=-D_MPI", "OPENMP=true", "CORE={0}".format(model), action]
|
|
)
|
|
|
|
self.patch_makefile(action, targets)
|
|
return targets
|
|
|
|
def build(self, spec, prefix):
|
|
copy_tree(
|
|
join_path("MPAS-Data", "atmosphere"), join_path("src", "core_atmosphere", "physics")
|
|
)
|
|
make(*self.target("init_atmosphere", "all"), parallel=True)
|
|
mkdir("bin")
|
|
copy("init_atmosphere_model", "bin")
|
|
make(*self.target("init_atmosphere", "clean"))
|
|
make(*self.target("atmosphere", "all"), parallel=True)
|
|
copy("atmosphere_model", "bin")
|
|
|
|
def install(self, spec, prefix):
|
|
install_tree("bin", prefix.bin)
|