Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/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
108
  DeviceLibABIVersion(unsigned V) : ABIVersion(V) {}
29
108
  static DeviceLibABIVersion fromCodeObjectVersion(unsigned CodeObjectVersion) {
30
108
    if (CodeObjectVersion < 4)
31
5
      CodeObjectVersion = 4;
32
108
    return DeviceLibABIVersion(CodeObjectVersion * 100);
33
108
  }
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
86
  bool requiresLibrary() { return ABIVersion >= 500; }
39
1
  std::string toString() {
40
1
    assert(ABIVersion % 100 == 0 && "Not supported");
41
1
    return Twine(ABIVersion / 100).str();
42
1
  }
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
950
    bool isValid() const { return !On.empty() && !Off.empty(); }
54
55
425
    StringRef get(bool Enabled) const {
56
425
      assert(isValid());
57
425
      return Enabled ? 
On166
:
Off259
;
58
425
    }
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
97.7k
    bool isSPACK() const { return !SPACKReleaseStr.empty(); }
71
    Candidate(std::string Path, bool StrictChecking = false,
72
              StringRef SPACKReleaseStr = {})
73
190k
        : Path(Path), StrictChecking(StrictChecking),
74
190k
          SPACKReleaseStr(SPACKReleaseStr.str()) {}
75
  };
76
77
  const Driver &D;
78
  bool HasHIPRuntime = false;
79
  bool HasDeviceLibrary = false;
80
81
  // Default version if not detected or specified.
82
  const unsigned DefaultVersionMajor = 3;
83
  const unsigned DefaultVersionMinor = 5;
84
  const char *DefaultVersionPatch = "0";
85
86
  // The version string in Major.Minor.Patch format.
87
  std::string DetectedVersion;
88
  // Version containing major and minor.
89
  llvm::VersionTuple VersionMajorMinor;
90
  // Version containing patch.
91
  std::string VersionPatch;
92
93
  // ROCm path specified by --rocm-path.
94
  StringRef RocmPathArg;
95
  // ROCm device library paths specified by --rocm-device-lib-path.
96
  std::vector<std::string> RocmDeviceLibPathArg;
97
  // HIP runtime path specified by --hip-path.
98
  StringRef HIPPathArg;
99
  // HIP version specified by --hip-version.
100
  StringRef HIPVersionArg;
101
  // Wheter -nogpulib is specified.
102
  bool NoBuiltinLibs = false;
103
104
  // Paths
105
  SmallString<0> InstallPath;
106
  SmallString<0> BinPath;
107
  SmallString<0> LibPath;
108
  SmallString<0> LibDevicePath;
109
  SmallString<0> IncludePath;
110
  SmallString<0> SharePath;
111
  llvm::StringMap<std::string> LibDeviceMap;
112
113
  // Libraries that are always linked.
114
  SmallString<0> OCML;
115
  SmallString<0> OCKL;
116
117
  // Libraries that are always linked depending on the language
118
  SmallString<0> OpenCL;
119
  SmallString<0> HIP;
120
121
  // Asan runtime library
122
  SmallString<0> AsanRTL;
123
124
  // Libraries swapped based on compile flags.
125
  ConditionalLibrary WavefrontSize64;
126
  ConditionalLibrary FiniteOnly;
127
  ConditionalLibrary UnsafeMath;
128
  ConditionalLibrary DenormalsAreZero;
129
  ConditionalLibrary CorrectlyRoundedSqrt;
130
131
  // Maps ABI version to library path. The version number is in the format of
132
  // three digits as used in the ABI version library name.
133
  std::map<unsigned, std::string> ABIVersionMap;
134
135
  // Cache ROCm installation search paths.
136
  SmallVector<Candidate, 4> ROCmSearchDirs;
137
  bool PrintROCmSearchDirs;
138
  bool Verbose;
139
140
122
  bool allGenericLibsValid() const {
141
122
    return !OCML.empty() && 
!OCKL.empty()105
&&
!OpenCL.empty()105
&&
!HIP.empty()105
&&
142
122
           
WavefrontSize64.isValid()105
&&
FiniteOnly.isValid()105
&&
143
122
           
UnsafeMath.isValid()105
&&
DenormalsAreZero.isValid()105
&&
144
122
           
CorrectlyRoundedSqrt.isValid()105
;
145
122
  }
146
147
  void scanLibDevicePath(llvm::StringRef Path);
148
  bool parseHIPVersionFile(llvm::StringRef V);
149
  const SmallVectorImpl<Candidate> &getInstallationPathCandidates();
150
151
  /// Find the path to a SPACK package under the ROCm candidate installation
152
  /// directory if the candidate is a SPACK ROCm candidate. \returns empty
153
  /// string if the candidate is not SPACK ROCm candidate or the requested
154
  /// package is not found.
155
  llvm::SmallString<0> findSPACKPackage(const Candidate &Cand,
156
                                        StringRef PackageName);
157
158
public:
159
  RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
160
                           const llvm::opt::ArgList &Args,
