1 //===--- ROCm.h - ROCm installation detector --------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
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"
25 /// ABI version of device library.
26 struct DeviceLibABIVersion
{
27 unsigned ABIVersion
= 0;
28 DeviceLibABIVersion(unsigned V
) : ABIVersion(V
) {}
29 static DeviceLibABIVersion
fromCodeObjectVersion(unsigned CodeObjectVersion
) {
30 if (CodeObjectVersion
< 4)
31 CodeObjectVersion
= 4;
32 return DeviceLibABIVersion(CodeObjectVersion
* 100);
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 bool requiresLibrary() { return ABIVersion
>= 500; }
39 std::string
toString() {
40 assert(ABIVersion
% 100 == 0 && "Not supported");
41 return Twine(ABIVersion
/ 100).str();
45 /// A class to find a viable ROCM installation
46 /// TODO: Generalize to handle libclc.
47 class RocmInstallationDetector
{
49 struct ConditionalLibrary
{
53 bool isValid() const { return !On
.empty() && !Off
.empty(); }
55 StringRef
get(bool Enabled
) const {
57 return Enabled
? On
: Off
;
61 // Installation path candidate.
63 llvm::SmallString
<0> Path
;
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
;
70 bool isSPACK() const { return !SPACKReleaseStr
.empty(); }
71 Candidate(std::string Path
, bool StrictChecking
= false,
72 StringRef SPACKReleaseStr
= {})
73 : Path(Path
), StrictChecking(StrictChecking
),
74 SPACKReleaseStr(SPACKReleaseStr
.str()) {}
78 bool HasHIPRuntime
= false;
79 bool HasDeviceLibrary
= false;
80 bool HasHIPStdParLibrary
= false;
81 bool HasRocThrustLibrary
= false;
82 bool HasRocPrimLibrary
= false;
84 // Default version if not detected or specified.
85 const unsigned DefaultVersionMajor
= 3;
86 const unsigned DefaultVersionMinor
= 5;
87 const char *DefaultVersionPatch
= "0";
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
;
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
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;
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
;
123 // Libraries that are always linked.
127 // Libraries that are always linked depending on the language
128 SmallString
<0> OpenCL
;
131 // Asan runtime library
132 SmallString
<0> AsanRTL
;
134 // Libraries swapped based on compile flags.
135 ConditionalLibrary WavefrontSize64
;
136 ConditionalLibrary FiniteOnly
;
137 ConditionalLibrary UnsafeMath
;
138 ConditionalLibrary DenormalsAreZero
;
139 ConditionalLibrary CorrectlyRoundedSqrt
;
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
;
145 // Cache ROCm installation search paths.
146 SmallVector
<Candidate
, 4> ROCmSearchDirs
;
147 bool PrintROCmSearchDirs
;
150 bool allGenericLibsValid() const {
151 return !OCML
.empty() && !OCKL
.empty() && !OpenCL
.empty() && !HIP
.empty() &&
152 WavefrontSize64
.isValid() && FiniteOnly
.isValid() &&
153 UnsafeMath
.isValid() && DenormalsAreZero
.isValid() &&
154 CorrectlyRoundedSqrt
.isValid();
157 void scanLibDevicePath(llvm::StringRef Path
);
158 bool parseHIPVersionFile(llvm::StringRef V
);
159 const SmallVectorImpl
<Candidate
> &getInstallationPathCandidates();
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
);
169 RocmInstallationDetector(const Driver
&D
, const llvm::Triple
&HostTriple
,
170 const llvm::opt::ArgList
&Args
,
171 bool DetectHIPRuntime
= true,
172 bool DetectDeviceLib
= false);
174 /// Get file paths of default bitcode libraries common to AMDGPU based
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;
187 /// Check whether we detected a valid HIP runtime.
188 bool hasHIPRuntime() const { return HasHIPRuntime
; }
190 /// Check whether we detected a valid ROCm device library.
191 bool hasDeviceLibrary() const { return HasDeviceLibrary
; }
193 /// Check whether we detected a valid HIP STDPAR Acceleration library.
194 bool hasHIPStdParLibrary() const { return HasHIPStdParLibrary
; }
196 /// Print information about the detected ROCm installation.
197 void print(raw_ostream
&OS
) const;
199 /// Get the detected Rocm install's version.
200 // RocmVersion version() const { return Version; }
202 /// Get the detected Rocm installation path.
203 StringRef
getInstallPath() const { return InstallPath
; }
205 /// Get the detected path to Rocm's bin directory.
206 // StringRef getBinPath() const { return BinPath; }
208 /// Get the detected Rocm Include path.
209 StringRef
getIncludePath() const { return IncludePath
; }
211 /// Get the detected Rocm library path.
212 StringRef
getLibPath() const { return LibPath
; }
214 /// Get the detected Rocm device library path.
215 StringRef
getLibDevicePath() const { return LibDevicePath
; }
217 StringRef
getOCMLPath() const {
218 assert(!OCML
.empty());
222 StringRef
getOCKLPath() const {
223 assert(!OCKL
.empty());
227 StringRef
getOpenCLPath() const {
228 assert(!OpenCL
.empty());
232 StringRef
getHIPPath() const {
233 assert(!HIP
.empty());
237 /// Returns empty string of Asan runtime library is not available.
238 StringRef
getAsanRTLPath() const { return AsanRTL
; }
240 StringRef
getWavefrontSize64Path(bool Enabled
) const {
241 return WavefrontSize64
.get(Enabled
);
244 StringRef
getFiniteOnlyPath(bool Enabled
) const {
245 return FiniteOnly
.get(Enabled
);
248 StringRef
getUnsafeMathPath(bool Enabled
) const {
249 return UnsafeMath
.get(Enabled
);
252 StringRef
getDenormalsAreZeroPath(bool Enabled
) const {
253 return DenormalsAreZero
.get(Enabled
);
256 StringRef
getCorrectlyRoundedSqrtPath(bool Enabled
) const {
257 return CorrectlyRoundedSqrt
.get(Enabled
);
260 StringRef
getABIVersionPath(DeviceLibABIVersion ABIVer
) const {
261 auto Loc
= ABIVersionMap
.find(ABIVer
.ABIVersion
);
262 if (Loc
== ABIVersionMap
.end())
267 /// Get libdevice file for given architecture
268 StringRef
getLibDeviceFile(StringRef Gpu
) const {
269 auto Loc
= LibDeviceMap
.find(Gpu
);
270 if (Loc
== LibDeviceMap
.end())
275 void AddHIPIncludeArgs(const llvm::opt::ArgList
&DriverArgs
,
276 llvm::opt::ArgStringList
&CC1Args
) const;
278 void detectDeviceLibrary();
279 void detectHIPRuntime();
281 /// Get the values for --rocm-device-lib-path arguments
282 ArrayRef
<std::string
> getRocmDeviceLibPathArg() const {
283 return RocmDeviceLibPathArg
;
286 /// Get the value for --rocm-path argument
287 StringRef
getRocmPathArg() const { return RocmPathArg
; }
289 /// Get the value for --hip-version argument
290 StringRef
getHIPVersionArg() const { return HIPVersionArg
; }
292 StringRef
getHIPVersion() const { return DetectedVersion
; }
295 } // end namespace driver
296 } // end namespace clang
298 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H