summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/gasnet/package.py
blob: 516accb30db6a5840b142cd166cbb4dac4119fd0 (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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# Copyright 2013-2023 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

from spack.package import *


class Gasnet(Package, CudaPackage, ROCmPackage):
    """GASNet is a language-independent, networking middleware layer that
    provides network-independent, high-performance communication primitives
    including Remote Memory Access (RMA) and Active Messages (AM). It has been
    used to implement parallel programming models and libraries such as UPC,
    UPC++, Co-Array Fortran, Legion, Chapel, and many others. The interface is
    primarily intended as a compilation target and for use by runtime library
    writers (as opposed to end users), and the primary goals are high
    performance, interface portability, and expressiveness.

    ***NOTICE***: The GASNet library built by this Spack package is ONLY intended for
    unit-testing purposes, and is generally UNSUITABLE FOR PRODUCTION USE.
    The RECOMMENDED way to build GASNet is as an embedded library as configured
    by the higher-level client runtime package (UPC++, Legion, etc), including
    system-specific configuration.
    """

    homepage = "https://gasnet.lbl.gov"
    url = "https://gasnet.lbl.gov/EX/GASNet-2021.3.0.tar.gz"
    git = "https://bitbucket.org/berkeleylab/gasnet.git"

    maintainers("PHHargrove", "bonachea")

    tags = ["e4s", "ecp"]

    version("develop", branch="develop")
    version("main", branch="stable")
    version("master", branch="master")

    version("2023.3.0", sha256="e1fa783d38a503cf2efa7662be591ca5c2bb98d19ac72a9bc6da457329a9a14f")
    version("2022.9.2", sha256="2352d52f395a9aa14cc57d82957d9f1ebd928d0a0021fd26c5f1382a06cd6f1d")
    version("2022.9.0", sha256="6873ff4ad8ebee49da4378f2d78095a6ccc31333d6ae4cd739b9f772af11f936")
    version("2022.3.0", sha256="91b59aa84c0680c807e00d3d1d8fa7c33c1aed50b86d1616f93e499620a9ba09")
    version("2021.9.0", sha256="1b6ff6cdad5ecf76b92032ef9507e8a0876c9fc3ee0ab008de847c1fad0359ee")
    version("2021.3.0", sha256="8a40fb3fa8bacc3922cd4d45217816fcb60100357ab97fb622a245567ea31747")
    version("2020.10.0", sha256="ed17baf7fce90499b539857ee37b3eea961aa475cffbde77e4c607a34ece06a0")
    version("2020.3.0", sha256="019eb2d2284856e6fabe6c8c0061c874f10e95fa0265245f227fd3497f1bb274")
    version("2019.9.0", sha256="117f5fdb16e53d0fa8a47a1e28cccab1d8020ed4f6e50163d985dc90226aaa2c")
    # Do NOT add older versions here.
    # GASNet-EX releases over 2 years old are not supported.

    # The optional network backends:
    variant(
        "conduits",
        values=any_combination_of("smp", "mpi", "ibv", "udp", "ofi", "ucx").with_default("smp"),
        description="The hardware-dependent network backends to enable.\n"
        + "(smp) = SMP conduit for single-node operation ;\n"
        + "(ibv) = Native InfiniBand verbs conduit ;\n"
        + "(ofi) = OFI conduit over libfabric, for HPE Cray Slingshot and Intel Omni-Path ;\n"
        + "(udp) = Portable UDP conduit, for Ethernet networks ;\n"
        + "(mpi) = Low-performance/portable MPI conduit ;\n"
        + "(ucx) = EXPERIMENTAL UCX conduit for Mellanox IB/RoCE ConnectX-5+ ;\n"
        + "For detailed recommendations, consult https://gasnet.lbl.gov",
    )

    variant("debug", default=False, description="Enable library debugging mode")

    variant(
        "cuda",
        default=False,
        description="Enables support for the CUDA memory kind in some conduits.\n"
        + "NOTE: Requires CUDA Driver library be present on the build system",
    )

    variant(
        "rocm",
        default=False,
        description="Enables support for the ROCm/HIP memory kind in some conduits",
    )

    depends_on("mpi", when="conduits=mpi")

    depends_on("autoconf@2.69", type="build", when="@master:")
    depends_on("automake@1.16:", type="build", when="@master:")

    conflicts("^hip@:4.4.0", when="+rocm")

    def install(self, spec, prefix):
        if spec.satisfies("@master:"):
            bootstrapsh = Executable("./Bootstrap")
            bootstrapsh()
            # Record git-describe when fetched from git:
            try:
                git = which("git")
                git("describe", "--long", "--always", output="version.git")
            except spack.util.executable.ProcessError:
                spack.main.send_warning_to_tty("Omitting version stamp due to git error")

        # The GASNet-EX library has a highly multi-dimensional configure space,
        # to accomodate the varying behavioral requirements of each client runtime.
        # The library's ABI/link compatibility is strongly dependent on these
        # client-specific build-time settings, and that variability is deliberately NOT
        # encoded in the variants of this package. The recommended way to build/deploy
        # GASNet is as an EMBEDDED library within the build of the client package
        # (eg. Berkeley UPC, UPC++, Legion, etc), some of which provide build-time
        # selection of the GASNet library sources. This spack package provides
        # the GASNet-EX sources, for use by appropriate client packages.
        install_tree(".", prefix + "/src")

        # Library build is provided for unit-testing purposes only (see notice above)
        if "conduits=none" not in spec:
            options = ["--prefix=%s" % prefix]

            if "+debug" in spec:
                options.append("--enable-debug")

            if "+cuda" in spec:
                options.append("--enable-kind-cuda-uva")

            if "+rocm" in spec:
                options.append("--enable-kind-hip")

            if "conduits=mpi" in spec:
                options.append("--enable-mpi-compat")
            else:
                options.append("--disable-mpi-compat")

            options.append("--disable-auto-conduit-detect")
            for c in spec.variants["conduits"].value:
                options.append("--enable-" + c)

            options.append("--enable-rpath")

            configure(*options)
            make()
            make("install")

            for c in spec.variants["conduits"].value:
                testdir = join_path(self.prefix.tests, c)
                mkdirp(testdir)
                make("-C", c + "-conduit", "testgasnet-par")
                install(c + "-conduit/testgasnet", testdir)
            make("-C", c + "-conduit", "testtools-par")
            install(c + "-conduit/testtools", self.prefix.tests)

    @run_after("install")
    @on_package_attributes(run_tests=True)
    def check_install(self):
        if "conduits=smp" in self.spec:
            make("-C", "smp-conduit", "run-tests")
        self.test_testtools()

    def _setup_test_env(self):
        """Set up key stand-alone test environment variables."""
        os.environ["GASNET_VERBOSEENV"] = "1"  # include diagnostic info

        # The following are not technically relevant to test_testtools
        os.environ["GASNET_SPAWN_VERBOSE"] = "1"  # include spawning diagnostics
        if "GASNET_SSH_SERVERS" not in os.environ:
            os.environ["GASNET_SSH_SERVERS"] = "localhost " * 4

    def test_testtools(self):
        """run testtools and check output"""
        if "conduits=none" in self.spec:
            raise SkipTest("Test requires conduit libraries")

        testtools_path = join_path(self.prefix.tests, "testtools")
        assert os.path.exists(testtools_path), "Test requires testtools"

        self._setup_test_env()
        testtools = which(testtools_path, required=True)
        out = testtools(output=str.split, error=str.split)
        assert "Done." in out

    def test_testgasnet(self):
        """run testgasnet and check output"""
        if "conduits=none" in self.spec:
            raise SkipTest("Test requires conduit libraries")

        self._setup_test_env()
        ranks = "4"
        spawner = {
            "smp": ["env", "GASNET_PSHM_NODES=" + ranks],
            "mpi": [join_path(self.prefix.bin, "gasnetrun_mpi"), "-n", ranks],
            "ibv": [join_path(self.prefix.bin, "gasnetrun_ibv"), "-n", ranks],
            "ofi": [join_path(self.prefix.bin, "gasnetrun_ofi"), "-n", ranks],
            "ucx": [join_path(self.prefix.bin, "gasnetrun_ucx"), "-n", ranks],
            "udp": [join_path(self.prefix.bin, "amudprun"), "-spawn", "L", "-np", ranks],
        }

        expected = "done."
        for c in self.spec.variants["conduits"].value:
            os.environ["GASNET_SUPERNODE_MAXSIZE"] = "0" if (c == "smp") else "1"
            test = join_path(self.prefix.tests, c, "testgasnet")

            with test_part(
                self,
                "test_testgasnet_{0}".format(c),
                purpose="run {0}-conduit/testgasnet".format(c),
            ):
                exe = which(spawner[c][0], required=True)

                args = spawner[c][1:] + [test]
                out = exe(*args, output=str.split, error=str.split)
                assert expected in out