Clang Project

clang_source_code/lib/Basic/Cuda.cpp
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
8namespace clang {
9
10const 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
34CudaVersion 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
46const 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// tahiti
83    return "gfx600";
84  case CudaArch::GFX601// pitcairn, verde, oland,hainan
85    return "gfx601";
86  case CudaArch::GFX700// kaveri
87    return "gfx700";
88  case CudaArch::GFX701// hawaii
89    return "gfx701";
90  case CudaArch::GFX702// 290,290x,R390,R390x
91    return "gfx702";
92  case CudaArch::GFX703// kabini mullins
93    return "gfx703";
94  case CudaArch::GFX704// bonaire
95    return "gfx704";
96  case CudaArch::GFX801// carrizo
97    return "gfx801";
98  case CudaArch::GFX802// tonga,iceland
99    return "gfx802";
100  case CudaArch::GFX803// fiji,polaris10
101    return "gfx803";
102  case CudaArch::GFX810// stoney
103    return "gfx810";
104  case CudaArch::GFX900// vega, instinct
105    return "gfx900";
106  case CudaArch::GFX902// TBA
107    return "gfx902";
108  case CudaArch::GFX904// TBA
109    return "gfx904";
110  case CudaArch::GFX906// TBA
111    return "gfx906";
112  case CudaArch::GFX909// TBA
113    return "gfx909";
114  }
115  llvm_unreachable("invalid enum");
116}
117
118CudaArch 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
154const 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
192CudaVirtualArch 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
212CudaVirtualArch 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
268CudaVersion 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
315CudaVersion 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
340static 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
365bool CudaFeatureEnabled(llvm::VersionTuple  VersionCudaFeature Feature) {
366  return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
367}
368
369bool CudaFeatureEnabled(CudaVersion VersionCudaFeature 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// namespace clang
379