/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Cuda.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
11 | 8 | const char *CudaVersionToString(CudaVersion V) { |
12 | 8 | switch (V) { |
13 | 0 | case CudaVersion::UNKNOWN: |
14 | 0 | return "unknown"; |
15 | 8 | case CudaVersion::CUDA_70: |
16 | 8 | return "7.0"; |
17 | 0 | case CudaVersion::CUDA_75: |
18 | 0 | return "7.5"; |
19 | 0 | case CudaVersion::CUDA_80: |
20 | 0 | return "8.0"; |
21 | 0 | case CudaVersion::CUDA_90: |
22 | 0 | return "9.0"; |
23 | 0 | case CudaVersion::CUDA_91: |
24 | 0 | return "9.1"; |
25 | 0 | case CudaVersion::CUDA_92: |
26 | 0 | return "9.2"; |
27 | 0 | case CudaVersion::CUDA_100: |
28 | 0 | return "10.0"; |
29 | 0 | case CudaVersion::CUDA_101: |
30 | 0 | return "10.1"; |
31 | 0 | case CudaVersion::CUDA_102: |
32 | 0 | return "10.2"; |
33 | 0 | case CudaVersion::CUDA_110: |
34 | 0 | return "11.0"; |
35 | 0 | case CudaVersion::CUDA_111: |
36 | 0 | return "11.1"; |
37 | 0 | case CudaVersion::CUDA_112: |
38 | 0 | return "11.2"; |
39 | 0 | case CudaVersion::CUDA_113: |
40 | 0 | return "11.3"; |
41 | 0 | case CudaVersion::CUDA_114: |
42 | 0 | return "11.4"; |
43 | 0 | case CudaVersion::CUDA_115: |
44 | 0 | return "11.5"; |
45 | 0 | case CudaVersion::NEW: |
46 | 0 | return ""; |
47 | 8 | } |
48 | 0 | llvm_unreachable("invalid enum"); |
49 | 0 | } |
50 | | |
51 | 0 | CudaVersion CudaStringToVersion(const llvm::Twine &S) { |
52 | 0 | return llvm::StringSwitch<CudaVersion>(S.str()) |
53 | 0 | .Case("7.0", CudaVersion::CUDA_70) |
54 | 0 | .Case("7.5", CudaVersion::CUDA_75) |
55 | 0 | .Case("8.0", CudaVersion::CUDA_80) |
56 | 0 | .Case("9.0", CudaVersion::CUDA_90) |
57 | 0 | .Case("9.1", CudaVersion::CUDA_91) |
58 | 0 | .Case("9.2", CudaVersion::CUDA_92) |
59 | 0 | .Case("10.0", CudaVersion::CUDA_100) |
60 | 0 | .Case("10.1", CudaVersion::CUDA_101) |
61 | 0 | .Case("10.2", CudaVersion::CUDA_102) |
62 | 0 | .Case("11.0", CudaVersion::CUDA_110) |
63 | 0 | .Case("11.1", CudaVersion::CUDA_111) |
64 | 0 | .Case("11.2", CudaVersion::CUDA_112) |
65 | 0 | .Case("11.3", CudaVersion::CUDA_113) |
66 | 0 | .Case("11.4", CudaVersion::CUDA_114) |
67 | 0 | .Case("11.5", CudaVersion::CUDA_115) |
68 | 0 | .Default(CudaVersion::UNKNOWN); |
69 | 0 | } |
70 | | |
71 | | namespace { |
72 | | struct CudaArchToStringMap { |
73 | | CudaArch arch; |
74 | | const char *arch_name; |
75 | | const char *virtual_arch_name; |
76 | | }; |
77 | | } // namespace |
78 | | |
79 | | #define SM2(sm, ca) \ |
80 | | { CudaArch::SM_##sm, "sm_" #sm, ca } |
81 | | #define SM(sm) SM2(sm, "compute_" #sm) |
82 | | #define GFX(gpu) \ |
83 | | { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" } |
84 | | static const CudaArchToStringMap arch_names[] = { |
85 | | // clang-format off |
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 |
92 | | SM(75), // Turing |
93 | | SM(80), SM(86), // Ampere |
94 | | GFX(600), // gfx600 |
95 | | GFX(601), // gfx601 |
96 | | GFX(602), // gfx602 |
97 | | GFX(700), // gfx700 |
98 | | GFX(701), // gfx701 |
99 | | GFX(702), // gfx702 |
100 | | GFX(703), // gfx703 |
101 | | GFX(704), // gfx704 |
102 | | GFX(705), // gfx705 |
103 | | GFX(801), // gfx801 |
104 | | GFX(802), // gfx802 |
105 | | GFX(803), // gfx803 |
106 | | GFX(805), // gfx805 |
107 | | GFX(810), // gfx810 |
108 | | GFX(900), // gfx900 |
109 | | GFX(902), // gfx902 |
110 | | GFX(904), // gfx903 |
111 | | GFX(906), // gfx906 |
112 | | GFX(908), // gfx908 |
113 | | GFX(909), // gfx909 |
114 | | GFX(90a), // gfx90a |
115 | | GFX(90c), // gfx90c |
116 | | GFX(940), // gfx940 |
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 | | GFX(1100), // gfx1100 |
129 | | GFX(1101), // gfx1101 |
130 | | GFX(1102), // gfx1102 |
131 | | GFX(1103), // gfx1103 |
132 | | {CudaArch::Generic, "generic", ""}, |
133 | | // clang-format on |
134 | | }; |
135 | | #undef SM |
136 | | #undef SM2 |
137 | | #undef GFX |
138 | | |
139 | 570 | const char *CudaArchToString(CudaArch A) { |
140 | 570 | auto result = std::find_if( |
141 | 570 | std::begin(arch_names), std::end(arch_names), |
142 | 4.58k | [A](const CudaArchToStringMap &map) { return A == map.arch; }); |
143 | 570 | if (result == std::end(arch_names)) |
144 | 0 | return "unknown"; |
145 | 570 | return result->arch_name; |
146 | 570 | } |
147 | | |
148 | 36 | const char *CudaArchToVirtualArchString(CudaArch A) { |
149 | 36 | auto result = std::find_if( |
150 | 36 | std::begin(arch_names), std::end(arch_names), |
151 | 132 | [A](const CudaArchToStringMap &map) { return A == map.arch; }); |
152 | 36 | if (result == std::end(arch_names)) |
153 | 0 | return "unknown"; |
154 | 36 | return result->virtual_arch_name; |
155 | 36 | } |
156 | | |
157 | 253 | CudaArch StringToCudaArch(llvm::StringRef S) { |
158 | 253 | auto result = std::find_if( |
159 | 253 | std::begin(arch_names), std::end(arch_names), |
160 | 2.34k | [S](const CudaArchToStringMap &map) { return S == map.arch_name; }); |
161 | 253 | if (result == std::end(arch_names)) |
162 | 18 | return CudaArch::UNKNOWN; |
163 | 235 | return result->arch; |
164 | 253 | } |
165 | | |
166 | 3 | CudaVersion MinVersionForCudaArch(CudaArch A) { |
167 | 3 | if (A == CudaArch::UNKNOWN) |
168 | 0 | return CudaVersion::UNKNOWN; |
169 | | |
170 | | // AMD GPUs do not depend on CUDA versions. |
171 | 3 | if (IsAMDGpuArch(A)) |
172 | 0 | return CudaVersion::CUDA_70; |
173 | | |
174 | 3 | switch (A) { |
175 | 0 | case CudaArch::SM_20: |
176 | 0 | case CudaArch::SM_21: |
177 | 0 | case CudaArch::SM_30: |
178 | 0 | case CudaArch::SM_32: |
179 | 3 | case CudaArch::SM_35: |
180 | 3 | case CudaArch::SM_37: |
181 | 3 | case CudaArch::SM_50: |
182 | 3 | case CudaArch::SM_52: |
183 | 3 | case CudaArch::SM_53: |
184 | 3 | return CudaVersion::CUDA_70; |
185 | 0 | case CudaArch::SM_60: |
186 | 0 | case CudaArch::SM_61: |
187 | 0 | case CudaArch::SM_62: |
188 | 0 | return CudaVersion::CUDA_80; |
189 | 0 | case CudaArch::SM_70: |
190 | 0 | return CudaVersion::CUDA_90; |
191 | 0 | case CudaArch::SM_72: |
192 | 0 | return CudaVersion::CUDA_91; |
193 | 0 | case CudaArch::SM_75: |
194 | 0 | return CudaVersion::CUDA_100; |
195 | 0 | case CudaArch::SM_80: |
196 | 0 | return CudaVersion::CUDA_110; |
197 | 0 | case CudaArch::SM_86: |
198 | 0 | return CudaVersion::CUDA_111; |
199 | 0 | default: |
200 | 0 | llvm_unreachable("invalid enum"); |
201 | 3 | } |
202 | 3 | } |
203 | | |
204 | 3 | CudaVersion MaxVersionForCudaArch(CudaArch A) { |
205 | | // AMD GPUs do not depend on CUDA versions. |
206 | 3 | if (IsAMDGpuArch(A)) |
207 | 0 | return CudaVersion::NEW; |
208 | | |
209 | 3 | switch (A) { |
210 | 0 | case CudaArch::UNKNOWN: |
211 | 0 | return CudaVersion::UNKNOWN; |
212 | 0 | case CudaArch::SM_20: |
213 | 0 | case CudaArch::SM_21: |
214 | 0 | return CudaVersion::CUDA_80; |
215 | 0 | case CudaArch::SM_30: |
216 | 0 | return CudaVersion::CUDA_110; |
217 | 3 | default: |
218 | 3 | return CudaVersion::NEW; |
219 | 3 | } |
220 | 3 | } |
221 | | |
222 | 1.75k | CudaVersion ToCudaVersion(llvm::VersionTuple Version) { |
223 | 1.75k | int IVer = Version.getMajor() * 10 + Version.getMinor().value_or(0); |
224 | 1.75k | switch(IVer) { |
225 | 4 | case 70: |
226 | 4 | return CudaVersion::CUDA_70; |
227 | 0 | case 75: |
228 | 0 | return CudaVersion::CUDA_75; |
229 | 80 | case 80: |
230 | 80 | return CudaVersion::CUDA_80; |
231 | 0 | case 90: |
232 | 0 | return CudaVersion::CUDA_90; |
233 | 0 | case 91: |
234 | 0 | return CudaVersion::CUDA_91; |
235 | 65 | case 92: |
236 | 65 | return CudaVersion::CUDA_92; |
237 | 0 | case 100: |
238 | 0 | return CudaVersion::CUDA_100; |
239 | 0 | case 101: |
240 | 0 | return CudaVersion::CUDA_101; |
241 | 0 | case 102: |
242 | 0 | return CudaVersion::CUDA_102; |
243 | 0 | case 110: |
244 | 0 | return CudaVersion::CUDA_110; |
245 | 0 | case 111: |
246 | 0 | return CudaVersion::CUDA_111; |
247 | 0 | case 112: |
248 | 0 | return CudaVersion::CUDA_112; |
249 | 0 | case 113: |
250 | 0 | return CudaVersion::CUDA_113; |
251 | 0 | case 114: |
252 | 0 | return CudaVersion::CUDA_114; |
253 | 20 | case 115: |
254 | 20 | return CudaVersion::CUDA_115; |
255 | 1.58k | default: |
256 | 1.58k | return CudaVersion::UNKNOWN; |
257 | 1.75k | } |
258 | 1.75k | } |
259 | | |
260 | 1.74k | bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) { |
261 | 1.74k | return CudaFeatureEnabled(ToCudaVersion(Version), Feature); |
262 | 1.74k | } |
263 | | |
264 | 1.74k | bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) { |
265 | 1.74k | switch (Feature) { |
266 | 1.74k | case CudaFeature::CUDA_USES_NEW_LAUNCH: |
267 | 1.74k | return Version >= CudaVersion::CUDA_92; |
268 | 6 | case CudaFeature::CUDA_USES_FATBIN_REGISTER_END: |
269 | 6 | return Version >= CudaVersion::CUDA_101; |
270 | 1.74k | } |
271 | 0 | llvm_unreachable("Unknown CUDA feature."); |
272 | 0 | } |
273 | | } // namespace clang |