summaryrefslogtreecommitdiff
path: root/var
diff options
context:
space:
mode:
authorarezaii <Ahmad.rezaii@hpe.com>2024-06-17 18:09:05 -0600
committerGitHub <noreply@github.com>2024-06-17 18:09:05 -0600
commit24b8d0666e4a43aab26981e98f06b72b34e658a8 (patch)
tree476e7e078fef85065b2a73229feb2fe8b0af3fbb /var
parent0f2c7248c81cef5039353903bae671aad95952d3 (diff)
downloadspack-24b8d0666e4a43aab26981e98f06b72b34e658a8.tar.gz
spack-24b8d0666e4a43aab26981e98f06b72b34e658a8.tar.bz2
spack-24b8d0666e4a43aab26981e98f06b72b34e658a8.tar.xz
spack-24b8d0666e4a43aab26981e98f06b72b34e658a8.zip
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>
Diffstat (limited to 'var')
-rw-r--r--var/spack/repos/builtin/packages/chapel/fix_spack_cc_wrapper_in_cray_prgenv.patch22
-rw-r--r--var/spack/repos/builtin/packages/chapel/package.py817
2 files changed, 827 insertions, 12 deletions
diff --git a/var/spack/repos/builtin/packages/chapel/fix_spack_cc_wrapper_in_cray_prgenv.patch b/var/spack/repos/builtin/packages/chapel/fix_spack_cc_wrapper_in_cray_prgenv.patch
new file mode 100644
index 0000000000..b53b7f2c26
--- /dev/null
+++ b/var/spack/repos/builtin/packages/chapel/fix_spack_cc_wrapper_in_cray_prgenv.patch
@@ -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)
diff --git a/var/spack/repos/builtin/packages/chapel/package.py b/var/spack/repos/builtin/packages/chapel/package.py
index feedd735d1..bdc293e827 100644
--- a/var/spack/repos/builtin/packages/chapel/package.py
+++ b/var/spack/repos/builtin/packages/chapel/package.py
@@ -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
+
+
+@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):
+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()