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: // 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::GFX908: // TBA 113 return "gfx908"; 114 case CudaArch::GFX909: // TBA 115 return "gfx909"; 116 case CudaArch::GFX1010: // TBA 117 return "gfx1010"; 118 case CudaArch::GFX1011: // TBA 119 return "gfx1011"; 120 case CudaArch::GFX1012: // TBA 121 return "gfx1012"; 122 } 123 llvm_unreachable("invalid enum"); 124 } 125 126 CudaArch StringToCudaArch(llvm::StringRef S) { 127 return llvm::StringSwitch<CudaArch>(S) 128 .Case("sm_20", CudaArch::SM_20) 129 .Case("sm_21", CudaArch::SM_21) 130 .Case("sm_30", CudaArch::SM_30) 131 .Case("sm_32", CudaArch::SM_32) 132 .Case("sm_35", CudaArch::SM_35) 133 .Case("sm_37", CudaArch::SM_37) 134 .Case("sm_50", CudaArch::SM_50) 135 .Case("sm_52", CudaArch::SM_52) 136 .Case("sm_53", CudaArch::SM_53) 137 .Case("sm_60", CudaArch::SM_60) 138 .Case("sm_61", CudaArch::SM_61) 139 .Case("sm_62", CudaArch::SM_62) 140 .Case("sm_70", CudaArch::SM_70) 141 .Case("sm_72", CudaArch::SM_72) 142 .Case("sm_75", CudaArch::SM_75) 143 .Case("gfx600", CudaArch::GFX600) 144 .Case("gfx601", CudaArch::GFX601) 145 .Case("gfx700", CudaArch::GFX700) 146 .Case("gfx701", CudaArch::GFX701) 147 .Case("gfx702", CudaArch::GFX702) 148 .Case("gfx703", CudaArch::GFX703) 149 .Case("gfx704", CudaArch::GFX704) 150 .Case("gfx801", CudaArch::GFX801) 151 .Case("gfx802", CudaArch::GFX802) 152 .Case("gfx803", CudaArch::GFX803) 153 .Case("gfx810", CudaArch::GFX810) 154 .Case("gfx900", CudaArch::GFX900) 155 .Case("gfx902", CudaArch::GFX902) 156 .Case("gfx904", CudaArch::GFX904) 157 .Case("gfx906", CudaArch::GFX906) 158 .Case("gfx908", CudaArch::GFX908) 159 .Case("gfx909", CudaArch::GFX909) 160 .Case("gfx1010", CudaArch::GFX1010) 161 .Case("gfx1011", CudaArch::GFX1011) 162 .Case("gfx1012", CudaArch::GFX1012) 163 .Default(CudaArch::UNKNOWN); 164 } 165 166 const char *CudaVirtualArchToString(CudaVirtualArch A) { 167 switch (A) { 168 case CudaVirtualArch::UNKNOWN: 169 return "unknown"; 170 case CudaVirtualArch::COMPUTE_20: 171 return "compute_20"; 172 case CudaVirtualArch::COMPUTE_30: 173 return "compute_30"; 174 case CudaVirtualArch::COMPUTE_32: 175 return "compute_32"; 176 case CudaVirtualArch::COMPUTE_35: 177 return "compute_35"; 178 case CudaVirtualArch::COMPUTE_37: 179 return "compute_37"; 180 case CudaVirtualArch::COMPUTE_50: 181 return "compute_50"; 182 case CudaVirtualArch::COMPUTE_52: 183 return "compute_52"; 184 case CudaVirtualArch::COMPUTE_53: 185 return "compute_53"; 186 case CudaVirtualArch::COMPUTE_60: 187 return "compute_60"; 188 case CudaVirtualArch::COMPUTE_61: 189 return "compute_61"; 190 case CudaVirtualArch::COMPUTE_62: 191 return "compute_62"; 192 case CudaVirtualArch::COMPUTE_70: 193 return "compute_70"; 194 case CudaVirtualArch::COMPUTE_72: 195 return "compute_72"; 196 case CudaVirtualArch::COMPUTE_75: 197 return "compute_75"; 198 case CudaVirtualArch::COMPUTE_AMDGCN: 199 return "compute_amdgcn"; 200 } 201 llvm_unreachable("invalid enum"); 202 } 203 204 CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S) { 205 return llvm::StringSwitch<CudaVirtualArch>(S) 206 .Case("compute_20", CudaVirtualArch::COMPUTE_20) 207 .Case("compute_30", CudaVirtualArch::COMPUTE_30) 208 .Case("compute_32", CudaVirtualArch::COMPUTE_32) 209 .Case("compute_35", CudaVirtualArch::COMPUTE_35) 210 .Case("compute_37", CudaVirtualArch::COMPUTE_37) 211 .Case("compute_50", CudaVirtualArch::COMPUTE_50) 212 .Case("compute_52", CudaVirtualArch::COMPUTE_52) 213 .Case("compute_53", CudaVirtualArch::COMPUTE_53) 214 .Case("compute_60", CudaVirtualArch::COMPUTE_60) 215 .Case("compute_61", CudaVirtualArch::COMPUTE_61) 216 .Case("compute_62", CudaVirtualArch::COMPUTE_62) 217 .Case("compute_70", CudaVirtualArch::COMPUTE_70) 218 .Case("compute_72", CudaVirtualArch::COMPUTE_72) 219 .Case("compute_75", CudaVirtualArch::COMPUTE_75) 220 .Case("compute_amdgcn", CudaVirtualArch::COMPUTE_AMDGCN) 221 .Default(CudaVirtualArch::UNKNOWN); 222 } 223 224 CudaVirtualArch VirtualArchForCudaArch(CudaArch A) { 225 switch (A) { 226 case CudaArch::LAST: 227 break; 228 case CudaArch::UNKNOWN: 229 return CudaVirtualArch::UNKNOWN; 230 case CudaArch::SM_20: 231 case CudaArch::SM_21: 232 return CudaVirtualArch::COMPUTE_20; 233 case CudaArch::SM_30: 234 return CudaVirtualArch::COMPUTE_30; 235 case CudaArch::SM_32: 236 return CudaVirtualArch::COMPUTE_32; 237 case CudaArch::SM_35: 238 return CudaVirtualArch::COMPUTE_35; 239 case CudaArch::SM_37: 240 return CudaVirtualArch::COMPUTE_37; 241 case CudaArch::SM_50: 242 return CudaVirtualArch::COMPUTE_50; 243 case CudaArch::SM_52: 244 return CudaVirtualArch::COMPUTE_52; 245 case CudaArch::SM_53: 246 return CudaVirtualArch::COMPUTE_53; 247 case CudaArch::SM_60: 248 return CudaVirtualArch::COMPUTE_60; 249 case CudaArch::SM_61: 250 return CudaVirtualArch::COMPUTE_61; 251 case CudaArch::SM_62: 252 return CudaVirtualArch::COMPUTE_62; 253 case CudaArch::SM_70: 254 return CudaVirtualArch::COMPUTE_70; 255 case CudaArch::SM_72: 256 return CudaVirtualArch::COMPUTE_72; 257 case CudaArch::SM_75: 258 return CudaVirtualArch::COMPUTE_75; 259 case CudaArch::GFX600: 260 case CudaArch::GFX601: 261 case CudaArch::GFX700: 262 case CudaArch::GFX701: 263 case CudaArch::GFX702: 264 case CudaArch::GFX703: 265 case CudaArch::GFX704: 266 case CudaArch::GFX801: 267 case CudaArch::GFX802: 268 case CudaArch::GFX803: 269 case CudaArch::GFX810: 270 case CudaArch::GFX900: 271 case CudaArch::GFX902: 272 case CudaArch::GFX904: 273 case CudaArch::GFX906: 274 case CudaArch::GFX908: 275 case CudaArch::GFX909: 276 case CudaArch::GFX1010: 277 case CudaArch::GFX1011: 278 case CudaArch::GFX1012: 279 return CudaVirtualArch::COMPUTE_AMDGCN; 280 } 281 llvm_unreachable("invalid enum"); 282 } 283 284 CudaVersion MinVersionForCudaArch(CudaArch A) { 285 switch (A) { 286 case CudaArch::LAST: 287 break; 288 case CudaArch::UNKNOWN: 289 return CudaVersion::UNKNOWN; 290 case CudaArch::SM_20: 291 case CudaArch::SM_21: 292 case CudaArch::SM_30: 293 case CudaArch::SM_32: 294 case CudaArch::SM_35: 295 case CudaArch::SM_37: 296 case CudaArch::SM_50: 297 case CudaArch::SM_52: 298 case CudaArch::SM_53: 299 return CudaVersion::CUDA_70; 300 case CudaArch::SM_60: 301 case CudaArch::SM_61: 302 case CudaArch::SM_62: 303 return CudaVersion::CUDA_80; 304 case CudaArch::SM_70: 305 return CudaVersion::CUDA_90; 306 case CudaArch::SM_72: 307 return CudaVersion::CUDA_91; 308 case CudaArch::SM_75: 309 return CudaVersion::CUDA_100; 310 case CudaArch::GFX600: 311 case CudaArch::GFX601: 312 case CudaArch::GFX700: 313 case CudaArch::GFX701: 314 case CudaArch::GFX702: 315 case CudaArch::GFX703: 316 case CudaArch::GFX704: 317 case CudaArch::GFX801: 318 case CudaArch::GFX802: 319 case CudaArch::GFX803: 320 case CudaArch::GFX810: 321 case CudaArch::GFX900: 322 case CudaArch::GFX902: 323 case CudaArch::GFX904: 324 case CudaArch::GFX906: 325 case CudaArch::GFX908: 326 case CudaArch::GFX909: 327 case CudaArch::GFX1010: 328 case CudaArch::GFX1011: 329 case CudaArch::GFX1012: 330 return CudaVersion::CUDA_70; 331 } 332 llvm_unreachable("invalid enum"); 333 } 334 335 CudaVersion MaxVersionForCudaArch(CudaArch A) { 336 switch (A) { 337 case CudaArch::UNKNOWN: 338 return CudaVersion::UNKNOWN; 339 case CudaArch::SM_20: 340 case CudaArch::SM_21: 341 case CudaArch::GFX600: 342 case CudaArch::GFX601: 343 case CudaArch::GFX700: 344 case CudaArch::GFX701: 345 case CudaArch::GFX702: 346 case CudaArch::GFX703: 347 case CudaArch::GFX704: 348 case CudaArch::GFX801: 349 case CudaArch::GFX802: 350 case CudaArch::GFX803: 351 case CudaArch::GFX810: 352 case CudaArch::GFX900: 353 case CudaArch::GFX902: 354 case CudaArch::GFX1010: 355 case CudaArch::GFX1011: 356 case CudaArch::GFX1012: 357 return CudaVersion::CUDA_80; 358 default: 359 return CudaVersion::LATEST; 360 } 361 } 362 363 static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { 364 int IVer = 365 Version.getMajor() * 10 + Version.getMinor().getValueOr(0); 366 switch(IVer) { 367 case 70: 368 return CudaVersion::CUDA_70; 369 case 75: 370 return CudaVersion::CUDA_75; 371 case 80: 372 return CudaVersion::CUDA_80; 373 case 90: 374 return CudaVersion::CUDA_90; 375 case 91: 376 return CudaVersion::CUDA_91; 377 case 92: 378 return CudaVersion::CUDA_92; 379 case 100: 380 return CudaVersion::CUDA_100; 381 case 101: 382 return CudaVersion::CUDA_101; 383 default: 384 return CudaVersion::UNKNOWN; 385 } 386 } 387 388 bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) { 389 return CudaFeatureEnabled(ToCudaVersion(Version), Feature); 390 } 391 392 bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) { 393 switch (Feature) { 394 case CudaFeature::CUDA_USES_NEW_LAUNCH: 395 return Version >= CudaVersion::CUDA_92; 396 case CudaFeature::CUDA_USES_FATBIN_REGISTER_END: 397 return Version >= CudaVersion::CUDA_101; 398 } 399 llvm_unreachable("Unknown CUDA feature."); 400 } 401 } // namespace clang 402