Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Driver/ToolChains/ROCm.h
Line
Count
Source (jump to first uncovered line)
1
//===--- ROCm.h - ROCm installation detector --------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
10
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
11
12
#include "clang/Basic/Cuda.h"
13
#include "clang/Basic/LLVM.h"
14
#include "clang/Driver/Driver.h"
15
#include "clang/Driver/Options.h"
16
#include "llvm/ADT/SmallString.h"
17
#include "llvm/ADT/StringMap.h"
18
#include "llvm/Option/ArgList.h"
19
#include "llvm/Support/VersionTuple.h"
20
#include "llvm/TargetParser/Triple.h"
21
22
namespace clang {
23
namespace driver {
24
25
/// ABI version of device library.
26
struct DeviceLibABIVersion {
27
  unsigned ABIVersion = 0;
28
0
  DeviceLibABIVersion(unsigned V) : ABIVersion(V) {}
29
0
  static DeviceLibABIVersion fromCodeObjectVersion(unsigned CodeObjectVersion) {
30
0
    if (CodeObjectVersion < 4)
31
0
      CodeObjectVersion = 4;
32
0
    return DeviceLibABIVersion(CodeObjectVersion * 100);
33
0
  }
34
  /// Whether ABI version bc file is requested.
35
  /// ABIVersion is code object version multiplied by 100. Code object v4
36
  /// and below works with ROCm 5.0 and below which does not have
37
  /// abi_version_*.bc. Code object v5 requires abi_version_500.bc.
38
0
  bool requiresLibrary() { return ABIVersion >= 500; }
39
0
  std::string toString() {
40
0
    assert(ABIVersion % 100 == 0 && "Not supported");
41
0
    return Twine(ABIVersion / 100).str();
42
0
  }
43
};
44
45
/// A class to find a viable ROCM installation
46
/// TODO: Generalize to handle libclc.
47
class RocmInstallationDetector {
48
private:
49
  struct ConditionalLibrary {
50
    SmallString<0> On;
51
    SmallString<0> Off;
52
53
0
    bool isValid() const { return !On.empty() && !Off.empty(); }
54
55
0
    StringRef get(bool Enabled) const {
56
0
      assert(isValid());
57
0
      return Enabled ? On : Off;
58
0
    }
59
  };
60
61
  // Installation path candidate.
62
  struct Candidate {
63
    llvm::SmallString<0> Path;
64
    bool StrictChecking;
65
    // Release string for ROCm packages built with SPACK if not empty. The
66
    // installation directories of ROCm packages built with SPACK follow the
67
    // convention <package_name>-<rocm_release_string>-<hash>.
68
    std::string SPACKReleaseStr;
69
70
0
    bool isSPACK() const { return !SPACKReleaseStr.empty(); }
71
    Candidate(std::string Path, bool StrictChecking = false,
72
              StringRef SPACKReleaseStr = {})
73
        : Path(Path), StrictChecking(StrictChecking),
74
0
          SPACKReleaseStr(SPACKReleaseStr.str()) {}
75
  };
76
77
  const Driver &D;
78
  bool HasHIPRuntime = false;
79
  bool HasDeviceLibrary = false;
80
  bool HasHIPStdParLibrary = false;
81
  bool HasRocThrustLibrary = false;
82
  bool HasRocPrimLibrary = false;
83
84
  // Default version if not detected or specified.
85
  const unsigned DefaultVersionMajor = 3;
86
  const unsigned DefaultVersionMinor = 5;
87
  const char *DefaultVersionPatch = "0";
88
89
  // The version string in Major.Minor.Patch format.
90
  std::string DetectedVersion;
91
  // Version containing major and minor.
92
  llvm::VersionTuple VersionMajorMinor;
93
  // Version containing patch.
94
  std::string VersionPatch;
95
96
  // ROCm path specified by --rocm-path.
97
  StringRef RocmPathArg;
98
  // ROCm device library paths specified by --rocm-device-lib-path.
99
  std::vector<std::string> RocmDeviceLibPathArg;
100
  // HIP runtime path specified by --hip-path.
101
  StringRef HIPPathArg;
102
  // HIP Standard Parallel Algorithm acceleration library specified by
103
  // --hipstdpar-path
104
  StringRef HIPStdParPathArg;
105
  // rocThrust algorithm library specified by --hipstdpar-thrust-path
106
  StringRef HIPRocThrustPathArg;
107
  // rocPrim algorithm library specified by --hipstdpar-prim-path
108
  StringRef HIPRocPrimPathArg;
109
  // HIP version specified by --hip-version.
110
  StringRef HIPVersionArg;
111
  // Wheter -nogpulib is specified.
112
  bool NoBuiltinLibs = false;
113
114
  // Paths
115
  SmallString<0> InstallPath;
116
  SmallString<0> BinPath;
117
  SmallString<0> LibPath;
118
  SmallString<0> LibDevicePath;
119
  SmallString<0> IncludePath;
120
  SmallString<0> SharePath;
121
  llvm::StringMap<std::string> LibDeviceMap;
122
123
  // Libraries that are always linked.
124
  SmallString<0> OCML;
125
  SmallString<0> OCKL;
126
127
  // Libraries that are always linked depending on the language
128
  SmallString<0> OpenCL;
129
  SmallString<0> HIP;
130
131
  // Asan runtime library
132
  SmallString<0> AsanRTL;
133
134
  // Libraries swapped based on compile flags.
135
  ConditionalLibrary WavefrontSize64;
136
  ConditionalLibrary FiniteOnly;
137
  ConditionalLibrary UnsafeMath;
138
  ConditionalLibrary DenormalsAreZero;
139
  ConditionalLibrary CorrectlyRoundedSqrt;
140
141
  // Maps ABI version to library path. The version number is in the format of
142
  // three digits as used in the ABI version library name.
143
  std::map<unsigned, std::string> ABIVersionMap;
144
145
  // Cache ROCm installation search paths.
146
  SmallVector<Candidate, 4> ROCmSearchDirs;
147
  bool PrintROCmSearchDirs;
148
  bool Verbose;
149
150
0
  bool allGenericLibsValid() const {
151
0
    return !OCML.empty() && !OCKL.empty() && !OpenCL.empty() && !HIP.empty() &&
152
0
           WavefrontSize64.isValid() && FiniteOnly.isValid() &&
153
0
           UnsafeMath.isValid() && DenormalsAreZero.isValid() &&
154
0
           CorrectlyRoundedSqrt.isValid();
155
0
  }
156
157
  void scanLibDevicePath(llvm::StringRef Path);
158
  bool parseHIPVersionFile(llvm::StringRef V);
159
  const SmallVectorImpl<Candidate> &getInstallationPathCandidates();
160
161
  /// Find the path to a SPACK package under the ROCm candidate installation
162
  /// directory if the candidate is a SPACK ROCm candidate. \returns empty
163
  /// string if the candidate is not SPACK ROCm candidate or the requested
164
  /// package is not found.
165
  llvm::SmallString<0> findSPACKPackage(const Candidate &Cand,
166
                                        StringRef PackageName);
167
168
public:
169
  RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
170
                           const llvm::opt::ArgList &Args,
171
                           bool DetectHIPRuntime = true,
172
                           bool DetectDeviceLib = false);
173
174
  /// Get file paths of default bitcode libraries common to AMDGPU based
175
  /// toolchains.
176
  llvm::SmallVector<std::string, 12>
177
  getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
178
                       StringRef LibDeviceFile, bool Wave64, bool DAZ,
179
                       bool FiniteOnly, bool UnsafeMathOpt,
180
                       bool FastRelaxedMath, bool CorrectSqrt,
181
                       DeviceLibABIVersion ABIVer, bool isOpenMP) const;
182
  /// Check file paths of default bitcode libraries common to AMDGPU based
183
  /// toolchains. \returns false if there are invalid or missing files.
184
  bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile,
185
                              DeviceLibABIVersion ABIVer) const;
