1 #include "clang/Basic/Cuda.h"
3 #include "llvm/ADT/StringRef.h"
4 #include "llvm/ADT/StringSwitch.h"
5 #include "llvm/ADT/Twine.h"
6 #include "llvm/Support/ErrorHandling.h"
7 #include "llvm/Support/VersionTuple.h"
11 const char *CudaVersionToString(CudaVersion V
) {
13 case CudaVersion::UNKNOWN
:
15 case CudaVersion::CUDA_70
:
17 case CudaVersion::CUDA_75
:
19 case CudaVersion::CUDA_80
:
21 case CudaVersion::CUDA_90
:
23 case CudaVersion::CUDA_91
:
25 case CudaVersion::CUDA_92
:
27 case CudaVersion::CUDA_100
:
29 case CudaVersion::CUDA_101
:
31 case CudaVersion::CUDA_102
:
33 case CudaVersion::CUDA_110
:
35 case CudaVersion::CUDA_111
:
37 case CudaVersion::CUDA_112
:
39 case CudaVersion::CUDA_113
:
41 case CudaVersion::CUDA_114
:
43 case CudaVersion::CUDA_115
:
45 case CudaVersion::NEW
:
48 llvm_unreachable("invalid enum");
51 CudaVersion
CudaStringToVersion(const llvm::Twine
&S
) {
52 return llvm::StringSwitch
<CudaVersion
>(S
.str())
53 .Case("7.0", CudaVersion::CUDA_70
)
54 .Case("7.5", CudaVersion::CUDA_75
)
55 .Case("8.0", CudaVersion::CUDA_80
)
56 .Case("9.0", CudaVersion::CUDA_90
)
57 .Case("9.1", CudaVersion::CUDA_91
)
58 .Case("9.2", CudaVersion::CUDA_92
)
59 .Case("10.0", CudaVersion::CUDA_100
)
60 .Case("10.1", CudaVersion::CUDA_101
)
61 .Case("10.2", CudaVersion::CUDA_102
)
62 .Case("11.0", CudaVersion::CUDA_110
)
63 .Case("11.1", CudaVersion::CUDA_111
)
64 .Case("11.2", CudaVersion::CUDA_112
)
65 .Case("11.3", CudaVersion::CUDA_113
)
66 .Case("11.4", CudaVersion::CUDA_114
)
67 .Case("11.5", CudaVersion::CUDA_115
)
68 .Default(CudaVersion::UNKNOWN
);
72 struct CudaArchToStringMap
{
74 const char *arch_name
;
75 const char *virtual_arch_name
;
80 { CudaArch::SM_##sm, "sm_" #sm, ca }
81 #define SM(sm) SM2(sm, "compute_" #sm)
83 { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
84 static const CudaArchToStringMap arch_names
[] = {
86 {CudaArch::UNUSED
, "", ""},
87 SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
88 SM(30), SM(32), SM(35), SM(37), // Kepler
89 SM(50), SM(52), SM(53), // Maxwell
90 SM(60), SM(61), SM(62), // Pascal
91 SM(70), SM(72), // Volta
93 SM(80), SM(86), // Ampere
117 GFX(1010), // gfx1010
118 GFX(1011), // gfx1011
119 GFX(1012), // gfx1012
120 GFX(1013), // gfx1013
121 GFX(1030), // gfx1030
122 GFX(1031), // gfx1031
123 GFX(1032), // gfx1032
124 GFX(1033), // gfx1033
125 GFX(1034), // gfx1034
126 GFX(1035), // gfx1035
127 GFX(1036), // gfx1036
128 {CudaArch::Generic
, "generic", ""},
135 const char *CudaArchToString(CudaArch A
) {
136 auto result
= std::find_if(
137 std::begin(arch_names
), std::end(arch_names
),
138 [A
](const CudaArchToStringMap
&map
) { return A
== map
.arch
; });
139 if (result
== std::end(arch_names
))
141 return result
->arch_name
;
144 const char *CudaArchToVirtualArchString(CudaArch A
) {
145 auto result
= std::find_if(
146 std::begin(arch_names
), std::end(arch_names
),
147 [A
](const CudaArchToStringMap
&map
) { return A
== map
.arch
; });
148 if (result
== std::end(arch_names
))
150 return result
->virtual_arch_name
;
153 CudaArch
StringToCudaArch(llvm::StringRef S
) {
154 auto result
= std::find_if(
155 std::begin(arch_names
), std::end(arch_names
),
156 [S
](const CudaArchToStringMap
&map
) { return S
== map
.arch_name
; });
157 if (result
== std::end(arch_names
))
158 return CudaArch::UNKNOWN
;
162 CudaVersion
MinVersionForCudaArch(CudaArch A
) {
163 if (A
== CudaArch::UNKNOWN
)
164 return CudaVersion::UNKNOWN
;
166 // AMD GPUs do not depend on CUDA versions.
168 return CudaVersion::CUDA_70
;
171 case CudaArch::SM_20
:
172 case CudaArch::SM_21
:
173 case CudaArch::SM_30
:
174 case CudaArch::SM_32
:
175 case CudaArch::SM_35
:
176 case CudaArch::SM_37
:
177 case CudaArch::SM_50
:
178 case CudaArch::SM_52
:
179 case CudaArch::SM_53
:
180 return CudaVersion::CUDA_70
;
181 case CudaArch::SM_60
:
182 case CudaArch::SM_61
:
183 case CudaArch::SM_62
:
184 return CudaVersion::CUDA_80
;
185 case CudaArch::SM_70
:
186 return CudaVersion::CUDA_90
;
187 case CudaArch::SM_72
:
188 return CudaVersion::CUDA_91
;
189 case CudaArch::SM_75
:
190 return CudaVersion::CUDA_100
;
191 case CudaArch::SM_80
:
192 return CudaVersion::CUDA_110
;
193 case CudaArch::SM_86
:
194 return CudaVersion::CUDA_111
;
196 llvm_unreachable("invalid enum");
200 CudaVersion
MaxVersionForCudaArch(CudaArch A
) {
201 // AMD GPUs do not depend on CUDA versions.
203 return CudaVersion::NEW
;
206 case CudaArch::UNKNOWN
:
207 return CudaVersion::UNKNOWN
;
208 case CudaArch::SM_20
:
209 case CudaArch::SM_21
:
210 return CudaVersion::CUDA_80
;
211 case CudaArch::SM_30
:
212 return CudaVersion::CUDA_110
;
214 return CudaVersion::NEW
;
218 CudaVersion
ToCudaVersion(llvm::VersionTuple Version
) {
220 Version
.getMajor() * 10 + Version
.getMinor().getValueOr(0);
223 return CudaVersion::CUDA_70
;
225 return CudaVersion::CUDA_75
;
227 return CudaVersion::CUDA_80
;
229 return CudaVersion::CUDA_90
;
231 return CudaVersion::CUDA_91
;
233 return CudaVersion::CUDA_92
;
235 return CudaVersion::CUDA_100
;
237 return CudaVersion::CUDA_101
;
239 return CudaVersion::CUDA_102
;
241 return CudaVersion::CUDA_110
;
243 return CudaVersion::CUDA_111
;
245 return CudaVersion::CUDA_112
;
247 return CudaVersion::CUDA_113
;
249 return CudaVersion::CUDA_114
;
251 return CudaVersion::CUDA_115
;
253 return CudaVersion::UNKNOWN
;
257 bool CudaFeatureEnabled(llvm::VersionTuple Version
, CudaFeature Feature
) {
258 return CudaFeatureEnabled(ToCudaVersion(Version
), Feature
);
261 bool CudaFeatureEnabled(CudaVersion Version
, CudaFeature Feature
) {
263 case CudaFeature::CUDA_USES_NEW_LAUNCH
:
264 return Version
>= CudaVersion::CUDA_92
;
265 case CudaFeature::CUDA_USES_FATBIN_REGISTER_END
:
266 return Version
>= CudaVersion::CUDA_101
;
268 llvm_unreachable("Unknown CUDA feature.");