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 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 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 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 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 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 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 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 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 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 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 390 bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) { 391 return CudaFeatureEnabled(ToCudaVersion(Version), Feature); 392 } 393 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