# 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) from spack.package import * from spack.pkg.builtin.boost import Boost class Sgpp(SConsPackage): """SGpp is a library and framework for sparse grids in different flavors. SGpp supports both hierarchical spatially-adaptive sparse grids and the dimensionally-adaptive sparse grid combination technique.""" homepage = "https://sgpp.sparsegrids.org" url = "https://github.com/SGpp/SGpp/archive/v3.2.0.tar.gz" git = "https://github.com/SGpp/SGpp.git" maintainers("G-071", "leiterrl", "pfluegdk") version("master", branch="master") version("3.4.0", sha256="450d4002850b0a48c561abe221b634261ca44eee111ca605c3e80797182f40b3") version("3.3.0", sha256="ca4d5b79f315b425ce69b04940c141451a76848bf1bd7b96067217304c68e2d4") version("3.2.0", sha256="dab83587fd447f92ed8546eacaac6b8cbe65b8db5e860218c0fa2e42f776962d") # Note: Older versions of SGpp required Python 2 (and offered Python 2 bindings) and have # thus been removed from this list as Spack now requires Python 3. # The last spack release with support for Python 2 is v0.19 - there, the spack package # still supports SGpp versions 3.1.0 and 3.0.0 if required. # Patches with bugfixes that are necessary to build old SGpp versions # with spack. Patches are submitted upstream, but need to applied # for versions too old to include them as they will not be # backported for old releases: # Patch that ensures libraries will actually # be copied into prefix/lib upon installation # (otherwise it would be prefix/lib/sgpp) # Fixed in SGpp in PR https://github.com/SGpp/SGpp/pull/222 patch("directory.patch", when="@1.0.0:3.2.0") # Fix faulty setup.py introduced in 3.2.0 # Fixed in SGpp in version 3.3.0 patch("fix-setup-py.patch", when="@3.2.0") # Fix compilation issue with opencl introduced in 3.2.0 # Fixed in SGpp in PR https://github.com/SGpp/SGpp/pull/219 patch("ocl.patch", when="@3.2.0+opencl") # Fixes compilation with AVX512 and datadriven # Fixed in SGpp in PR https://github.com/SGpp/SGpp/pull/229 patch("avx512_datadriven_compilation.patch", when="@:3.3.0+datadriven") # Continue despite distutils deprecation warning! # distutils will be removed in future SGpp versions. See # https://github.com/SGpp/SGpp/issues/263 for associated issue! # TODO Once distutils is removed from SGpp, limit patch to @:3.4.0 patch("disable_disutils_deprecation_warning.patch", when="^python@3.10:3.11") variant("python", default=True, description="Provide Python bindings for SGpp") variant("optimization", default=True, description="Builds the optimization module of SGpp") variant("pde", default=True, description="Builds the datadriven module of SGpp") variant("quadrature", default=True, description="Builds the datadriven module of SGpp") variant("datadriven", default=False, description="Builds the datadriven module of SGpp") variant("misc", default=False, description="Builds the misc module of SGpp") variant("combigrid", default=False, description="Builds the combigrid module of SGpp") variant("solver", default=True, description="Builds the solver module of SGpp") variant( "opencl", default=False, description="Enables support for OpenCL accelerated operations" ) variant("mpi", default=False, description="Enables support for MPI-distributed operations") # Mandatory dependencies depends_on("scons@3:", type=("build")) depends_on("zlib-api", type=("link")) # Python dependencies extends("python", when="+python") depends_on("py-pip", when="+python", type="build") depends_on("py-wheel", when="+python", type="build") # TODO allow newer versions once distutils is removed from SGpp depends_on("py-setuptools@:59", type=("build")) # TODO allow newer versions once distutils is removed from SGpp depends_on("python@3.7:3.11", type=("build", "run")) depends_on("swig@3:", when="+python", type=("build")) depends_on("py-numpy@1.17:", when="+python", type=("build", "run")) depends_on("py-scipy@1.3:", when="+python", type=("build", "run")) # OpenCL dependency depends_on("opencl@1.1:", when="+opencl", type=("build", "run")) # MPI dependency depends_on("mpi", when="+mpi", type=("build", "run")) # Testing requires boost test depends_on("boost+test", type=("test")) # TODO: replace this with an explicit list of components of Boost, # for instance depends_on('boost +filesystem') # See https://github.com/spack/spack/pull/22303 for reference depends_on(Boost.with_default_variants, type=("test")) # Compiler with C++11 support is required conflicts("%gcc@:4.8.4", msg="Compiler with c++11 support is required!") conflicts("%apple-clang@:3.9", msg="Compiler with c++11 support is required!") conflicts("%clang@:3.2", msg="Compiler with c++11 support is required!") conflicts("%intel@:14", msg="Compiler with c++11 support is required!") # Solver python bindings are actually using the pde module at one point: conflicts("-pde", when="+python+solver") # some modules depend on each other (notably datadriven and misc) conflicts("+pde", when="-solver") # Datadriven module requirements conflicts("+datadriven", when="-solver") conflicts("+datadriven", when="-optimization") conflicts("+datadriven", when="-pde") # Misc module requirements conflicts("+misc", when="-datadriven") conflicts("+misc", when="-solver") conflicts("+misc", when="-optimization") conflicts("+misc", when="-pde") # Combigrid module requirements (for 3.2.0 or older) # newer combigrids have no dependencies conflicts("+combigrid", when="@1.0.0:3.2.0~optimization") conflicts("+combigrid", when="@1.0.0:3.2.0~pde") conflicts("+combigrid", when="@1.0.0:3.2.0~solver") conflicts("+combigrid", when="@1.0.0:3.2.0~quadrature") patch("for_aarch64.patch", when="target=aarch64:") def build_args(self, spec, prefix): # Testing parameters if self.run_tests: self.args = ["COMPILE_BOOST_TESTS=1", "RUN_BOOST_TESTS=1"] if "+python" in spec: self.args.append("RUN_PYTHON_TESTS=1") if spec.satisfies("@1.0.0:3.2.0"): self.args.append("RUN_CPPLINT=1") else: # argument was renamed after 3.2.0 self.args.append("CHECK_STYLE=1") else: self.args = ["COMPILE_BOOST_TESTS=0", "RUN_BOOST_TESTS=0", "RUN_PYTHON_TESTS=0"] if spec.satisfies("@1.0.0:3.2.0"): self.args.append("RUN_CPPLINT=0") else: # argument was renamed after 3.2.0 self.args.append("CHECK_STYLE=0") # Install direction self.args.append("PREFIX={0}".format(prefix)) # Generate swig bindings? self.args.append("SG_PYTHON={0}".format("1" if "+python" in spec else "0")) # Java bindings are now deprecated within SGpp self.args.append("SG_JAVA=0") # Which modules to build? self.args.append("SG_OPTIMIZATION={0}".format("1" if "+optimization" in spec else "0")) self.args.append("SG_QUADRATURE={0}".format("1" if "+quadrature" in spec else "0")) self.args.append("SG_PDE={0}".format("1" if "+pde" in spec else "0")) self.args.append("SG_DATADRIVEN={0}".format("1" if "+datadriven" in spec else "0")) self.args.append("SG_COMBIGRID={0}".format("1" if "+combigrid" in spec else "0")) self.args.append("SG_SOLVER={0}".format("1" if "+solver" in spec else "0")) self.args.append("SG_MISC={0}".format("1" if "+misc" in spec else "0")) # SIMD scons parameter (pick according to simd spec) if "avx512" in self.spec.target: self.args.append("ARCH=avx512") elif "avx2" in self.spec.target: self.args.append("ARCH=avx2") elif "avx" in self.spec.target: self.args.append("ARCH=avx") elif "fma4" in self.spec.target: self.args.append("ARCH=fma4") elif "sse42" in self.spec.target: self.args.append("ARCH=sse42") elif "sse3" in self.spec.target: self.args.append("ARCH=sse3") # OpenCL Flags self.args.append("USE_OCL={0}".format("1" if "+opencl" in spec else "0")) # Get the mpicxx compiler from the Spack spec # (makes certain we use the one from spack): if "+mpi" in spec: self.args.append("CXX={0}".format(self.spec["mpi"].mpicxx)) else: self.args.append("CXX={0}".format(self.compiler.cxx)) return self.args def install_args(self, spec, prefix): # SGpp expects the same args for the install and build commands return self.args @run_after("install") def python_install(self): if "+python" in self.spec: args = std_pip_args + ["--prefix=" + self.prefix, "."] pip(*args)