summaryrefslogtreecommitdiff
path: root/lib/spack/spack/build_systems/rocm.py
blob: f6ea0537fd5a00770d71742516de97fe52919ced (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
# 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)

# Troubleshooting advice for +rocm builds:
#
# 1. When building with clang, go your compilers.yaml,
#    add an entry for the amd version of clang, as below.
#    This will ensure that your entire package is compiled/linked
#    with the same compiler version. If you use a different version of
#    clang which is linked against a different version of the gcc library,
#    you will get errors along the lines of:
#    undefined reference to
#       `std::__throw_out_of_range_fmt(char const*, ...)@@GLIBCXX_3.4.20'
#    which is indicative of a mismatch in standard library versions.
#
#    in compilers.yaml
#    - compiler:
#        spec: clang@amd
#        paths:
#          cc: /opt/rocm/llvm/bin/clang
#          cxx: /opt/rocm/llvm/bin/clang++
#          f77:
#          fc:
#        flags: {}
#        operating_system: rhel7
#        target: x86_64
#        modules: []
#        environment: {}
#        extra_rpaths: []
#
#    It is advisable to replace /rocm/ in the paths above with /rocm-version/
#    and introduce spec version numbers to ensure reproducible results.
#
# 2. hip and its dependencies are currently NOT picked up by spack
#    automatically, and should therefore be added to packages.yaml by hand:
#
#    in packages.yaml:
#    hip:
#      externals:
#      - spec: hip
#        prefix: /opt/rocm/hip
#        extra_attributes:
#          compilers:
#            c: /opt/rocm/llvm/bin/clang++
#            c++: /opt/rocm/llvm/bin/clang++
#            hip: /opt/rocm/hip/bin/hipcc
#      buildable: false
#    hsa-rocr-dev:
#      externals:
#      - spec: hsa-rocr-dev
#        prefix: /opt/rocm
#        extra_attributes:
#          compilers:
#            c: /opt/rocm/llvm/bin/clang++
#            cxx: /opt/rocm/llvm/bin/clang++
#      buildable: false
#    llvm-amdgpu:
#      externals:
#      - spec: llvm-amdgpu
#        prefix: /opt/rocm/llvm
#        extra_attributes:
#          compilers:
#            c: /opt/rocm/llvm/bin/clang++
#            cxx: /opt/rocm/llvm/bin/clang++
#      buildable: false
#
#    It is advisable to replace /rocm/ in the paths above with /rocm-version/
#    and introduce spec version numbers to ensure reproducible results.
#
# 3. In part 2, DO NOT list the path to hsa as /opt/rocm/hsa ! You want spack
#    to find hsa in /opt/rocm/include/hsa/hsa.h . The directory of
#    /opt/rocm/hsa also has an hsa.h file, but it won't be found because spack
#    does not like its directory structure.
#

import spack.variant
from spack.directives import conflicts, depends_on, variant
from spack.package_base import PackageBase


class ROCmPackage(PackageBase):
    """Auxiliary class which contains ROCm variant, dependencies and conflicts
    and is meant to unify and facilitate its usage. Closely mimics CudaPackage.

    Maintainers: dtaller
    """

    # https://llvm.org/docs/AMDGPUUsage.html
    # Possible architectures
    amdgpu_targets = (
        "gfx701",
        "gfx801",
        "gfx802",
        "gfx803",
        "gfx900",
        "gfx900:xnack-",
        "gfx902",
        "gfx904",
        "gfx906",
        "gfx906:xnack-",
        "gfx908",
        "gfx908:xnack-",
        "gfx909",
        "gfx90a",
        "gfx90a:xnack-",
        "gfx90a:xnack+",
        "gfx90c",
        "gfx940",
        "gfx941",
        "gfx942",
        "gfx1010",
        "gfx1011",
        "gfx1012",
        "gfx1013",
        "gfx1030",
        "gfx1031",
        "gfx1032",
        "gfx1033",
        "gfx1034",
        "gfx1035",
        "gfx1036",
        "gfx1100",
        "gfx1101",
        "gfx1102",
        "gfx1103",
    )

    variant("rocm", default=False, description="Enable ROCm support")

    # possible amd gpu targets for rocm builds
    variant(
        "amdgpu_target",
        description="AMD GPU architecture",
        values=spack.variant.any_combination_of(*amdgpu_targets),
        sticky=True,
        when="+rocm",
    )

    depends_on("llvm-amdgpu", when="+rocm")
    depends_on("hsa-rocr-dev", when="+rocm")
    depends_on("hip +rocm", when="+rocm")

    # need amd gpu type for rocm builds
    conflicts("amdgpu_target=none", when="+rocm")

    # https://github.com/ROCm-Developer-Tools/HIP/blob/master/bin/hipcc
    # It seems that hip-clang does not (yet?) accept this flag, in which case
    # we will still need to set the HCC_AMDGPU_TARGET environment flag in the
    # hip package file. But I will leave this here for future development.
    @staticmethod
    def hip_flags(amdgpu_target):
        archs = ",".join(amdgpu_target)
        return "--amdgpu-target={0}".format(archs)

    # HIP version vs Architecture

    # TODO: add a bunch of lines like:
    # depends_on('hip@:6.0', when='amdgpu_target=gfx701')
    # to indicate minimum version for each architecture.

    # Add compiler minimum versions based on the first release where the
    # processor is included in llvm/lib/Support/TargetParser.cpp
    depends_on("llvm-amdgpu@4.1.0:", when="amdgpu_target=gfx900:xnack-")
    depends_on("llvm-amdgpu@4.1.0:", when="amdgpu_target=gfx906:xnack-")
    depends_on("llvm-amdgpu@4.1.0:", when="amdgpu_target=gfx908:xnack-")
    depends_on("llvm-amdgpu@4.1.0:", when="amdgpu_target=gfx90c")
    depends_on("llvm-amdgpu@4.3.0:", when="amdgpu_target=gfx90a")
    depends_on("llvm-amdgpu@4.3.0:", when="amdgpu_target=gfx90a:xnack-")
    depends_on("llvm-amdgpu@4.3.0:", when="amdgpu_target=gfx90a:xnack+")
    depends_on("llvm-amdgpu@5.2.0:", when="amdgpu_target=gfx940")
    depends_on("llvm-amdgpu@5.7.0:", when="amdgpu_target=gfx941")
    depends_on("llvm-amdgpu@5.7.0:", when="amdgpu_target=gfx942")
    depends_on("llvm-amdgpu@4.5.0:", when="amdgpu_target=gfx1013")
    depends_on("llvm-amdgpu@3.8.0:", when="amdgpu_target=gfx1030")
    depends_on("llvm-amdgpu@3.9.0:", when="amdgpu_target=gfx1031")
    depends_on("llvm-amdgpu@4.1.0:", when="amdgpu_target=gfx1032")
    depends_on("llvm-amdgpu@4.1.0:", when="amdgpu_target=gfx1033")
    depends_on("llvm-amdgpu@4.3.0:", when="amdgpu_target=gfx1034")
    depends_on("llvm-amdgpu@4.5.0:", when="amdgpu_target=gfx1035")
    depends_on("llvm-amdgpu@5.2.0:", when="amdgpu_target=gfx1036")
    depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1100")
    depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1101")
    depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1102")
    depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1103")

    # Compiler conflicts

    # TODO: add conflicts statements along the lines of
    # arch_platform = ' target=x86_64: platform=linux'
    # conflicts('%gcc@5:', when='+cuda ^cuda@:7.5' + arch_platform)
    # conflicts('platform=darwin', when='+cuda ^cuda@11.0.2:')
    # for hip-related limitations.