186
187
  /// Check whether we detected a valid HIP runtime.
188
0
  bool hasHIPRuntime() const { return HasHIPRuntime; }
189
190
  /// Check whether we detected a valid ROCm device library.
191
0
  bool hasDeviceLibrary() const { return HasDeviceLibrary; }
192
193
  /// Check whether we detected a valid HIP STDPAR Acceleration library.
194
0
  bool hasHIPStdParLibrary() const { return HasHIPStdParLibrary; }
195
196
  /// Print information about the detected ROCm installation.
197
  void print(raw_ostream &OS) const;
198
199
  /// Get the detected Rocm install's version.
200
  // RocmVersion version() const { return Version; }
201
202
  /// Get the detected Rocm installation path.
203
0
  StringRef getInstallPath() const { return InstallPath; }
204
205
  /// Get the detected path to Rocm's bin directory.
206
  // StringRef getBinPath() const { return BinPath; }
207
208
  /// Get the detected Rocm Include path.
209
0
  StringRef getIncludePath() const { return IncludePath; }
210
211
  /// Get the detected Rocm library path.
212
0
  StringRef getLibPath() const { return LibPath; }
213
214
  /// Get the detected Rocm device library path.
215
0
  StringRef getLibDevicePath() const { return LibDevicePath; }
216
217
0
  StringRef getOCMLPath() const {
218
0
    assert(!OCML.empty());
219
0
    return OCML;
220
0
  }
