spack/var/spack/repos/builtin/packages/lvarray/package.py
Todd Gamblin 3118647802
Update copyright year to 2024 (#41919)
It was time to run `spack license update-copyright-year` again.
2024-01-02 09:21:30 +01:00

377 lines
14 KiB
Python

# Copyright 2013-2024 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
import socket
import warnings
from os import environ as env
from os.path import join as pjoin
from spack.package import *
def cmake_cache_entry(name, value, comment=""):
"""Generate a string for a cmake cache variable"""
return 'set(%s "%s" CACHE PATH "%s")\n\n' % (name, value, comment)
def cmake_cache_string(name, string, comment=""):
"""Generate a string for a cmake cache variable"""
return 'set(%s "%s" CACHE STRING "%s")\n\n' % (name, string, comment)
def cmake_cache_option(name, boolean_value, comment=""):
"""Generate a string for a cmake configuration option"""
value = "ON" if boolean_value else "OFF"
return 'set(%s %s CACHE BOOL "%s")\n\n' % (name, value, comment)
class Lvarray(CMakePackage, CudaPackage):
"""LvArray portable HPC containers."""
homepage = "https://github.com/GEOSX/lvarray"
git = "https://github.com/GEOSX/LvArray.git"
tags = ["radiuss"]
maintainers("corbett5")
license("BSD-3-Clause")
version("develop", branch="develop", submodules=False)
version("main", branch="main", submodules=False)
version(
"0.2.2", tag="v0.2.2", commit="3f7bacf5a4e967d4628b860132f5c29673314d3a", submodules=False
)
version(
"0.2.1", tag="v0.2.1", commit="3fece6bbbeb172442275d1ad1a52d6b54cd53163", submodules=False
)
version(
"0.1.0", tag="v0.1.0", commit="0bf5f7d077de4a08f58db24baed207f9dba95f6e", submodules=True
)
variant("shared", default=True, description="Build Shared Libs")
variant("umpire", default=False, description="Build Umpire support")
variant("chai", default=False, description="Build Chai support")
variant("caliper", default=False, description="Build Caliper support")
variant("pylvarray", default=False, description="Build Python support")
variant("tests", default=True, description="Build tests")
variant("benchmarks", default=False, description="Build benchmarks")
variant("examples", default=False, description="Build examples")
variant("docs", default=False, description="Build docs")
variant("addr2line", default=True, description="Build support for addr2line.")
depends_on("blt", when="@0.2.0:", type="build")
depends_on("camp")
depends_on("camp+cuda", when="+cuda")
depends_on("raja")
depends_on("raja+cuda", when="+cuda")
# At the moment Umpire doesn't support shared when building with CUDA.
depends_on("umpire", when="+umpire")
depends_on("umpire+cuda~shared", when="+umpire+cuda")
depends_on("chai+raja", when="+chai")
depends_on("chai+raja+cuda", when="+chai+cuda")
depends_on("caliper", when="+caliper")
depends_on("python +shared +pic", type=("build", "link", "run"), when="+pylvarray")
depends_on("py-numpy@1.19:", type=("build", "link", "run"), when="+pylvarray")
depends_on("py-scipy@1.5.2:", type=("build", "run"), when="+pylvarray")
depends_on("doxygen@1.8.13:", when="+docs", type="build")
depends_on("py-sphinx@1.6.3:", when="+docs", type="build")
phases = ["hostconfig", "cmake", "build", "install"]
@run_after("build")
@on_package_attributes(run_tests=True)
def check(self):
"""Searches the CMake-generated Makefile for the target ``test``
and runs it if found.
"""
with working_dir(self.build_directory):
ctest("-V", "--force-new-ctest-process", "-j 1")
@run_after("build")
def build_docs(self):
if "+docs" in self.spec:
with working_dir(self.build_directory):
make("docs")
def _get_sys_type(self, spec):
sys_type = str(spec.architecture)
# if on llnl systems, we can use the SYS_TYPE
if "SYS_TYPE" in env:
sys_type = env["SYS_TYPE"]
return sys_type
def _get_host_config_path(self, spec):
var = ""
if "+cuda" in spec:
var = "-".join([var, "cuda"])
hostname = socket.gethostname().rstrip("1234567890")
host_config_path = "%s-%s-%s%s.cmake" % (
hostname,
self._get_sys_type(spec),
spec.compiler,
var,
)
dest_dir = self.stage.source_path
host_config_path = os.path.abspath(pjoin(dest_dir, host_config_path))
return host_config_path
def hostconfig(self, spec, prefix, py_site_pkgs_dir=None):
"""
This method creates a 'host-config' file that specifies
all of the options used to configure and build Umpire.
For more details about 'host-config' files see:
http://software.llnl.gov/conduit/building.html
Note:
The `py_site_pkgs_dir` arg exists to allow a package that
subclasses this package provide a specific site packages
dir when calling this function. `py_site_pkgs_dir` should
be an absolute path or `None`.
This is necessary because the spack `python_purelib` and `python_platlib`
vars will not exist in the base class. For more details
on this issue see: https://github.com/spack/spack/issues/6261
"""
#######################
# Compiler Info
#######################
c_compiler = env["SPACK_CC"]
cpp_compiler = env["SPACK_CXX"]
#######################################################################
# By directly fetching the names of the actual compilers we appear
# to doing something evil here, but this is necessary to create a
# 'host config' file that works outside of the spack install env.
#######################################################################
sys_type = self._get_sys_type(spec)
##############################################
# Find and record what CMake is used
##############################################
cmake_exe = spec["cmake"].command.path
cmake_exe = os.path.realpath(cmake_exe)
host_config_path = self._get_host_config_path(spec)
with open(host_config_path, "w") as cfg:
cfg.write("#{0}\n".format("#" * 80))
cfg.write("# Generated host-config - Edit at own risk!\n")
cfg.write("#{0}\n".format("#" * 80))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# SYS_TYPE: {0}\n".format(sys_type))
cfg.write("# Compiler Spec: {0}\n".format(spec.compiler))
cfg.write("# CMake executable path: %s\n" % cmake_exe)
cfg.write("#{0}\n\n".format("-" * 80))
if "blt" in spec:
cfg.write(cmake_cache_entry("BLT_SOURCE_DIR", spec["blt"].prefix))
#######################
# Compiler Settings
#######################
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Compilers\n")
cfg.write("#{0}\n\n".format("-" * 80))
cfg.write(cmake_cache_entry("CMAKE_C_COMPILER", c_compiler))
cfg.write(cmake_cache_entry("CMAKE_CXX_COMPILER", cpp_compiler))
# use global spack compiler flags
cflags = " ".join(spec.compiler_flags["cflags"])
cxxflags = " ".join(spec.compiler_flags["cxxflags"])
if "%intel" in spec:
cflags += " -qoverride-limits"
cxxflags += " -qoverride-limits"
if cflags:
cfg.write(cmake_cache_entry("CMAKE_C_FLAGS", cflags))
if cxxflags:
cfg.write(cmake_cache_entry("CMAKE_CXX_FLAGS", cxxflags))
release_flags = "-O3 -DNDEBUG"
cfg.write(cmake_cache_string("CMAKE_CXX_FLAGS_RELEASE", release_flags))
reldebinf_flags = "-O3 -g -DNDEBUG"
cfg.write(cmake_cache_string("CMAKE_CXX_FLAGS_RELWITHDEBINFO", reldebinf_flags))
debug_flags = "-O0 -g"
cfg.write(cmake_cache_string("CMAKE_CXX_FLAGS_DEBUG", debug_flags))
if "%clang arch=linux-rhel7-ppc64le" in spec:
cfg.write(cmake_cache_entry("CMAKE_EXE_LINKER_FLAGS", "-Wl,--no-toc-optimize"))
if "+cuda" in spec:
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Cuda\n")
cfg.write("#{0}\n\n".format("-" * 80))
cfg.write(cmake_cache_option("ENABLE_CUDA", True))
cfg.write(cmake_cache_entry("CMAKE_CUDA_STANDARD", 14))
cudatoolkitdir = spec["cuda"].prefix
cfg.write(cmake_cache_entry("CUDA_TOOLKIT_ROOT_DIR", cudatoolkitdir))
cudacompiler = "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc"
cfg.write(cmake_cache_entry("CMAKE_CUDA_COMPILER", cudacompiler))
cmake_cuda_flags = (
"-restrict --expt-extended-lambda -Werror "
"cross-execution-space-call,reorder,"
"deprecated-declarations"
)
archSpecifiers = ("-mtune", "-mcpu", "-march", "-qtune", "-qarch")
for archSpecifier in archSpecifiers:
for compilerArg in spec.compiler_flags["cxxflags"]:
if compilerArg.startswith(archSpecifier):
cmake_cuda_flags += " -Xcompiler " + compilerArg
if not spec.satisfies("cuda_arch=none"):
cuda_arch = spec.variants["cuda_arch"].value
cmake_cuda_flags += " -arch sm_{0}".format(cuda_arch[0])
cfg.write(cmake_cache_string("CMAKE_CUDA_FLAGS", cmake_cuda_flags))
cfg.write(
cmake_cache_string("CMAKE_CUDA_FLAGS_RELEASE", "-O3 -Xcompiler -O3 -DNDEBUG")
)
cfg.write(
cmake_cache_string(
"CMAKE_CUDA_FLAGS_RELWITHDEBINFO", "-O3 -g -lineinfo -Xcompiler -O3"
)
)
cfg.write(cmake_cache_string("CMAKE_CUDA_FLAGS_DEBUG", "-O0 -Xcompiler -O0 -g -G"))
else:
cfg.write(cmake_cache_option("ENABLE_CUDA", False))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# CAMP\n")
cfg.write("#{0}\n\n".format("-" * 80))
cfg.write(cmake_cache_entry("CAMP_DIR", spec["camp"].prefix))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# RAJA\n")
cfg.write("#{0}\n\n".format("-" * 80))
cfg.write(cmake_cache_entry("RAJA_DIR", spec["raja"].prefix))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Umpire\n")
cfg.write("#{0}\n\n".format("-" * 80))
if "+umpire" in spec:
cfg.write(cmake_cache_option("ENABLE_UMPIRE", True))
cfg.write(cmake_cache_entry("UMPIRE_DIR", spec["umpire"].prefix))
else:
cfg.write(cmake_cache_option("ENABLE_UMPIRE", False))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# CHAI\n")
cfg.write("#{0}\n\n".format("-" * 80))
if "+chai" in spec:
cfg.write(cmake_cache_option("ENABLE_CHAI", True))
cfg.write(cmake_cache_entry("CHAI_DIR", spec["chai"].prefix))
else:
cfg.write(cmake_cache_option("ENABLE_CHAI", False))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Caliper\n")
cfg.write("#{0}\n\n".format("-" * 80))
if "+caliper" in spec:
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Caliper\n")
cfg.write("#{0}\n\n".format("-" * 80))
cfg.write(cmake_cache_option("ENABLE_CALIPER", True))
cfg.write(cmake_cache_entry("CALIPER_DIR", spec["caliper"].prefix))
else:
cfg.write(cmake_cache_option("ENABLE_CALIPER", False))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Python\n")
cfg.write("#{0}\n\n".format("-" * 80))
if "+pylvarray" in spec:
cfg.write(cmake_cache_option("ENABLE_PYLVARRAY", True))
python_exe = os.path.join(spec["python"].prefix.bin, "python3")
cfg.write(cmake_cache_entry("Python3_EXECUTABLE", python_exe))
else:
cfg.write(cmake_cache_option("ENABLE_PYLVARRAY", False))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Documentation\n")
cfg.write("#{0}\n\n".format("-" * 80))
if "+docs" in spec:
cfg.write(cmake_cache_option("ENABLE_DOCS", True))
sphinx_dir = spec["py-sphinx"].prefix
cfg.write(
cmake_cache_string(
"SPHINX_EXECUTABLE", os.path.join(sphinx_dir, "bin", "sphinx-build")
)
)
doxygen_dir = spec["doxygen"].prefix
cfg.write(
cmake_cache_string(
"DOXYGEN_EXECUTABLE", os.path.join(doxygen_dir, "bin", "doxygen")
)
)
else:
cfg.write(cmake_cache_option("ENABLE_DOCS", False))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# addr2line\n")
cfg.write("#{0}\n\n".format("-" * 80))
cfg.write(cmake_cache_option("ENABLE_ADDR2LINE", "+addr2line" in spec))
cfg.write("#{0}\n".format("-" * 80))
cfg.write("# Other\n")
cfg.write("#{0}\n\n".format("-" * 80))
def cmake_args(self):
spec = self.spec
host_config_path = self._get_host_config_path(spec)
options = []
options.extend(["-C", host_config_path])
# Shared libs
options.append(self.define_from_variant("BUILD_SHARED_LIBS", "shared"))
if "~tests~examples~benchmarks" in spec:
options.append("-DENABLE_TESTS=OFF")
else:
options.append("-DENABLE_TESTS=ON")
if "~test" in spec:
options.append("-DDISABLE_UNIT_TESTS=ON")
elif "+tests" in spec and ("%intel" in spec or "%xl" in spec):
warnings.warn(
"The LvArray unit tests take an excessive amount of"
" time to build with the Intel or IBM compilers."
)
options.append(self.define_from_variant("ENABLE_EXAMPLES", "examples"))
options.append(self.define_from_variant("ENABLE_BENCHMARKS", "benchmarks"))
options.append(self.define_from_variant("ENABLE_DOCS", "docs"))
return options