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