1 #include "clang/Basic/Cuda.h"
2
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"
8
9 namespace clang {
10
CudaVersionToString(CudaVersion V)11 const char *CudaVersionToString(CudaVersion V) {
12 switch (V) {
13 case CudaVersion::UNKNOWN:
14 return "unknown";
15 case CudaVersion::CUDA_70:
16 return "7.0";
17 case CudaVersion::CUDA_75:
18 return "7.5";
19 case CudaVersion::CUDA_80:
20 return "8.0";
21 case CudaVersion::CUDA_90:
22 return "9.0";
23 case CudaVersion::CUDA_91:
24 return "9.1";
25 case CudaVersion::CUDA_92:
26 return "9.2";
27 case CudaVersion::CUDA_100:
28 return "10.0";
29 case CudaVersion::CUDA_101:
30 return "10.1";
31 }
32 llvm_unreachable("invalid enum");
33 }
34
CudaStringToVersion(const llvm::Twine & S)35 CudaVersion CudaStringToVersion(const llvm::Twine &S) {
36 return llvm::StringSwitch<CudaVersion>(S.str())
37 .Case("7.0", CudaVersion::CUDA_70)
38 .Case("7.5", CudaVersion::CUDA_75)
39 .Case("8.0", CudaVersion::CUDA_80)
40 .Case("9.0", CudaVersion::CUDA_90)
41 .Case("9.1", CudaVersion::CUDA_91)
42 .Case("9.2", CudaVersion::CUDA_92)
43 .Case("10.0", CudaVersion::CUDA_100)
44 .Case("10.1", CudaVersion::CUDA_101)
45 .Default(CudaVersion::UNKNOWN);
46 }
47
CudaArchToString(CudaArch A)48 const char *CudaArchToString(CudaArch A) {
49 switch (A) {
50 case CudaArch::LAST:
51 break;
52 case CudaArch::UNKNOWN:
53 return "unknown";
54 case CudaArch::SM_20:
55 return "sm_20";
56 case CudaArch::SM_21:
57 return "sm_21";
58 case CudaArch::SM_30:
59 return "sm_30";
60 case CudaArch::SM_32:
61 return "sm_32";
62 case CudaArch::SM_35:
63 return "sm_35";
64 case CudaArch::SM_37:
65 return "sm_37";
66 case CudaArch::SM_50:
67 return "sm_50";
68 case CudaArch::SM_52:
69 return "sm_52";
70 case CudaArch::SM_53:
71 return "sm_53";
72 case CudaArch::SM_60:
73 return "sm_60";
74 case CudaArch::SM_61:
75 return "sm_61";
76 case CudaArch::SM_62:
77 return "sm_62";
78 case CudaArch::SM_70:
79 return "sm_70";
80 case CudaArch::SM_72:
81 return "sm_72";
82 case CudaArch::SM_75:
83 return "sm_75";
84 case CudaArch::GFX600: // tahiti
85 return "gfx600";
86 case CudaArch::GFX601: // pitcairn, verde, oland,hainan
87 return "gfx601";
88 case CudaArch::GFX700: // kaveri
89 return "gfx700";
90 case CudaArch::GFX701: // hawaii
91 return "gfx701";
92 case CudaArch::GFX702: // 290,290x,R390,R390x
93 return "gfx702";
94 case CudaArch::GFX703: // kabini mullins
95 return "gfx703";
96 case CudaArch::GFX704: // bonaire
97 return "gfx704";
98 case CudaArch::GFX801: // carrizo
99 return "gfx801";
100 case CudaArch::GFX802: // tonga,iceland
101 return "gfx802";
102 case CudaArch::GFX803: // fiji,polaris10
103 return "gfx803";
104 case CudaArch::GFX810: // stoney
105 return "gfx810";
106 case CudaArch::GFX900: // vega, instinct
107 return "gfx900";
108 case CudaArch::GFX902: // TBA
109 return "gfx902";
110 case CudaArch::GFX904: // TBA
111 return "gfx904";
112 case CudaArch::GFX906: // TBA
113 return "gfx906";
114 case CudaArch::GFX908: // TBA
115 return "gfx908";
116 case CudaArch::GFX909: // TBA
117 return "gfx909";
118 case CudaArch::GFX1010: // TBA
119 return "gfx1010";
120 case CudaArch::GFX1011: // TBA
121 return "gfx1011";
122 case CudaArch::GFX1012: // TBA
123 return "gfx1012";
124 }
125 llvm_unreachable("invalid enum");
126 }
127
StringToCudaArch(llvm::StringRef S)128 CudaArch StringToCudaArch(llvm::StringRef S) {
129 return llvm::StringSwitch<CudaArch>(S)
130 .Case("sm_20", CudaArch::SM_20)
131 .Case("sm_21", CudaArch::SM_21)
132 .Case("sm_30", CudaArch::SM_30)
133 .Case("sm_32", CudaArch::SM_32)
134 .Case("sm_35", CudaArch::SM_35)
135 .Case("sm_37", CudaArch::SM_37)
136 .Case("sm_50", CudaArch::SM_50)
137 .Case("sm_52", CudaArch::SM_52)
138 .Case("sm_53", CudaArch::SM_53)
139 .Case("sm_60", CudaArch::SM_60)
140 .Case("sm_61", CudaArch::SM_61)
141 .Case("sm_62", CudaArch::SM_62)
142 .Case("sm_70", CudaArch::SM_70)
143 .Case("sm_72", CudaArch::SM_72)
144 .Case("sm_75", CudaArch::SM_75)
145 .Case("gfx600", CudaArch::GFX600)
146 .Case("gfx601", CudaArch::GFX601)
147 .Case("gfx700", CudaArch::GFX700)
148 .Case("gfx701", CudaArch::GFX701)
149 .Case("gfx702", CudaArch::GFX702)
150 .Case("gfx703", CudaArch::GFX703)
151 .Case("gfx704", CudaArch::GFX704)
152 .Case("gfx801", CudaArch::GFX801)
153 .Case("gfx802", CudaArch::GFX802)
154 .Case("gfx803", CudaArch::GFX803)
155 .Case("gfx810", CudaArch::GFX810)
156 .Case("gfx900", CudaArch::GFX900)
157 .Case("gfx902", CudaArch::GFX902)
158 .Case("gfx904", CudaArch::GFX904)
159 .Case("gfx906", CudaArch::GFX906)
160 .Case("gfx908", CudaArch::GFX908)
161 .Case("gfx909", CudaArch::GFX909)
162 .Case("gfx1010", CudaArch::GFX1010)
163 .Case("gfx1011", CudaArch::GFX1011)
164 .Case("gfx1012", CudaArch::GFX1012)
165 .Default(CudaArch::UNKNOWN);
166 }
167
CudaVirtualArchToString(CudaVirtualArch A)168 const char *CudaVirtualArchToString(CudaVirtualArch A) {
169 switch (A) {
170 case CudaVirtualArch::UNKNOWN:
171 return "unknown";
172 case CudaVirtualArch::COMPUTE_20:
173 return "compute_20";
174 case CudaVirtualArch::COMPUTE_30:
175 return "compute_30";
176 case CudaVirtualArch::COMPUTE_32:
177 return "compute_32";
178 case CudaVirtualArch::COMPUTE_35:
179 return "compute_35";
180 case CudaVirtualArch::COMPUTE_37:
181 return "compute_37";
182 case CudaVirtualArch::COMPUTE_50:
183 return "compute_50";
184 case CudaVirtualArch::COMPUTE_52:
185 return "compute_52";
186 case CudaVirtualArch::COMPUTE_53:
187 return "compute_53";
188 case CudaVirtualArch::COMPUTE_60:
189 return "compute_60";
190 case CudaVirtualArch::COMPUTE_61:
191 return "compute_61";
192 case CudaVirtualArch::COMPUTE_62:
193 return "compute_62";
194 case CudaVirtualArch::COMPUTE_70:
195 return "compute_70";
196 case CudaVirtualArch::COMPUTE_72:
197 return "compute_72";
198 case CudaVirtualArch::COMPUTE_75:
199 return "compute_75";
200 case CudaVirtualArch::COMPUTE_AMDGCN:
201 return "compute_amdgcn";
202 }
203 llvm_unreachable("invalid enum");
204 }
205
StringToCudaVirtualArch(llvm::StringRef S)206 CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S) {
207 return llvm::StringSwitch<CudaVirtualArch>(S)
208 .Case("compute_20", CudaVirtualArch::COMPUTE_20)
209 .Case("compute_30", CudaVirtualArch::COMPUTE_30)
210 .Case("compute_32", CudaVirtualArch::COMPUTE_32)
211 .Case("compute_35", CudaVirtualArch::COMPUTE_35)
212 .Case("compute_37", CudaVirtualArch::COMPUTE_37)
213 .Case("compute_50", CudaVirtualArch::COMPUTE_50)
214 .Case("compute_52", CudaVirtualArch::COMPUTE_52)
215 .Case("compute_53", CudaVirtualArch::COMPUTE_53)
216 .Case("compute_60", CudaVirtualArch::COMPUTE_60)
217 .Case("compute_61", CudaVirtualArch::COMPUTE_61)
218 .Case("compute_62", CudaVirtualArch::COMPUTE_62)
219 .Case("compute_70", CudaVirtualArch::COMPUTE_70)
220 .Case("compute_72", CudaVirtualArch::COMPUTE_72)
221 .Case("compute_75", CudaVirtualArch::COMPUTE_75)
222 .Case("compute_amdgcn", CudaVirtualArch::COMPUTE_AMDGCN)
223 .Default(CudaVirtualArch::UNKNOWN);
224 }
225
VirtualArchForCudaArch(CudaArch A)226 CudaVirtualArch VirtualArchForCudaArch(CudaArch A) {
227 switch (A) {
228 case CudaArch::LAST:
229 break;
230 case CudaArch::UNKNOWN:
231 return CudaVirtualArch::UNKNOWN;
232 case CudaArch::SM_20:
233 case CudaArch::SM_21:
234 return CudaVirtualArch::COMPUTE_20;
235 case CudaArch::SM_30:
236 return CudaVirtualArch::COMPUTE_30;
237 case CudaArch::SM_32:
238 return CudaVirtualArch::COMPUTE_32;
239 case CudaArch::SM_35:
240 return CudaVirtualArch::COMPUTE_35;
241 case CudaArch::SM_37:
242 return CudaVirtualArch::COMPUTE_37;
243 case CudaArch::SM_50:
244 return CudaVirtualArch::COMPUTE_50;
245 case CudaArch::SM_52:
246 return CudaVirtualArch::COMPUTE_52;
247 case CudaArch::SM_53:
248 return CudaVirtualArch::COMPUTE_53;
249 case CudaArch::SM_60:
250 return CudaVirtualArch::COMPUTE_60;
251 case CudaArch::SM_61:
252 return CudaVirtualArch::COMPUTE_61;
253 case CudaArch::SM_62:
254 return CudaVirtualArch::COMPUTE_62;
255 case CudaArch::SM_70:
256 return CudaVirtualArch::COMPUTE_70;
257 case CudaArch::SM_72:
258 return CudaVirtualArch::COMPUTE_72;
259 case CudaArch::SM_75:
260 return CudaVirtualArch::COMPUTE_75;
261 case CudaArch::GFX600:
262 case CudaArch::GFX601:
263 case CudaArch::GFX700:
264 case CudaArch::GFX701:
265 case CudaArch::GFX702:
266 case CudaArch::GFX703:
267 case CudaArch::GFX704:
268 case CudaArch::GFX801:
269 case CudaArch::GFX802:
270 case CudaArch::GFX803:
271 case CudaArch::GFX810:
272 case CudaArch::GFX900:
273 case CudaArch::GFX902:
274 case CudaArch::GFX904:
275 case CudaArch::GFX906:
276 case CudaArch::GFX908:
277 case CudaArch::GFX909:
278 case CudaArch::GFX1010:
279 case CudaArch::GFX1011:
280 case CudaArch::GFX1012:
281 return CudaVirtualArch::COMPUTE_AMDGCN;
282 }
283 llvm_unreachable("invalid enum");
284 }
285
MinVersionForCudaArch(CudaArch A)286 CudaVersion MinVersionForCudaArch(CudaArch A) {
287 switch (A) {
288 case CudaArch::LAST:
289 break;
290 case CudaArch::UNKNOWN:
291 return CudaVersion::UNKNOWN;
292 case CudaArch::SM_20:
293 case CudaArch::SM_21:
294 case CudaArch::SM_30:
295 case CudaArch::SM_32:
296 case CudaArch::SM_35:
297 case CudaArch::SM_37:
298 case CudaArch::SM_50:
299 case CudaArch::SM_52:
300 case CudaArch::SM_53:
301 return CudaVersion::CUDA_70;
302 case CudaArch::SM_60:
303 case CudaArch::SM_61:
304 case CudaArch::SM_62:
305 return CudaVersion::CUDA_80;
306 case CudaArch::SM_70:
307 return CudaVersion::CUDA_90;
308 case CudaArch::SM_72:
309 return CudaVersion::CUDA_91;
310 case CudaArch::SM_75:
311 return CudaVersion::CUDA_100;
312 case CudaArch::GFX600:
313 case CudaArch::GFX601:
314 case CudaArch::GFX700:
315 case CudaArch::GFX701:
316 case CudaArch::GFX702:
317 case CudaArch::GFX703:
318 case CudaArch::GFX704:
319 case CudaArch::GFX801:
320 case CudaArch::GFX802:
321 case CudaArch::GFX803:
322 case CudaArch::GFX810:
323 case CudaArch::GFX900:
324 case CudaArch::GFX902:
325 case CudaArch::GFX904:
326 case CudaArch::GFX906:
327 case CudaArch::GFX908:
328 case CudaArch::GFX909:
329 case CudaArch::GFX1010:
330 case CudaArch::GFX1011:
331 case CudaArch::GFX1012:
332 return CudaVersion::CUDA_70;
333 }
334 llvm_unreachable("invalid enum");
335 }
336
MaxVersionForCudaArch(CudaArch A)337 CudaVersion MaxVersionForCudaArch(CudaArch A) {
338 switch (A) {
339 case CudaArch::UNKNOWN:
340 return CudaVersion::UNKNOWN;
341 case CudaArch::SM_20:
342 case CudaArch::SM_21:
343 case CudaArch::GFX600:
344 case CudaArch::GFX601:
345 case CudaArch::GFX700:
346 case CudaArch::GFX701:
347 case CudaArch::GFX702:
348 case CudaArch::GFX703:
349 case CudaArch::GFX704:
350 case CudaArch::GFX801:
351 case CudaArch::GFX802:
352 case CudaArch::GFX803:
353 case CudaArch::GFX810:
354 case CudaArch::GFX900:
355 case CudaArch::GFX902:
356 case CudaArch::GFX1010:
357 case CudaArch::GFX1011:
358 case CudaArch::GFX1012:
359 return CudaVersion::CUDA_80;
360 default:
361 return CudaVersion::LATEST;
362 }
363 }
364
ToCudaVersion(llvm::VersionTuple Version)365 static CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
366 int IVer =
367 Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
368 switch(IVer) {
369 case 70:
370 return CudaVersion::CUDA_70;
371 case 75:
372 return CudaVersion::CUDA_75;
373 case 80:
374 return CudaVersion::CUDA_80;
375 case 90:
376 return CudaVersion::CUDA_90;
377 case 91:
378 return CudaVersion::CUDA_91;
379 case 92:
380 return CudaVersion::CUDA_92;
381 case 100:
382 return CudaVersion::CUDA_100;
383 case 101:
384 return CudaVersion::CUDA_101;
385 default:
386 return CudaVersion::UNKNOWN;
387 }
388 }
389
CudaFeatureEnabled(llvm::VersionTuple Version,CudaFeature Feature)390 bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
391 return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
392 }
393
CudaFeatureEnabled(CudaVersion Version,CudaFeature Feature)394 bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
395 switch (Feature) {
396 case CudaFeature::CUDA_USES_NEW_LAUNCH:
397 return Version >= CudaVersion::CUDA_92;
398 case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
399 return Version >= CudaVersion::CUDA_101;
400 }
401 llvm_unreachable("Unknown CUDA feature.");
402 }
403 } // namespace clang
404