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