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