2023-01-19 06:30:17 +08:00
|
|
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
2019-03-22 17:58:48 +08:00
|
|
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
|
|
|
|
2021-12-03 09:13:25 +08:00
|
|
|
import os
|
2019-03-22 17:58:48 +08:00
|
|
|
import sys
|
|
|
|
|
2022-05-29 00:55:44 +08:00
|
|
|
from spack.package import *
|
2021-07-09 06:12:30 +08:00
|
|
|
|
2019-03-22 17:58:48 +08:00
|
|
|
|
2021-05-13 07:04:08 +08:00
|
|
|
class Ginkgo(CMakePackage, CudaPackage, ROCmPackage):
|
2019-03-22 17:58:48 +08:00
|
|
|
"""High-performance linear algebra library for manycore systems,
|
|
|
|
with a focus on sparse solution of linear systems."""
|
|
|
|
|
2019-05-02 07:25:39 +08:00
|
|
|
homepage = "https://ginkgo-project.github.io/"
|
2022-07-31 06:19:18 +08:00
|
|
|
git = "https://github.com/ginkgo-project/ginkgo.git"
|
|
|
|
|
2023-06-07 02:58:53 +08:00
|
|
|
test_requires_compiler = True
|
|
|
|
|
2023-02-02 13:07:25 +08:00
|
|
|
maintainers("tcojean", "hartwiganzt")
|
2022-07-31 06:19:18 +08:00
|
|
|
|
|
|
|
tags = ["e4s"]
|
|
|
|
|
|
|
|
version("develop", branch="develop")
|
|
|
|
version("master", branch="master")
|
2023-06-26 20:13:48 +08:00
|
|
|
version("1.6.0", commit="1f1ed46e724334626f016f105213c047e16bc1ae", preferred=True) # v1.6.0
|
|
|
|
version("1.5.0", commit="234594c92b58e2384dfb43c2d08e7f43e2b58e7a") # v1.5.0
|
2022-10-14 00:41:18 +08:00
|
|
|
version("1.5.0.glu_experimental", branch="glu_experimental")
|
2022-11-15 02:33:11 +08:00
|
|
|
version("1.4.0", commit="f811917c1def4d0fcd8db3fe5c948ce13409e28e") # v1.4.0
|
2022-07-31 06:19:18 +08:00
|
|
|
version("1.3.0", commit="4678668c66f634169def81620a85c9a20b7cec78") # v1.3.0
|
|
|
|
version("1.2.0", commit="b4be2be961fd5db45c3d02b5e004d73550722e31") # v1.2.0
|
|
|
|
version("1.1.1", commit="08d2c5200d3c78015ac8a4fd488bafe1e4240cf5") # v1.1.1
|
|
|
|
version("1.1.0", commit="b9bec8225442b3eb2a85a870efa112ab767a17fb") # v1.1.0
|
|
|
|
version("1.0.0", commit="45244641e0c2b19ba33aecd25153c0bddbcbe1a0") # v1.0.0
|
|
|
|
|
|
|
|
variant("shared", default=True, description="Build shared libraries")
|
|
|
|
variant("full_optimizations", default=False, description="Compile with all optimizations")
|
|
|
|
variant("openmp", default=sys.platform != "darwin", description="Build with OpenMP")
|
|
|
|
variant("oneapi", default=False, description="Build with oneAPI support")
|
|
|
|
variant("develtools", default=False, description="Compile with develtools enabled")
|
|
|
|
variant("hwloc", default=False, description="Enable HWLOC support")
|
2022-11-15 02:33:11 +08:00
|
|
|
variant("mpi", default=False, description="Enable MPI support")
|
2022-07-31 06:19:18 +08:00
|
|
|
|
|
|
|
depends_on("cmake@3.9:", type="build")
|
|
|
|
depends_on("cuda@9:", when="+cuda")
|
2022-11-15 02:33:11 +08:00
|
|
|
depends_on("mpi", when="+mpi")
|
2022-07-31 06:19:18 +08:00
|
|
|
|
2022-11-15 02:33:11 +08:00
|
|
|
depends_on("rocthrust", when="+rocm")
|
|
|
|
depends_on("hipsparse", when="+rocm")
|
|
|
|
depends_on("hipblas", when="+rocm")
|
|
|
|
depends_on("rocrand", when="+rocm")
|
|
|
|
# ROCPRIM is not a direct dependency, but until we have reviewed our CMake
|
|
|
|
# setup for rocthrust, this needs to also be added here.
|
|
|
|
depends_on("rocprim", when="+rocm")
|
|
|
|
depends_on("hwloc@2.1:", when="+hwloc")
|
2022-07-31 06:19:18 +08:00
|
|
|
|
|
|
|
depends_on("googletest", type="test")
|
|
|
|
depends_on("numactl", type="test", when="+hwloc")
|
|
|
|
|
|
|
|
depends_on("intel-oneapi-mkl", when="+oneapi")
|
|
|
|
depends_on("intel-oneapi-dpl", when="+oneapi")
|
|
|
|
|
|
|
|
conflicts("%gcc@:5.2.9")
|
2021-05-13 07:04:08 +08:00
|
|
|
conflicts("+rocm", when="@:1.1.1")
|
2022-11-15 02:33:11 +08:00
|
|
|
conflicts("+mpi", when="@:1.4.0")
|
2021-05-13 07:04:08 +08:00
|
|
|
conflicts("+cuda", when="+rocm")
|
2021-12-03 09:13:25 +08:00
|
|
|
conflicts("+openmp", when="+oneapi")
|
2021-05-13 07:04:08 +08:00
|
|
|
|
|
|
|
# ROCm 4.1.0 breaks platform settings which breaks Ginkgo's HIP support.
|
|
|
|
conflicts("^hip@4.1.0:", when="@:1.3.0")
|
|
|
|
conflicts("^hipblas@4.1.0:", when="@:1.3.0")
|
|
|
|
conflicts("^hipsparse@4.1.0:", when="@:1.3.0")
|
|
|
|
conflicts("^rocthrust@4.1.0:", when="@:1.3.0")
|
2022-11-15 02:33:11 +08:00
|
|
|
conflicts("^rocprim@4.1.0:", when="@:1.3.0")
|
2021-09-06 20:11:35 +08:00
|
|
|
|
|
|
|
# Skip smoke tests if compatible hardware isn't found
|
2022-07-31 06:19:18 +08:00
|
|
|
patch("1.4.0_skip_invalid_smoke_tests.patch", when="@1.4.0")
|
2019-11-08 08:51:20 +08:00
|
|
|
|
2021-12-03 09:13:25 +08:00
|
|
|
# Newer DPC++ compilers use the updated SYCL 2020 standard which change
|
|
|
|
# kernel attribute propagation rules. This doesn't work well with the
|
|
|
|
# initial Ginkgo oneAPI support.
|
2022-07-31 06:19:18 +08:00
|
|
|
patch("1.4.0_dpcpp_use_old_standard.patch", when="+oneapi @1.4.0")
|
2021-12-03 09:13:25 +08:00
|
|
|
|
2022-12-13 03:46:20 +08:00
|
|
|
# Add missing include statement
|
2023-06-26 20:13:48 +08:00
|
|
|
patch("thrust-count-header.patch", when="+rocm @1.5.0")
|
2022-12-13 03:46:20 +08:00
|
|
|
|
2021-12-03 09:13:25 +08:00
|
|
|
def setup_build_environment(self, env):
|
|
|
|
spec = self.spec
|
2022-07-31 06:19:18 +08:00
|
|
|
if "+oneapi" in spec:
|
|
|
|
env.set("MKLROOT", join_path(spec["intel-oneapi-mkl"].prefix, "mkl", "latest"))
|
|
|
|
env.set("DPL_ROOT", join_path(spec["intel-oneapi-dpl"].prefix, "dpl", "latest"))
|
2021-12-03 09:13:25 +08:00
|
|
|
|
2019-03-22 17:58:48 +08:00
|
|
|
def cmake_args(self):
|
2020-10-11 10:08:58 +08:00
|
|
|
# Check that the have the correct C++ standard is available
|
2022-07-31 06:19:18 +08:00
|
|
|
if self.spec.satisfies("@:1.2.0"):
|
2020-10-11 10:08:58 +08:00
|
|
|
try:
|
|
|
|
self.compiler.cxx11_flag
|
|
|
|
except UnsupportedCompilerFlag:
|
2022-07-31 06:19:18 +08:00
|
|
|
raise InstallError("Ginkgo requires a C++11-compliant C++ compiler")
|
2020-10-11 10:08:58 +08:00
|
|
|
else:
|
|
|
|
try:
|
|
|
|
self.compiler.cxx14_flag
|
|
|
|
except UnsupportedCompilerFlag:
|
2022-07-31 06:19:18 +08:00
|
|
|
raise InstallError("Ginkgo requires a C++14-compliant C++ compiler")
|
2021-12-03 09:13:25 +08:00
|
|
|
|
|
|
|
cxx_is_dpcpp = os.path.basename(self.compiler.cxx) == "dpcpp"
|
2022-07-31 06:19:18 +08:00
|
|
|
if self.spec.satisfies("+oneapi") and not cxx_is_dpcpp:
|
|
|
|
raise InstallError(
|
|
|
|
"Ginkgo's oneAPI backend requires the" + "DPC++ compiler as main CXX compiler."
|
|
|
|
)
|
2020-10-11 10:08:58 +08:00
|
|
|
|
2019-03-22 17:58:48 +08:00
|
|
|
spec = self.spec
|
2021-05-19 18:59:06 +08:00
|
|
|
from_variant = self.define_from_variant
|
2020-10-11 10:08:58 +08:00
|
|
|
args = [
|
2022-07-31 06:19:18 +08:00
|
|
|
from_variant("GINKGO_BUILD_CUDA", "cuda"),
|
|
|
|
from_variant("GINKGO_BUILD_HIP", "rocm"),
|
2022-11-15 02:33:11 +08:00
|
|
|
from_variant("GINKGO_BUILD_DPCPP", "oneapi"),
|
2022-07-31 06:19:18 +08:00
|
|
|
from_variant("GINKGO_BUILD_OMP", "openmp"),
|
2022-11-15 02:33:11 +08:00
|
|
|
from_variant("GINKGO_BUILD_MPI", "mpi"),
|
2022-07-31 06:19:18 +08:00
|
|
|
from_variant("BUILD_SHARED_LIBS", "shared"),
|
|
|
|
from_variant("GINKGO_JACOBI_FULL_OPTIMIZATIONS", "full_optimizations"),
|
|
|
|
from_variant("GINKGO_BUILD_HWLOC", "hwloc"),
|
|
|
|
from_variant("GINKGO_DEVEL_TOOLS", "develtools"),
|
2019-05-02 07:25:39 +08:00
|
|
|
# As we are not exposing benchmarks, examples, tests nor doc
|
|
|
|
# as part of the installation, disable building them altogether.
|
2022-07-31 06:19:18 +08:00
|
|
|
"-DGINKGO_BUILD_BENCHMARKS=OFF",
|
|
|
|
"-DGINKGO_BUILD_DOC=OFF",
|
|
|
|
"-DGINKGO_BUILD_EXAMPLES=OFF",
|
2022-11-15 02:33:11 +08:00
|
|
|
"-DGINKGO_WITH_CCACHE=OFF",
|
2022-07-31 06:19:18 +08:00
|
|
|
self.define("GINKGO_BUILD_TESTS", self.run_tests),
|
2021-05-13 07:04:08 +08:00
|
|
|
# Let spack handle the RPATH
|
2022-07-31 06:19:18 +08:00
|
|
|
"-DGINKGO_INSTALL_RPATH=OFF",
|
2019-03-22 17:58:48 +08:00
|
|
|
]
|
2021-05-13 07:04:08 +08:00
|
|
|
|
|
|
|
if self.run_tests:
|
2022-07-31 06:19:18 +08:00
|
|
|
args.append("-DGINKGO_USE_EXTERNAL_GTEST=ON")
|
2021-05-13 07:04:08 +08:00
|
|
|
|
2022-07-31 06:19:18 +08:00
|
|
|
if "+cuda" in spec:
|
|
|
|
archs = spec.variants["cuda_arch"].value
|
|
|
|
if archs != "none":
|
2021-05-13 07:04:08 +08:00
|
|
|
arch_str = ";".join(archs)
|
2022-07-31 06:19:18 +08:00
|
|
|
args.append("-DGINKGO_CUDA_ARCHITECTURES={0}".format(arch_str))
|
|
|
|
|
|
|
|
if "+rocm" in spec:
|
|
|
|
args.append("-DHIP_PATH={0}".format(spec["hip"].prefix))
|
|
|
|
args.append("-DHIP_CLANG_PATH={0}/bin".format(spec["llvm-amdgpu"].prefix))
|
|
|
|
args.append("-DHIP_CLANG_INCLUDE_PATH={0}/include".format(spec["llvm-amdgpu"].prefix))
|
|
|
|
args.append("-DHIPSPARSE_PATH={0}".format(spec["hipsparse"].prefix))
|
|
|
|
args.append("-DHIPBLAS_PATH={0}".format(spec["hipblas"].prefix))
|
|
|
|
args.append("-DHIPRAND_PATH={0}/hiprand".format(spec["rocrand"].prefix))
|
|
|
|
args.append("-DROCRAND_PATH={0}/rocrand".format(spec["rocrand"].prefix))
|
2022-11-15 02:33:11 +08:00
|
|
|
args.append("-DROCPRIM_INCLUDE_DIRS={0}".format(spec["rocprim"].prefix.include))
|
2022-07-31 06:19:18 +08:00
|
|
|
archs = self.spec.variants["amdgpu_target"].value
|
|
|
|
if archs != "none":
|
2021-05-13 07:04:08 +08:00
|
|
|
arch_str = ";".join(archs)
|
2022-07-31 06:19:18 +08:00
|
|
|
args.append("-DGINKGO_HIP_AMDGPU={0}".format(arch_str))
|
2022-08-12 15:20:47 +08:00
|
|
|
if spec.satisfies("^hip@5.2.0:"):
|
|
|
|
args.append(
|
|
|
|
self.define("CMAKE_MODULE_PATH", self.spec["hip"].prefix.lib.cmake.hip)
|
|
|
|
)
|
2020-10-11 10:08:58 +08:00
|
|
|
return args
|
2020-11-13 04:42:34 +08:00
|
|
|
|
2023-06-07 02:58:53 +08:00
|
|
|
@property
|
|
|
|
def extra_install_tests(self):
|
|
|
|
return "test_install" if self.spec.satisfies("@1.3.0") else "test"
|
2022-09-20 03:37:34 +08:00
|
|
|
|
2022-07-31 06:19:18 +08:00
|
|
|
@run_after("install")
|
2022-09-20 03:37:34 +08:00
|
|
|
def cache_test_sources(self):
|
|
|
|
self.cache_extra_test_sources(self.extra_install_tests)
|
|
|
|
|
2023-06-07 02:58:53 +08:00
|
|
|
def _cached_tests_src_dir(self, script):
|
|
|
|
"""The cached smoke test source directory for the script."""
|
|
|
|
subdir = script if self.spec.satisfies("@1.4.0:") else ""
|
|
|
|
return join_path(self.test_suite.current_test_cache_dir, self.extra_install_tests, subdir)
|
2022-09-20 03:37:34 +08:00
|
|
|
|
2023-06-07 02:58:53 +08:00
|
|
|
def _build_and_run_test(self, script):
|
|
|
|
"""Build and run the test against the installation."""
|
|
|
|
src_dir = self._cached_tests_src_dir(script)
|
2022-09-20 03:37:34 +08:00
|
|
|
|
|
|
|
cmake_args = [
|
2023-06-07 02:58:53 +08:00
|
|
|
f"-DCMAKE_C_COMPILER={os.environ['CC']}",
|
|
|
|
f"-DCMAKE_CXX_COMPILER={os.environ['CXX']}",
|
|
|
|
src_dir,
|
2022-09-20 03:37:34 +08:00
|
|
|
]
|
|
|
|
|
|
|
|
# Fix: For HIP tests, add the ARCH compilation flags when not present
|
|
|
|
if "+rocm" in self.spec:
|
2023-06-07 02:58:53 +08:00
|
|
|
src_path = join_path(src_dir, "CMakeLists.txt")
|
2022-09-20 03:37:34 +08:00
|
|
|
cmakelists = open(src_path, "rt")
|
|
|
|
data = cmakelists.read()
|
|
|
|
data = data.replace(
|
|
|
|
'CLANG_OPTIONS "${GINKGO_PIC_OPTION}"',
|
|
|
|
'CLANG_OPTIONS "${GINKGO_AMD_ARCH_FLAGS}" "${GINKGO_PIC_OPTION}"',
|
|
|
|
)
|
|
|
|
cmakelists.close()
|
|
|
|
cmakelists = open(src_path, "wt")
|
|
|
|
cmakelists.write(data)
|
|
|
|
cmakelists.close()
|
|
|
|
|
2023-06-07 02:58:53 +08:00
|
|
|
cmake = which(self.spec["cmake"].prefix.bin.cmake)
|
|
|
|
make = which("make")
|
|
|
|
with working_dir(src_dir):
|
|
|
|
cmake(*cmake_args)
|
|
|
|
make()
|
|
|
|
exe = which(script)
|
|
|
|
output = exe(output=str.split, error=str.split)
|
|
|
|
assert "correctly detected and is complete" in output
|
|
|
|
|
|
|
|
def test_install(self):
|
|
|
|
"""build, run and check results of test_install"""
|
|
|
|
if not self.spec.satisfies("@1.3.0:"):
|
|
|
|
raise SkipTest("Test is only available for v1.3.0:")
|
|
|
|
|
|
|
|
self._build_and_run_test("test_install")
|
|
|
|
|
|
|
|
def test_install_cuda(self):
|
|
|
|
"""build, run and check results of test_install_cuda"""
|
|
|
|
if not self.spec.satisfies("@1.4.0: +cuda"):
|
|
|
|
raise SkipTest("Test is only available for v1.4.0: +cuda")
|
|
|
|
|
|
|
|
self._build_and_run_test("test_install_cuda")
|
|
|
|
|
|
|
|
def test_install_hip(self):
|
|
|
|
"""build, run and check results of test_install_hip"""
|
|
|
|
if not self.spec.satisfies("@1.4.0: +rocm"):
|
|
|
|
raise SkipTest("Test is only available for v1.4.0: +rocm")
|
|
|
|
|
|
|
|
self._build_and_run_test("test_install_hip")
|
|
|
|
|
|
|
|
def test_exportbuild(self):
|
|
|
|
"""build, run and check results of test_exportbuild"""
|
|
|
|
if not self.spec.satisfies("@1.4.0:"):
|
|
|
|
raise SkipTest("Test is only available for v1.4.0:")
|
|
|
|
|
|
|
|
self._build_and_run_test("test_exportbuild")
|