summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/sgpp/package.py
blob: 635f047166e42391314fdbf7fb29e768b7deec5c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# 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)