xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Cuda.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1 #include "clang/Basic/Cuda.h"
2 
3 #include "llvm/ADT/Twine.h"
4 #include "llvm/Support/ErrorHandling.h"
5 #include "llvm/Support/VersionTuple.h"
6 
7 namespace clang {
8 
9 struct CudaVersionMapEntry {
10   const char *Name;
11   CudaVersion Version;
12   llvm::VersionTuple TVersion;
13 };
14 #define CUDA_ENTRY(major, minor)                                               \
15   {                                                                            \
16     #major "." #minor, CudaVersion::CUDA_##major##minor,                       \
17         llvm::VersionTuple(major, minor)                                       \
18   }
19 
20 static const CudaVersionMapEntry CudaNameVersionMap[] = {
21     CUDA_ENTRY(7, 0),
22     CUDA_ENTRY(7, 5),
23     CUDA_ENTRY(8, 0),
24     CUDA_ENTRY(9, 0),
25     CUDA_ENTRY(9, 1),
26     CUDA_ENTRY(9, 2),
27     CUDA_ENTRY(10, 0),
28     CUDA_ENTRY(10, 1),
29     CUDA_ENTRY(10, 2),
30     CUDA_ENTRY(11, 0),
31     CUDA_ENTRY(11, 1),
32     CUDA_ENTRY(11, 2),
33     CUDA_ENTRY(11, 3),
34     CUDA_ENTRY(11, 4),
35     CUDA_ENTRY(11, 5),
36     CUDA_ENTRY(11, 6),
37     CUDA_ENTRY(11, 7),
38     CUDA_ENTRY(11, 8),
39     CUDA_ENTRY(12, 0),
40     CUDA_ENTRY(12, 1),
41     CUDA_ENTRY(12, 2),
42     CUDA_ENTRY(12, 3),
43     CUDA_ENTRY(12, 4),
44     CUDA_ENTRY(12, 5),
45     CUDA_ENTRY(12, 6),
46     CUDA_ENTRY(12, 8),
47     {"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())},
48     {"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone.
49 };
50 #undef CUDA_ENTRY
51 
52 const char *CudaVersionToString(CudaVersion V) {
53   for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
54     if (I->Version == V)
55       return I->Name;
56 
57   return CudaVersionToString(CudaVersion::UNKNOWN);
58 }
59 
60 CudaVersion CudaStringToVersion(const llvm::Twine &S) {
61   std::string VS = S.str();
62   for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
63     if (I->Name == VS)
64       return I->Version;
65   return CudaVersion::UNKNOWN;
66 }
67 
68 CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
69   for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
70     if (I->TVersion == Version)
71       return I->Version;
72   return CudaVersion::UNKNOWN;
73 }
74 
75 CudaVersion MinVersionForOffloadArch(OffloadArch A) {
76   if (A == OffloadArch::UNKNOWN)
77     return CudaVersion::UNKNOWN;
78 
79   // AMD GPUs do not depend on CUDA versions.
80   if (IsAMDOffloadArch(A))
81     return CudaVersion::CUDA_70;
82 
83   switch (A) {
84   case OffloadArch::SM_20:
85   case OffloadArch::SM_21:
86   case OffloadArch::SM_30:
87   case OffloadArch::SM_32_:
88   case OffloadArch::SM_35:
89   case OffloadArch::SM_37:
90   case OffloadArch::SM_50:
91   case OffloadArch::SM_52:
92   case OffloadArch::SM_53:
93     return CudaVersion::CUDA_70;
94   case OffloadArch::SM_60:
95   case OffloadArch::SM_61:
96   case OffloadArch::SM_62:
97     return CudaVersion::CUDA_80;
98   case OffloadArch::SM_70:
99     return CudaVersion::CUDA_90;
100   case OffloadArch::SM_72:
101     return CudaVersion::CUDA_91;
102   case OffloadArch::SM_75:
103     return CudaVersion::CUDA_100;
104   case OffloadArch::SM_80:
105     return CudaVersion::CUDA_110;
106   case OffloadArch::SM_86:
107     return CudaVersion::CUDA_111;
108   case OffloadArch::SM_87:
109     return CudaVersion::CUDA_114;
110   case OffloadArch::SM_89:
111   case OffloadArch::SM_90:
112     return CudaVersion::CUDA_118;
113   case OffloadArch::SM_90a:
114     return CudaVersion::CUDA_120;
115   case OffloadArch::SM_100:
116   case OffloadArch::SM_100a:
117   case OffloadArch::SM_101:
118   case OffloadArch::SM_101a:
119   case OffloadArch::SM_120:
120   case OffloadArch::SM_120a:
121     return CudaVersion::CUDA_128;
122   default:
123     llvm_unreachable("invalid enum");
124   }
125 }
126 
127 CudaVersion MaxVersionForOffloadArch(OffloadArch A) {
128   // AMD GPUs do not depend on CUDA versions.
129   if (IsAMDOffloadArch(A))
130     return CudaVersion::NEW;
131 
132   switch (A) {
133   case OffloadArch::UNKNOWN:
134     return CudaVersion::UNKNOWN;
135   case OffloadArch::SM_20:
136   case OffloadArch::SM_21:
137     return CudaVersion::CUDA_80;
138   case OffloadArch::SM_30:
139   case OffloadArch::SM_32_:
140     return CudaVersion::CUDA_102;
141   case OffloadArch::SM_35:
142   case OffloadArch::SM_37:
143     return CudaVersion::CUDA_118;
144   default:
145     return CudaVersion::NEW;
146   }
147 }
148 
149 bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
150   return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
151 }
152 
153 bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
154   switch (Feature) {
155   case CudaFeature::CUDA_USES_NEW_LAUNCH:
156     return Version >= CudaVersion::CUDA_92;
157   case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
158     return Version >= CudaVersion::CUDA_101;
159   }
160   llvm_unreachable("Unknown CUDA feature.");
161 }
162 } // namespace clang
163