Chapel package: major update (#42197)
* add cray detection taken from upcxx * add CUDA/ROCm support * add numerous pass-through options to Chapel build, like gpu_mem_strategy, comm_substrate, etc.; all variants are translated to analogous CHPL_* environment variables. As a side effect, this defines a number of environment variables that are not actually used by Chapel. * Define LD_LIBRARY_PATH, LIBRARY_PATH, and PKG_CONFIG_PATH to help programs built with Chapel properly locate needed runtime dependencies --------- Co-authored-by: bonachea <dobonachea@lbl.gov>
This commit is contained in:
parent
f339225d22
commit
03c22f403f
2 changed files with 827 additions and 12 deletions
|
@ -0,0 +1,22 @@
|
|||
diff --git a/util/chplenv/chpl_llvm.py b/util/chplenv/chpl_llvm.py
|
||||
index f0fd495f28..95dc9c3f67 100755
|
||||
--- a/util/chplenv/chpl_llvm.py
|
||||
+++ b/util/chplenv/chpl_llvm.py
|
||||
@@ -866,13 +866,14 @@ def get_clang_prgenv_args():
|
||||
os.environ['PE_CHAPEL_PKGCONFIG_LIBS'] = gather_pe_chpl_pkgconfig_libs()
|
||||
|
||||
# Use cc --cray-print-opts=... to get arguments from compiler driver
|
||||
-
|
||||
+ # find the actual cc in case something like spack has wrapped it
|
||||
+ real_cc = os.path.join(os.environ["CRAYPE_DIR"], "bin", "cc")
|
||||
# Get compilation arguments
|
||||
- opts = run_command(['cc', '--cray-print-opts=cflags'])
|
||||
+ opts = run_command([real_cc, '--cray-print-opts=cflags'])
|
||||
comp_args.extend(opts.split())
|
||||
|
||||
# Get link arguments
|
||||
- opts = run_command(['cc', '--cray-print-opts=libs'])
|
||||
+ opts = run_command([real_cc, '--cray-print-opts=libs'])
|
||||
link_args.extend(opts.split())
|
||||
|
||||
return (comp_args, link_args)
|
|
@ -3,24 +3,817 @@
|
|||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from spack.package import *
|
||||
from spack.util.environment import is_system_path, set_env
|
||||
|
||||
|
||||
class Chapel(AutotoolsPackage):
|
||||
@llnl.util.lang.memoized
|
||||
def is_CrayEX():
|
||||
# Credit to upcxx package for this hpe-cray-ex detection function
|
||||
if spack.platforms.host().name == "linux":
|
||||
target = os.environ.get("CRAYPE_NETWORK_TARGET")
|
||||
if target in ["ofi", "ucx"]: # normal case
|
||||
return True
|
||||
elif target is None: # but some systems lack Cray PrgEnv
|
||||
fi_info = which("fi_info")
|
||||
if (
|
||||
fi_info
|
||||
and fi_info("-l", output=str, error=str, fail_on_error=False).find("cxi") >= 0
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Chapel(AutotoolsPackage, CudaPackage, ROCmPackage):
|
||||
"""Chapel is a modern programming language that is parallel, productive,
|
||||
portable, scalable and open-source."""
|
||||
portable, scalable and open-source. The Chapel package comes with many
|
||||
options in the form of variants, most of which can be left unset to allow
|
||||
Chapel's built-in scripts to determine the proper values based on the environment."""
|
||||
|
||||
homepage = "https://chapel-lang.org/"
|
||||
url = "https://github.com/chapel-lang/chapel/releases/download/1.24.1/chapel-1.24.1.tar.gz"
|
||||
|
||||
url = "https://github.com/chapel-lang/chapel/archive/refs/tags/2.0.0.tar.gz"
|
||||
git = "https://github.com/chapel-lang/chapel.git"
|
||||
|
||||
test_requires_compiler = True
|
||||
|
||||
# TODO: Re-enable these once we add determine_version and determine_variants
|
||||
# executables = ["^chpl$", "^chpldoc$"]
|
||||
|
||||
# A list of GitHub accounts to notify when the package is updated.
|
||||
# TODO: add chapel-project github account
|
||||
maintainers("arezaii", "bonachea")
|
||||
|
||||
# See https://spdx.org/licenses/ for a list.
|
||||
license("Apache-2.0")
|
||||
|
||||
version("1.24.1", sha256="f898f266fccaa34d937b38730a361d42efb20753ba43a95e5682816e008ce5e4")
|
||||
version("1.24.0", sha256="77c6087f3e0837268470915f2ad260d49cf7ac4adf16f5b44862ae624c1be801")
|
||||
version("1.23.0", sha256="7ae2c8f17a7b98ac68378e94a842cf16d4ab0bcfeabc0fee5ab4aaa07b205661")
|
||||
version("1.22.1", sha256="8235eb0869c9b04256f2e5ce3ac4f9eff558401582fba0eba05f254449a24989")
|
||||
version("1.22.0", sha256="57ba6ee5dfc36efcd66854ecb4307e1c054700ea201eff73012bd8b4572c2ce6")
|
||||
version("1.21.0", sha256="886f7ba0e0e86c86dba99417e3165f90b1d3eca59c8cd5a7f645ce28cb5d82a0")
|
||||
version("1.20.0", sha256="08bc86df13e4ad56d0447f52628b0f8e36b0476db4e19a90eeb2bd5f260baece")
|
||||
version("1.19.0", sha256="c2b68a20d87cc382c2f73dd1ecc6a4f42fb2f590b0b10fbc577382dd35c9e9bd")
|
||||
version("1.18.0", sha256="68471e1f398b074edcc28cae0be26a481078adc3edea4df663f01c6bd3b6ae0d")
|
||||
version("main", branch="main")
|
||||
|
||||
version("2.0.1", sha256="47e1f3789478ea870bd4ecdf52acbe469d171b89b663309325431f3da7c75008")
|
||||
version("2.0.0", sha256="a8cab99fd034c7b7229be8d4626ec95cf02072646fb148c74b4f48c460c6059c")
|
||||
|
||||
patch("fix_spack_cc_wrapper_in_cray_prgenv.patch", when="@2.0.0:")
|
||||
|
||||
launcher_names = (
|
||||
"amudprun",
|
||||
"aprun",
|
||||
"gasnetrun_ibv",
|
||||
"gasnetrun_mpi",
|
||||
"mpirun4ofi",
|
||||
"lsf-gasnetrun_ibv",
|
||||
"pals",
|
||||
"pbs-aprun",
|
||||
"pbs-gasnetrun_ibv",
|
||||
"slurm-gasnetrun_ibv",
|
||||
"slurm-gasnetrun_mpi",
|
||||
"slurm-gasnetrun_ofi",
|
||||
"slurm-srun",
|
||||
"smp",
|
||||
"none",
|
||||
"unset",
|
||||
)
|
||||
|
||||
# TODO: revise this list of mappings, probably need more logic for cce, see upc++
|
||||
compiler_map = {
|
||||
"aocc": "clang",
|
||||
"apple-clang": "clang",
|
||||
"arm": "clang",
|
||||
"clang": "clang",
|
||||
"cce": "cray-prgenv-cray",
|
||||
"dpcpp": "intel",
|
||||
"gcc": "gnu",
|
||||
"intel": "intel",
|
||||
"llvm": "llvm",
|
||||
"oneapi": "intel",
|
||||
"pgi": "pgi",
|
||||
"rocmcc": "clang",
|
||||
"unset": "unset",
|
||||
}
|
||||
|
||||
cpu_options = (
|
||||
"native",
|
||||
"none",
|
||||
"unknown",
|
||||
"unset",
|
||||
"aarch64",
|
||||
"barcelona",
|
||||
"bdver1",
|
||||
"bdver2",
|
||||
"bdver3",
|
||||
"bdver4",
|
||||
"broadwell",
|
||||
"core2",
|
||||
"haswell",
|
||||
"ivybridge",
|
||||
"k8",
|
||||
"k8sse3",
|
||||
"nehalem",
|
||||
"sandybridge",
|
||||
"skylake",
|
||||
"thunderx",
|
||||
"thunderx2t99",
|
||||
"westmere",
|
||||
)
|
||||
|
||||
# TODO: add other package dependencies
|
||||
package_module_dict = {
|
||||
"curl": "curl",
|
||||
"hdf5": "hdf5+hl~mpi",
|
||||
"libevent": "libevent",
|
||||
"protobuf": "py-protobuf",
|
||||
"ssl": "openssl",
|
||||
"yaml": "libyaml@0.1",
|
||||
"zmq": "libzmq",
|
||||
}
|
||||
|
||||
platform_opts = (
|
||||
"cray-cs",
|
||||
"cray-xc",
|
||||
"cygwin32",
|
||||
"cygwin64",
|
||||
"darwin",
|
||||
"hpe-apollo",
|
||||
"hpe-cray-ex",
|
||||
"linux32",
|
||||
"linux64",
|
||||
"netbsd32",
|
||||
"netbsd64",
|
||||
"pwr6",
|
||||
"unset",
|
||||
)
|
||||
|
||||
variant(
|
||||
"atomics",
|
||||
values=("unset", "cstdlib", "intrinsics", "locks"),
|
||||
default="unset",
|
||||
description="Select atomics implementation",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
# TODO: refactor this somehow, this is a separate documentation tool, not a variant of chapel
|
||||
variant("chpldoc", default=False, description="Build chpldoc in addition to chpl")
|
||||
|
||||
variant("developer", default=False, description="Enable Chapel developer mode")
|
||||
|
||||
variant(
|
||||
"comm",
|
||||
default="none",
|
||||
description="Build Chapel with multi-locale support",
|
||||
values=("gasnet", "none", "ofi", "ugni"),
|
||||
)
|
||||
|
||||
variant(
|
||||
"comm_substrate",
|
||||
default="unset",
|
||||
description="Build Chapel with GASNet multi-locale support using the "
|
||||
"supplied CHPL_COMM_SUBSTRATE",
|
||||
values=("ibv", "ofi", "udp", "smp", "unset"),
|
||||
multi=False,
|
||||
sticky=True, # never allow the concretizer to choose this
|
||||
)
|
||||
|
||||
# Chapel depends on GASNet whenever comm=gasnet.
|
||||
# The default (and recommendation) is to use the embedded copy of GASNet.
|
||||
# This variant allows overriding with a particular version of GASNet sources,
|
||||
# although this is not officially supported and some combinations might be rejected.
|
||||
variant(
|
||||
"gasnet",
|
||||
description="Control the GASNet library version used",
|
||||
default="bundled",
|
||||
values=("bundled", "spack"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"gasnet_segment",
|
||||
default="unset",
|
||||
description="Build Chapel with multi-locale support using the "
|
||||
"supplied CHPL_GASNET_SEGMENT",
|
||||
values=("everything", "fast", "large", "unset"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"gmp",
|
||||
description="Build with gmp support",
|
||||
default="spack",
|
||||
values=("bundled", "none", "spack"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"gpu_mem_strategy",
|
||||
description="The memory allocation strategy for GPU data",
|
||||
values=("array_on_device", "unified_memory"),
|
||||
default="array_on_device",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"host_arch",
|
||||
description="Host architecture of the build machine",
|
||||
values=("x86_64", "aarch64", "arm64", "unset"),
|
||||
default="unset",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"host_jemalloc",
|
||||
values=("bundled", "none", "spack", "unset"),
|
||||
default="unset",
|
||||
multi=False,
|
||||
description="Selects between no jemalloc, bundled jemalloc, or spack supplied jemalloc",
|
||||
)
|
||||
|
||||
variant(
|
||||
"host_mem",
|
||||
values=("cstdlib", "jemalloc"),
|
||||
default="jemalloc",
|
||||
description="Memory management layer for the chpl compiler",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"host_platform",
|
||||
description="Host platform",
|
||||
default="unset",
|
||||
values=platform_opts,
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"hwloc",
|
||||
description="Build with hwloc support",
|
||||
default="bundled",
|
||||
values=(
|
||||
"bundled",
|
||||
"none",
|
||||
# CHPL_HWLOC=system existed back to at least 2017,
|
||||
# but it was buggy and unsupported until version 2.1
|
||||
conditional("spack", when="@2.1:"),
|
||||
),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"launcher",
|
||||
values=launcher_names,
|
||||
default="unset",
|
||||
description="Launcher to use for running Chapel programs",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"lib_pic",
|
||||
values=("none", "pic"),
|
||||
default="none",
|
||||
description="Build position-independent code suitable for shared libraries",
|
||||
)
|
||||
|
||||
variant(
|
||||
"libfabric",
|
||||
default="unset",
|
||||
description="When building with ofi support, specify libfabric option",
|
||||
values=("bundled", "spack", "unset"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"llvm",
|
||||
default="spack",
|
||||
description="LLVM backend type. The 'spack' value can use an external "
|
||||
"source of LLVM or let spack build a version if no LLVM installs were "
|
||||
"previously detected by 'spack external find'",
|
||||
values=("bundled", "none", "spack"),
|
||||
)
|
||||
|
||||
variant(
|
||||
"re2",
|
||||
description="Build with re2 support",
|
||||
default="bundled",
|
||||
values=("bundled", "none"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"target_arch",
|
||||
description="Target architecture for cross compilation",
|
||||
default="unset",
|
||||
values=("x86_64", "aarch64", "arm64", "unset"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"target_cpu",
|
||||
values=cpu_options,
|
||||
description="Indicate that the target executable should be specialized "
|
||||
"to the given architecture when using --specialize (and --fast).",
|
||||
default="unset",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"target_platform",
|
||||
description="Target platform for cross compilation",
|
||||
default="unset",
|
||||
values=platform_opts,
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"tasks",
|
||||
description="Select tasking layer for intra-locale parallelism",
|
||||
default="qthreads",
|
||||
values=("fifo", "qthreads"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"timers",
|
||||
description="Select timers implementation",
|
||||
default="unset",
|
||||
values=("generic", "unset"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
variant(
|
||||
"unwind",
|
||||
description="Build with unwind library for stack tracing",
|
||||
default="none",
|
||||
values=("bundled", "none", "spack"),
|
||||
multi=False,
|
||||
)
|
||||
|
||||
# Add dependencies for package modules
|
||||
for variant_name, dep in package_module_dict.items():
|
||||
variant(
|
||||
variant_name,
|
||||
description="Build with support for the Chapel {0} package module".format(
|
||||
variant_name
|
||||
),
|
||||
default=True,
|
||||
)
|
||||
depends_on(dep, when="+{0}".format(variant_name))
|
||||
|
||||
# TODO: for CHPL_X_CC and CHPL_X_CXX, can we capture an arbitrary path, possibly
|
||||
# with arguments?
|
||||
chpl_env_vars = [
|
||||
"CHPL_ATOMICS",
|
||||
"CHPL_AUX_FILESYS",
|
||||
"CHPL_COMM",
|
||||
"CHPL_COMM_SUBSTRATE",
|
||||
"CHPL_DEVELOPER",
|
||||
"CHPL_GASNET_SEGMENT",
|
||||
"CHPL_GMP",
|
||||
"CHPL_GPU",
|
||||
"CHPL_GPU_ARCH",
|
||||
"CHPL_GPU_MEM_STRATEGY",
|
||||
"CHPL_HOST_ARCH",
|
||||
# "CHPL_HOST_CC",
|
||||
"CHPL_HOST_COMPILER",
|
||||
# "CHPL_HOST_CXX",
|
||||
"CHPL_HOST_JEMALLOC",
|
||||
"CHPL_HOST_MEM",
|
||||
"CHPL_HOST_PLATFORM",
|
||||
"CHPL_HWLOC",
|
||||
"CHPL_LAUNCHER",
|
||||
"CHPL_LIB_PIC",
|
||||
"CHPL_LIBFABRIC",
|
||||
"CHPL_LLVM",
|
||||
"CHPL_LLVM_CONFIG",
|
||||
"CHPL_LLVM_SUPPORT",
|
||||
"CHPL_LLVM_VERSION",
|
||||
"CHPL_LOCALE_MODEL",
|
||||
"CHPL_MEM",
|
||||
"CHPL_RE2",
|
||||
"CHPL_SANITIZE",
|
||||
"CHPL_SANITIZE_EXE",
|
||||
"CHPL_TARGET_ARCH",
|
||||
# "CHPL_TARGET_CC",
|
||||
"CHPL_TARGET_COMPILER",
|
||||
"CHPL_TARGET_CPU",
|
||||
# "CHPL_TARGET_CXX",
|
||||
"CHPL_TARGET_PLATFORM",
|
||||
"CHPL_TASKS",
|
||||
"CHPL_TIMERS",
|
||||
"CHPL_UNWIND",
|
||||
]
|
||||
|
||||
conflicts("platform=windows") # Support for windows is through WSL only
|
||||
|
||||
conflicts("+rocm", when="+cuda", msg="Chapel must be built with either CUDA or ROCm, not both")
|
||||
conflicts("+rocm", when="@:2.0.0", msg="ROCm support in spack requires Chapel 2.0.0 or later")
|
||||
|
||||
conflicts(
|
||||
"comm_substrate=unset",
|
||||
when="comm=gasnet",
|
||||
msg="comm=gasnet requires you to also set comm_substrate= to the appropriate network",
|
||||
)
|
||||
|
||||
conflicts(
|
||||
"^python@3.12:",
|
||||
when="@:2.1.0",
|
||||
msg="Chapel versions prior to 2.1.0 may produce SyntaxWarnings with Python >= 3.12",
|
||||
)
|
||||
|
||||
conflicts(
|
||||
"host_jemalloc=spack",
|
||||
when="platform=linux",
|
||||
msg="Only bundled jemalloc may be used on Linux systems, see "
|
||||
"https://chapel-lang.org/docs/usingchapel/chplenv.html#chpl-host-jemalloc",
|
||||
)
|
||||
|
||||
conflicts(
|
||||
"host_jemalloc=bundled",
|
||||
when="platform=darwin",
|
||||
msg="Only system jemalloc may be used on Darwin (MacOS) systems, see "
|
||||
"https://chapel-lang.org/docs/usingchapel/chplenv.html#chpl-host-jemalloc",
|
||||
)
|
||||
|
||||
with when("llvm=none"):
|
||||
conflicts("+cuda", msg="Cuda support requires building with LLVM")
|
||||
conflicts("+rocm", msg="ROCm support requires building with LLVM")
|
||||
|
||||
# Add dependencies
|
||||
|
||||
depends_on("doxygen@1.8.17:", when="+chpldoc")
|
||||
|
||||
# TODO: keep up to date with util/chplenv/chpl_llvm.py
|
||||
with when("llvm=spack"):
|
||||
depends_on("llvm@11:17", when="@:2.0.1")
|
||||
depends_on("llvm@11:18", when="@2.1.0:")
|
||||
|
||||
# Based on docs https://chapel-lang.org/docs/technotes/gpu.html#requirements
|
||||
depends_on("llvm@16:", when="llvm=spack ^cuda@12:")
|
||||
requires(
|
||||
"^llvm targets=all",
|
||||
msg="llvm=spack +cuda requires LLVM support the nvptx target",
|
||||
when="llvm=spack +cuda",
|
||||
)
|
||||
|
||||
depends_on("cuda@11:", when="+cuda", type=("build", "link", "run", "test"))
|
||||
|
||||
# This is because certain systems have binutils installed as a system package
|
||||
# but do not include the headers. Spack incorrectly supplies those external
|
||||
# packages as proper dependencies for LLVM, but then LLVM will fail to build
|
||||
# with an error about missing plugin-api.h
|
||||
depends_on("binutils+gold+ld+plugins+headers", when="llvm=bundled")
|
||||
|
||||
depends_on("m4")
|
||||
|
||||
depends_on("gmp", when="gmp=spack", type=("build", "link", "run", "test"))
|
||||
depends_on("hwloc", when="hwloc=spack", type=("build", "link", "run", "test"))
|
||||
depends_on("libfabric", when="libfabric=spack", type=("build", "link", "run", "test"))
|
||||
depends_on("libunwind", when="unwind=spack", type=("build", "link", "run", "test"))
|
||||
depends_on("jemalloc", when="host_jemalloc=spack", type=("build", "link", "run", "test"))
|
||||
|
||||
depends_on("gasnet conduits=none", when="gasnet=spack")
|
||||
depends_on("gasnet@2024.5.0: conduits=none", when="@2.1.0: gasnet=spack")
|
||||
|
||||
depends_on("python@3.7:")
|
||||
depends_on("cmake@3.16:")
|
||||
|
||||
# ensure we can map the spack compiler name to one of the ones we recognize
|
||||
requires(
|
||||
"%aocc",
|
||||
"%apple-clang",
|
||||
"%arm",
|
||||
"%clang",
|
||||
"%cce",
|
||||
"%cray-prgenv-cray",
|
||||
"%cray-prgenv-gnu",
|
||||
"%cray-prgenv-intel",
|
||||
"%cray-prgenv-pgi",
|
||||
"%dpcpp",
|
||||
"%gcc",
|
||||
"%intel",
|
||||
"%llvm",
|
||||
"%oneapi",
|
||||
"%pgi",
|
||||
"%rocmcc",
|
||||
policy="one_of",
|
||||
)
|
||||
|
||||
def unset_chpl_env_vars(self, env):
|
||||
# Clean the environment from any pre-set CHPL_ variables that affect the build
|
||||
for var in self.chpl_env_vars:
|
||||
env.unset(var)
|
||||
|
||||
def build(self, spec, prefix):
|
||||
make()
|
||||
if spec.variants["chpldoc"].value:
|
||||
make("chpldoc")
|
||||
|
||||
def setup_chpl_platform(self, env):
|
||||
if self.spec.variants["host_platform"].value == "unset":
|
||||
if is_CrayEX():
|
||||
env.set("CHPL_HOST_PLATFORM", "hpe-cray-ex")
|
||||
|
||||
def setup_chpl_compilers(self, env):
|
||||
env.set("CHPL_HOST_COMPILER", self.compiler_map[self.spec.compiler.name])
|
||||
env.set("CHPL_TARGET_COMPILER", self.compiler_map[self.spec.compiler.name])
|
||||
|
||||
# Undo spack compiler wrappers:
|
||||
# the C/C++ compilers must work post-install
|
||||
if self.spec.satisfies("+cuda") or self.spec.satisfies("+rocm"):
|
||||
env.set("CHPL_TARGET_COMPILER", "llvm")
|
||||
real_cc = join_path(self.spec["llvm"].prefix, "bin", "clang")
|
||||
real_cxx = join_path(self.spec["llvm"].prefix, "bin", "clang++")
|
||||
elif is_CrayEX() and os.environ.get("CRAYPE_DIR"):
|
||||
real_cc = join_path(os.environ["CRAYPE_DIR"], "bin", "cc")
|
||||
real_cxx = join_path(os.environ["CRAYPE_DIR"], "bin", "CC")
|
||||
else:
|
||||
real_cc = self.compiler.cc
|
||||
real_cxx = self.compiler.cxx
|
||||
env.set("CHPL_TARGET_CC", real_cc)
|
||||
env.set("CHPL_TARGET_CXX", real_cxx)
|
||||
|
||||
def setup_chpl_comm(self, env, spec):
|
||||
env.set("CHPL_COMM", spec.variants["comm"].value)
|
||||
|
||||
@run_before("configure", when="gasnet=spack")
|
||||
def setup_gasnet(self):
|
||||
dst = join_path(self.stage.source_path, "third-party", "gasnet", "gasnet-src")
|
||||
remove_directory_contents(dst)
|
||||
os.rmdir(dst)
|
||||
symlink(self.spec["gasnet"].prefix.src, dst)
|
||||
|
||||
def setup_chpl_llvm(self, env):
|
||||
if self.spec.variants["llvm"].value == "spack":
|
||||
env.set(
|
||||
"CHPL_LLVM_CONFIG", "{0}/{1}".format(self.spec["llvm"].prefix, "bin/llvm-config")
|
||||
)
|
||||
|
||||
def setup_if_not_unset(self, env, var, value):
|
||||
if value != "unset":
|
||||
if value == "spack":
|
||||
value = "system"
|
||||
env.set(var, value)
|
||||
|
||||
def prepend_cpath_include(self, env, prefix):
|
||||
if not is_system_path(prefix):
|
||||
env.prepend_path("CPATH", prefix.include)
|
||||
|
||||
def setup_env_vars(self, env):
|
||||
# variants that appear unused by Spack typically correspond directly to
|
||||
# a CHPL_<variant> variable which will be used by the Chapel build system
|
||||
for v in self.spec.variants.keys():
|
||||
self.setup_if_not_unset(env, "CHPL_" + v.upper(), self.spec.variants[v].value)
|
||||
self.setup_chpl_llvm(env)
|
||||
self.setup_chpl_compilers(env)
|
||||
self.setup_chpl_platform(env)
|
||||
|
||||
# TODO: a function to set defaults for things where we removed variants
|
||||
# We'll set to GPU later if +rocm or +cuda requested
|
||||
env.set("CHPL_LOCALE_MODEL", "flat")
|
||||
|
||||
if self.spec.satisfies("+developer"):
|
||||
env.set("CHPL_DEVELOPER", "true")
|
||||
|
||||
if self.spec.variants["gmp"].value == "spack":
|
||||
# TODO: why must we add to CPATH to find gmp.h
|
||||
# TODO: why must we add to LIBRARY_PATH to find lgmp
|
||||
self.prepend_cpath_include(env, self.spec["gmp"].prefix)
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["gmp"].prefix.lib)
|
||||
# Need this for the test env, where it does not appear automatic:
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["gmp"].prefix.lib.pkgconfig)
|
||||
|
||||
if self.spec.variants["hwloc"].value == "spack":
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["hwloc"].prefix.lib)
|
||||
# Need this for the test env, where it does not appear automatic:
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["hwloc"].prefix.lib.pkgconfig)
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["libpciaccess"].prefix.lib.pkgconfig)
|
||||
|
||||
if self.spec.variants["unwind"].value == "spack":
|
||||
# chapel package would not build without cpath, missing libunwind.h
|
||||
self.prepend_cpath_include(env, self.spec["libunwind"].prefix)
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["libunwind"].prefix.lib)
|
||||
|
||||
if self.spec.satisfies("+yaml"):
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["libyaml"].prefix.lib.pkgconfig)
|
||||
self.prepend_cpath_include(env, self.spec["libyaml"].prefix)
|
||||
# could not compile test/library/packages/Yaml/writeAndParse.chpl without this
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["libyaml"].prefix.lib)
|
||||
|
||||
if self.spec.satisfies("+zmq"):
|
||||
self.prepend_cpath_include(env, self.spec["libzmq"].prefix)
|
||||
# could not compile test/library/packages/ZMQ/hello.chpl without this
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["libzmq"].prefix.lib)
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["libzmq"].prefix.lib)
|
||||
# could not compile test/library/packages/ZMQ/hello.chpl without this
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["libzmq"].prefix.lib)
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["libzmq"].prefix.lib.pkgconfig)
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["libsodium"].prefix.lib.pkgconfig)
|
||||
|
||||
if self.spec.satisfies("+curl"):
|
||||
self.prepend_cpath_include(env, self.spec["curl"].prefix)
|
||||
# could not compile test/library/packages/Curl/check-http.chpl without this
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["curl"].prefix.lib)
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["curl"].prefix.lib)
|
||||
env.prepend_path("PKG_CONFIG_PATH", self.spec["curl"].prefix.lib.pkgconfig)
|
||||
|
||||
if self.spec.satisfies("+cuda"):
|
||||
# TODO: why must we add to LD_LIBRARY_PATH to find libcudart?
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["cuda"].prefix.lib64)
|
||||
env.set("CHPL_LOCALE_MODEL", "gpu")
|
||||
env.set("CHPL_GPU", "nvidia")
|
||||
|
||||
if self.spec.satisfies("+rocm"):
|
||||
env.set("CHPL_LOCALE_MODEL", "gpu")
|
||||
env.set("CHPL_GPU", "amd")
|
||||
env.set("CHPL_HOST_COMPILER", "llvm")
|
||||
env.set("CHPL_GPU_ARCH", self.spec.variants["amdgpu_target"].value[0])
|
||||
env.set(
|
||||
"CHPL_LLVM_CONFIG",
|
||||
"{0}/{1}".format(self.spec["llvm-amdgpu"].prefix, "bin/llvm-config"),
|
||||
)
|
||||
self.prepend_cpath_include(env, self.spec["hip"].prefix)
|
||||
env.set("CHPL_ROCM_PATH", self.spec["llvm-amdgpu"].prefix)
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["hip"].prefix.lib)
|
||||
env.prepend_path("LIBRARY_PATH", self.spec["hsa-rocr-dev"].prefix.lib)
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["hip"].prefix.lib)
|
||||
env.prepend_path("LD_LIBRARY_PATH", self.spec["hsa-rocr-dev"].prefix.lib)
|
||||
self.setup_chpl_comm(env, self.spec)
|
||||
|
||||
def setup_build_environment(self, env):
|
||||
self.unset_chpl_env_vars(env)
|
||||
self.setup_env_vars(env)
|
||||
|
||||
def setup_run_environment(self, env):
|
||||
self.setup_env_vars(env)
|
||||
env.prepend_path(
|
||||
"PATH", join_path(self.prefix.share, "chapel", self._output_version_short, "util")
|
||||
)
|
||||
|
||||
@property
|
||||
@llnl.util.lang.memoized
|
||||
def _output_version_long(self):
|
||||
if str(self.spec.version).lower() == "main":
|
||||
return "2.1.0"
|
||||
spec_vers_str = str(self.spec.version.up_to(3))
|
||||
return spec_vers_str
|
||||
|
||||
@property
|
||||
@llnl.util.lang.memoized
|
||||
def _output_version_short(self):
|
||||
if str(self.spec.version).lower() == "main":
|
||||
return "2.1"
|
||||
spec_vers_str = str(self.spec.version.up_to(2))
|
||||
return spec_vers_str
|
||||
|
||||
def test_version(self):
|
||||
"""Perform version checks on selected installed package binaries."""
|
||||
expected = f"version {self._output_version_long}"
|
||||
exes = ["chpl"]
|
||||
|
||||
if self.spec.satisfies("+chpldoc"):
|
||||
exes.append("chpldoc")
|
||||
|
||||
for exe in exes:
|
||||
reason = f"ensure version of {exe} is {self._output_version_long}"
|
||||
with test_part(self, f"test_version_{exe}", purpose=reason):
|
||||
path = join_path(self.prefix.bin, exe)
|
||||
if not os.path.isfile(path):
|
||||
raise SkipTest(f"{path} is not installed")
|
||||
prog = which(path)
|
||||
if prog is None:
|
||||
raise RuntimeError(f"Could not find {path}")
|
||||
output = prog("--version", output=str.split, error=str.split)
|
||||
assert expected in output
|
||||
|
||||
def check(self):
|
||||
# TODO: we skip the self-check because it's ran by default but:
|
||||
# - make check doesn't work at build time b/c the PATH isn't yet updated
|
||||
# - make test is a long running operation
|
||||
pass
|
||||
|
||||
def check_chpl_install_gasnet(self):
|
||||
"""Setup env to run self-test after installing the package with gasnet"""
|
||||
with set_env(
|
||||
GASNET_SPAWNFN="L",
|
||||
GASNET_QUIET="yes",
|
||||
GASNET_ROUTE_OUTPUT="0",
|
||||
QT_AFFINITY="no",
|
||||
CHPL_QTHREAD_ENABLE_OVERSUBSCRIPTION="1",
|
||||
CHPL_RT_MASTERIP="127.0.0.1",
|
||||
CHPL_RT_WORKERIP="127.0.0.0",
|
||||
CHPL_LAUNCHER="",
|
||||
):
|
||||
return subprocess.run(["util/test/checkChplInstall"])
|
||||
|
||||
def check_chpl_install(self):
|
||||
if self.spec.variants["comm"].value != "none":
|
||||
return self.check_chpl_install_gasnet()
|
||||
else:
|
||||
return subprocess.run(["util/test/checkChplInstall"])
|
||||
|
||||
def test_hello(self):
|
||||
"""Run the hello world test"""
|
||||
with working_dir(self.test_suite.current_test_cache_dir):
|
||||
with set_env(CHPL_CHECK_HOME=self.test_suite.current_test_cache_dir):
|
||||
with test_part(self, "test_hello", purpose="test hello world"):
|
||||
if self.spec.satisfies("+cuda") or self.spec.satisfies("+rocm"):
|
||||
with set_env(COMP_FLAGS="--no-checks --no-compiler-driver"):
|
||||
res = self.check_chpl_install()
|
||||
assert res and res.returncode == 0
|
||||
else:
|
||||
res = self.check_chpl_install()
|
||||
assert res and res.returncode == 0
|
||||
|
||||
# TODO: This is a pain because the checkChplDoc script doesn't have the same
|
||||
# support for CHPL_CHECK_HOME and chpldoc is finicky about CHPL_HOME
|
||||
def test_chpldoc(self):
|
||||
"""Run the chpldoc test"""
|
||||
if not self.spec.satisfies("+chpldoc"):
|
||||
print("Skipping chpldoc test as chpldoc variant is not set")
|
||||
return
|
||||
with working_dir(self.test_suite.current_test_cache_dir):
|
||||
with set_env(CHPL_HOME=self.test_suite.current_test_cache_dir):
|
||||
with test_part(self, "test_chpldoc", purpose="test chpldoc"):
|
||||
res = subprocess.run(["util/test/checkChplDoc"])
|
||||
assert res.returncode == 0
|
||||
|
||||
# TODO: In order to run these tests, there's a lot of infrastructure to copy
|
||||
# from the Chapel test suite and there are conflicts with CHPL_HOME needing
|
||||
# to match the compiler's directory and the test suite's directory
|
||||
# def test_package_modules(self):
|
||||
# """Test that the package modules are available"""
|
||||
# # if not self.spec.satisfies("+module_tests"):
|
||||
# # print("Skipping module tests as module_tests variant is not set")
|
||||
# # return
|
||||
# tests_to_run = []
|
||||
# with working_dir(self.test_suite.current_test_cache_dir):
|
||||
# with set_env(CHPL_HOME=join_path(self.spec.prefix.share,
|
||||
# "chapel", self._output_version_short)):
|
||||
# with test_part(self, "test_package_modules", purpose="test package modules"):
|
||||
# if self.spec.satisfies("+yaml"):
|
||||
# tests_to_run.append("test/library/packages/Yaml/writeAndParse.chpl")
|
||||
# if self.spec.satisfies("+zmq"):
|
||||
# tests_to_run.append("test/library/packages/ZMQ/weather.chpl")
|
||||
# if self.spec.satisfies("+ssl"):
|
||||
# tests_to_run.append("test/library/packages/Crypto/")
|
||||
# # TODO: These tests fail with llvm, unable to find C variable CURLPAUSE_CONT
|
||||
# if (
|
||||
# self.spec.satisfies("+curl")
|
||||
# and self.spec.variants["llvm"].value == "none"
|
||||
# ):
|
||||
# with set_env(CHPL_NIGHTLY_TEST_CONFIG_NAME="networking-packages"):
|
||||
# print("Running package module test for package 'curl'")
|
||||
# res = subprocess.run(
|
||||
# ["util/start_test", "test/library/packages/Curl/"]
|
||||
# )
|
||||
# assert res.returncode == 0
|
||||
# print("Running package module test for package 'url'")
|
||||
# res = subprocess.run(["util/start_test",
|
||||
# "test/library/packages/URL/"])
|
||||
# assert res.returncode == 0
|
||||
# if self.spec.satisfies("+hdf5"):
|
||||
# tests_to_run.append("test/library/packages/HDF5/")
|
||||
# if self.spec.satisfies("+protobuf"):
|
||||
# tests_to_run.append("test/library/packages/ProtobufProtocolSupport/")
|
||||
# if len(tests_to_run) > 0:
|
||||
# with set_env(CHPL_HOME=self.test_suite.current_test_cache_dir):
|
||||
# compiler = join_path(self.spec.prefix.bin,'chpl')
|
||||
# print("Running package module tests for packages...")
|
||||
# print(f" command to run: util/start_test --compiler {compiler}")
|
||||
# tests_to_run.insert(0, "util/start_test")
|
||||
# tests_to_run.insert(1, "--compiler")
|
||||
# tests_to_run.insert(2, compiler)
|
||||
# res = subprocess.run([t for t in tests_to_run])
|
||||
# assert res.returncode == 0
|
||||
|
||||
@run_after("install")
|
||||
def copy_test_files(self):
|
||||
"""Copy test files to the install directory"""
|
||||
test_files = [
|
||||
"test/release/examples",
|
||||
"util/start_test",
|
||||
"util/test",
|
||||
"util/chplenv",
|
||||
"util/config",
|
||||
# "test/library/packages/Curl",
|
||||
# "test/library/packages/URL/",
|
||||
# "test/library/packages/ProtobufProtocolSupport/",
|
||||
# "test/library/packages/Crypto/",
|
||||
# "test/library/packages/Yaml/",
|
||||
# "test/library/packages/ZMQ/",
|
||||
# "test/library/packages/HDF5/",
|
||||
"chplconfig",
|
||||
"make",
|
||||
"third-party/chpl-venv/",
|
||||
]
|
||||
cache_extra_test_sources(self, test_files)
|
||||
|
||||
# @run_after("install")
|
||||
# @on_package_attributes(run_tests=True)
|
||||
# def self_check(self):
|
||||
# """Run the self-check after installing the package"""
|
||||
# path_put_first("PATH", [self.prefix.bin])
|
||||
# self.test_version()
|
||||
# self.test_hello()
|
||||
# if self.spec.satisfies("+chpldoc"):
|
||||
# make("check-chpldoc")
|
||||
# self.test_package_modules()
|
||||
|
|
Loading…
Reference in a new issue