161
                           bool DetectHIPRuntime = true,
162
                           bool DetectDeviceLib = false);
163
164
  /// Get file paths of default bitcode libraries common to AMDGPU based
165
  /// toolchains.
166
  llvm::SmallVector<std::string, 12>
167
  getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
168
                       StringRef LibDeviceFile, bool Wave64, bool DAZ,
169
                       bool FiniteOnly, bool UnsafeMathOpt,
170
                       bool FastRelaxedMath, bool CorrectSqrt,
171
                       DeviceLibABIVersion ABIVer, bool isOpenMP) const;
172
  /// Check file paths of default bitcode libraries common to AMDGPU based
173
  /// toolchains. \returns false if there are invalid or missing files.
174
  bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile,
175
                              DeviceLibABIVersion ABIVer) const;
176
177
  /// Check whether we detected a valid HIP runtime.
178
272
  bool hasHIPRuntime() const { return HasHIPRuntime; }
179
180
  /// Check whether we detected a valid ROCm device library.
181
197
  bool hasDeviceLibrary() const { return HasDeviceLibrary; }
182
183
  /// Print information about the detected ROCm installation.
184
  void print(raw_ostream &OS) const;
185
186
  /// Get the detected Rocm install's version.
187
  // RocmVersion version() const { return Version; }
188
189
  /// Get the detected Rocm installation path.
190
0
  StringRef getInstallPath() const { return InstallPath; }
191
192
  /// Get the detected path to Rocm's bin directory.
193
  // StringRef getBinPath() const { return BinPath; }
194
195
  /// Get the detected Rocm Include path.
196
124
  StringRef getIncludePath() const { return IncludePath; }
197
198
  /// Get the detected Rocm library path.
199
161
  StringRef getLibPath() const { return LibPath; }
200
201
  /// Get the detected Rocm device library path.
202
0
  StringRef getLibDevicePath() const { return LibDevicePath; }
203
204
85
  StringRef getOCMLPath() const {
205
85
    assert(!OCML.empty());
206
85
    return OCML;
207
85
  }
208
209
85
  StringRef getOCKLPath() const {
210
85
    assert(!OCKL.empty());
211
85
    return OCKL;
212
85
  }
213
214
17
  StringRef getOpenCLPath() const {
215
17
    assert(!OpenCL.empty());
216
17
    return OpenCL;
217
17
  }
218
219
87
  StringRef getHIPPath() const {
220
87
    assert(!HIP.empty());
221
87
    return HIP;
222
87
  }
223
224
  /// Returns empty string of Asan runtime library is not available.
225
6
  StringRef getAsanRTLPath() const { return AsanRTL; }
226
227
85
  StringRef getWavefrontSize64Path(bool Enabled) const {
228
85
    return WavefrontSize64.get(Enabled);
229
85
  }
230
231
85
  StringRef getFiniteOnlyPath(bool Enabled) const {
232
85
    return FiniteOnly.get(Enabled);
233
85
  }
234
235
85
  StringRef getUnsafeMathPath(bool Enabled) const {
236
85
    return UnsafeMath.get(Enabled);
237
85
  }
238
239
85
  StringRef getDenormalsAreZeroPath(bool Enabled) const {
240
85
    return DenormalsAreZero.get(Enabled);
241
85
  }
242
243
85
  StringRef getCorrectlyRoundedSqrtPath(bool Enabled) const {
244
85
    return CorrectlyRoundedSqrt.get(Enabled);
245
85
  }
246
247
87
  StringRef getABIVersionPath(DeviceLibABIVersion ABIVer) const {
248
87
    auto Loc = ABIVersionMap.find(ABIVer.ABIVersion);
249
87
    if (Loc == ABIVersionMap.end())
250
3
      return StringRef();
251
84
    return Loc->second;
252
87
  }
253
254
  /// Get libdevice file for given architecture
255
108
  StringRef getLibDeviceFile(StringRef Gpu) const {
256
108
    auto Loc = LibDeviceMap.find(Gpu);
257
108
    if (Loc == LibDeviceMap.end())
258
22
      return "";
259
86
    return Loc->second;
260
108
  }
261
262
  void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
263
                         llvm::opt::ArgStringList &CC1Args) const;
264
265
  void detectDeviceLibrary();
266
  void detectHIPRuntime();
267
268
  /// Get the values for --rocm-device-lib-path arguments
269
123
  ArrayRef<std::string> getRocmDeviceLibPathArg() const {
270
123
    return RocmDeviceLibPathArg;
271
123
  }
272
273
  /// Get the value for --rocm-path argument
274
0
  StringRef getRocmPathArg() const { return RocmPathArg; }
275
276
  /// Get the value for --hip-version argument
277
0
  StringRef getHIPVersionArg() const { return HIPVersionArg; }
278
279
0
  StringRef getHIPVersion() const { return DetectedVersion; }
280
};
281
282
} // end namespace driver
283
} // end namespace clang
284
285
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H