221
222
0
  StringRef getOCKLPath() const {
223
0
    assert(!OCKL.empty());
224
0
    return OCKL;
225
0
  }
226
227
0
  StringRef getOpenCLPath() const {
228
0
    assert(!OpenCL.empty());
229
0
    return OpenCL;
230
0
  }
231
232
0
  StringRef getHIPPath() const {
233
0
    assert(!HIP.empty());
234
0
    return HIP;
235
0
  }
236
237
  /// Returns empty string of Asan runtime library is not available.
238
0
  StringRef getAsanRTLPath() const { return AsanRTL; }
239
240
0
  StringRef getWavefrontSize64Path(bool Enabled) const {
241
0
    return WavefrontSize64.get(Enabled);
242
0
  }
243
244
0
  StringRef getFiniteOnlyPath(bool Enabled) const {
245
0
    return FiniteOnly.get(Enabled);
246
0
  }
247
248
0
  StringRef getUnsafeMathPath(bool Enabled) const {
249
0
    return UnsafeMath.get(Enabled);
250
0
  }
251
252
0
  StringRef getDenormalsAreZeroPath(bool Enabled) const {
253
0
    return DenormalsAreZero.get(Enabled);
254
0
  }
255
256
0
  StringRef getCorrectlyRoundedSqrtPath(bool Enabled) const {
257
0
    return CorrectlyRoundedSqrt.get(Enabled);
258
0
  }
259
260
0
  StringRef getABIVersionPath(DeviceLibABIVersion ABIVer) const {
261
0
    auto Loc = ABIVersionMap.find(ABIVer.ABIVersion);
262
0
    if (Loc == ABIVersionMap.end())
263
0
      return StringRef();
264
0
    return Loc->second;
265
0
  }
266
267
  /// Get libdevice file for given architecture
268
0
  StringRef getLibDeviceFile(StringRef Gpu) const {
269
0
    auto Loc = LibDeviceMap.find(Gpu);
270
0
    if (Loc == LibDeviceMap.end())
271
0
      return "";
272
0
    return Loc->second;
273
0
  }
274
275
  void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
276
                         llvm::opt::ArgStringList &CC1Args) const;
277
278
  void detectDeviceLibrary();
279
  void detectHIPRuntime();
280
281
  /// Get the values for --rocm-device-lib-path arguments
282
0
  ArrayRef<std::string> getRocmDeviceLibPathArg() const {
283
0
    return RocmDeviceLibPathArg;
284
0
  }
285
286
  /// Get the value for --rocm-path argument
287
0
  StringRef getRocmPathArg() const { return RocmPathArg; }
288
289
  /// Get the value for --hip-version argument
290
0
  StringRef getHIPVersionArg() const { return HIPVersionArg; }
291
292
0
  StringRef getHIPVersion() const { return DetectedVersion; }
293
};
294
295
} // end namespace driver
296
} // end namespace clang
297
298
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H