xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Basic/Cuda.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg #include "clang/Basic/Cuda.h"
27330f729Sjoerg 
37330f729Sjoerg #include "llvm/ADT/StringRef.h"
47330f729Sjoerg #include "llvm/ADT/StringSwitch.h"
5*e038c9c4Sjoerg #include "llvm/ADT/Twine.h"
67330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
77330f729Sjoerg #include "llvm/Support/VersionTuple.h"
87330f729Sjoerg 
97330f729Sjoerg namespace clang {
107330f729Sjoerg 
CudaVersionToString(CudaVersion V)117330f729Sjoerg const char *CudaVersionToString(CudaVersion V) {
127330f729Sjoerg   switch (V) {
137330f729Sjoerg   case CudaVersion::UNKNOWN:
147330f729Sjoerg     return "unknown";
157330f729Sjoerg   case CudaVersion::CUDA_70:
167330f729Sjoerg     return "7.0";
177330f729Sjoerg   case CudaVersion::CUDA_75:
187330f729Sjoerg     return "7.5";
197330f729Sjoerg   case CudaVersion::CUDA_80:
207330f729Sjoerg     return "8.0";
217330f729Sjoerg   case CudaVersion::CUDA_90:
227330f729Sjoerg     return "9.0";
237330f729Sjoerg   case CudaVersion::CUDA_91:
247330f729Sjoerg     return "9.1";
257330f729Sjoerg   case CudaVersion::CUDA_92:
267330f729Sjoerg     return "9.2";
277330f729Sjoerg   case CudaVersion::CUDA_100:
287330f729Sjoerg     return "10.0";
297330f729Sjoerg   case CudaVersion::CUDA_101:
307330f729Sjoerg     return "10.1";
31*e038c9c4Sjoerg   case CudaVersion::CUDA_102:
32*e038c9c4Sjoerg     return "10.2";
33*e038c9c4Sjoerg   case CudaVersion::CUDA_110:
34*e038c9c4Sjoerg     return "11.0";
35*e038c9c4Sjoerg   case CudaVersion::CUDA_111:
36*e038c9c4Sjoerg     return "11.1";
37*e038c9c4Sjoerg   case CudaVersion::CUDA_112:
38*e038c9c4Sjoerg     return "11.2";
397330f729Sjoerg   }
407330f729Sjoerg   llvm_unreachable("invalid enum");
417330f729Sjoerg }
427330f729Sjoerg 
CudaStringToVersion(const llvm::Twine & S)43*e038c9c4Sjoerg CudaVersion CudaStringToVersion(const llvm::Twine &S) {
44*e038c9c4Sjoerg   return llvm::StringSwitch<CudaVersion>(S.str())
457330f729Sjoerg       .Case("7.0", CudaVersion::CUDA_70)
467330f729Sjoerg       .Case("7.5", CudaVersion::CUDA_75)
477330f729Sjoerg       .Case("8.0", CudaVersion::CUDA_80)
487330f729Sjoerg       .Case("9.0", CudaVersion::CUDA_90)
497330f729Sjoerg       .Case("9.1", CudaVersion::CUDA_91)
507330f729Sjoerg       .Case("9.2", CudaVersion::CUDA_92)
517330f729Sjoerg       .Case("10.0", CudaVersion::CUDA_100)
52*e038c9c4Sjoerg       .Case("10.1", CudaVersion::CUDA_101)
53*e038c9c4Sjoerg       .Case("10.2", CudaVersion::CUDA_102)
54*e038c9c4Sjoerg       .Case("11.0", CudaVersion::CUDA_110)
55*e038c9c4Sjoerg       .Case("11.1", CudaVersion::CUDA_111)
56*e038c9c4Sjoerg       .Case("11.2", CudaVersion::CUDA_112)
57*e038c9c4Sjoerg       .Default(CudaVersion::UNKNOWN);
587330f729Sjoerg }
597330f729Sjoerg 
60*e038c9c4Sjoerg namespace {
61*e038c9c4Sjoerg struct CudaArchToStringMap {
62*e038c9c4Sjoerg   CudaArch arch;
63*e038c9c4Sjoerg   const char *arch_name;
64*e038c9c4Sjoerg   const char *virtual_arch_name;
65*e038c9c4Sjoerg };
66*e038c9c4Sjoerg } // namespace
67*e038c9c4Sjoerg 
68*e038c9c4Sjoerg #define SM2(sm, ca)                                                            \
69*e038c9c4Sjoerg   { CudaArch::SM_##sm, "sm_" #sm, ca }
70*e038c9c4Sjoerg #define SM(sm) SM2(sm, "compute_" #sm)
71*e038c9c4Sjoerg #define GFX(gpu)                                                               \
72*e038c9c4Sjoerg   { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
73*e038c9c4Sjoerg static const CudaArchToStringMap arch_names[] = {
74*e038c9c4Sjoerg     // clang-format off
75*e038c9c4Sjoerg     {CudaArch::UNUSED, "", ""},
76*e038c9c4Sjoerg     SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
77*e038c9c4Sjoerg     SM(30), SM(32), SM(35), SM(37),  // Kepler
78*e038c9c4Sjoerg     SM(50), SM(52), SM(53),          // Maxwell
79*e038c9c4Sjoerg     SM(60), SM(61), SM(62),          // Pascal
80*e038c9c4Sjoerg     SM(70), SM(72),                  // Volta
81*e038c9c4Sjoerg     SM(75),                          // Turing
82*e038c9c4Sjoerg     SM(80), SM(86),                  // Ampere
83*e038c9c4Sjoerg     GFX(600),  // gfx600
84*e038c9c4Sjoerg     GFX(601),  // gfx601
85*e038c9c4Sjoerg     GFX(602),  // gfx602
86*e038c9c4Sjoerg     GFX(700),  // gfx700
87*e038c9c4Sjoerg     GFX(701),  // gfx701
88*e038c9c4Sjoerg     GFX(702),  // gfx702
89*e038c9c4Sjoerg     GFX(703),  // gfx703
90*e038c9c4Sjoerg     GFX(704),  // gfx704
91*e038c9c4Sjoerg     GFX(705),  // gfx705
92*e038c9c4Sjoerg     GFX(801),  // gfx801
93*e038c9c4Sjoerg     GFX(802),  // gfx802
94*e038c9c4Sjoerg     GFX(803),  // gfx803
95*e038c9c4Sjoerg     GFX(805),  // gfx805
96*e038c9c4Sjoerg     GFX(810),  // gfx810
97*e038c9c4Sjoerg     GFX(900),  // gfx900
98*e038c9c4Sjoerg     GFX(902),  // gfx902
99*e038c9c4Sjoerg     GFX(904),  // gfx903
100*e038c9c4Sjoerg     GFX(906),  // gfx906
101*e038c9c4Sjoerg     GFX(908),  // gfx908
102*e038c9c4Sjoerg     GFX(909),  // gfx909
103*e038c9c4Sjoerg     GFX(90a),  // gfx90a
104*e038c9c4Sjoerg     GFX(90c),  // gfx90c
105*e038c9c4Sjoerg     GFX(1010), // gfx1010
106*e038c9c4Sjoerg     GFX(1011), // gfx1011
107*e038c9c4Sjoerg     GFX(1012), // gfx1012
108*e038c9c4Sjoerg     GFX(1030), // gfx1030
109*e038c9c4Sjoerg     GFX(1031), // gfx1031
110*e038c9c4Sjoerg     GFX(1032), // gfx1032
111*e038c9c4Sjoerg     GFX(1033), // gfx1033
112*e038c9c4Sjoerg     GFX(1034), // gfx1034
113*e038c9c4Sjoerg     // clang-format on
114*e038c9c4Sjoerg };
115*e038c9c4Sjoerg #undef SM
116*e038c9c4Sjoerg #undef SM2
117*e038c9c4Sjoerg #undef GFX
118*e038c9c4Sjoerg 
CudaArchToString(CudaArch A)1197330f729Sjoerg const char *CudaArchToString(CudaArch A) {
120*e038c9c4Sjoerg   auto result = std::find_if(
121*e038c9c4Sjoerg       std::begin(arch_names), std::end(arch_names),
122*e038c9c4Sjoerg       [A](const CudaArchToStringMap &map) { return A == map.arch; });
123*e038c9c4Sjoerg   if (result == std::end(arch_names))
1247330f729Sjoerg     return "unknown";
125*e038c9c4Sjoerg   return result->arch_name;
1267330f729Sjoerg }
127*e038c9c4Sjoerg 
CudaArchToVirtualArchString(CudaArch A)128*e038c9c4Sjoerg const char *CudaArchToVirtualArchString(CudaArch A) {
129*e038c9c4Sjoerg   auto result = std::find_if(
130*e038c9c4Sjoerg       std::begin(arch_names), std::end(arch_names),
131*e038c9c4Sjoerg       [A](const CudaArchToStringMap &map) { return A == map.arch; });
132*e038c9c4Sjoerg   if (result == std::end(arch_names))
133*e038c9c4Sjoerg     return "unknown";
134*e038c9c4Sjoerg   return result->virtual_arch_name;
1357330f729Sjoerg }
1367330f729Sjoerg 
StringToCudaArch(llvm::StringRef S)1377330f729Sjoerg CudaArch StringToCudaArch(llvm::StringRef S) {
138*e038c9c4Sjoerg   auto result = std::find_if(
139*e038c9c4Sjoerg       std::begin(arch_names), std::end(arch_names),
140*e038c9c4Sjoerg       [S](const CudaArchToStringMap &map) { return S == map.arch_name; });
141*e038c9c4Sjoerg   if (result == std::end(arch_names))
142*e038c9c4Sjoerg     return CudaArch::UNKNOWN;
143*e038c9c4Sjoerg   return result->arch;
1447330f729Sjoerg }
1457330f729Sjoerg 
MinVersionForCudaArch(CudaArch A)1467330f729Sjoerg CudaVersion MinVersionForCudaArch(CudaArch A) {
147*e038c9c4Sjoerg   if (A == CudaArch::UNKNOWN)
1487330f729Sjoerg     return CudaVersion::UNKNOWN;
149*e038c9c4Sjoerg 
150*e038c9c4Sjoerg   // AMD GPUs do not depend on CUDA versions.
151*e038c9c4Sjoerg   if (IsAMDGpuArch(A))
152*e038c9c4Sjoerg     return CudaVersion::CUDA_70;
153*e038c9c4Sjoerg 
154*e038c9c4Sjoerg   switch (A) {
1557330f729Sjoerg   case CudaArch::SM_20:
1567330f729Sjoerg   case CudaArch::SM_21:
1577330f729Sjoerg   case CudaArch::SM_30:
1587330f729Sjoerg   case CudaArch::SM_32:
1597330f729Sjoerg   case CudaArch::SM_35:
1607330f729Sjoerg   case CudaArch::SM_37:
1617330f729Sjoerg   case CudaArch::SM_50:
1627330f729Sjoerg   case CudaArch::SM_52:
1637330f729Sjoerg   case CudaArch::SM_53:
1647330f729Sjoerg     return CudaVersion::CUDA_70;
1657330f729Sjoerg   case CudaArch::SM_60:
1667330f729Sjoerg   case CudaArch::SM_61:
1677330f729Sjoerg   case CudaArch::SM_62:
1687330f729Sjoerg     return CudaVersion::CUDA_80;
1697330f729Sjoerg   case CudaArch::SM_70:
1707330f729Sjoerg     return CudaVersion::CUDA_90;
1717330f729Sjoerg   case CudaArch::SM_72:
1727330f729Sjoerg     return CudaVersion::CUDA_91;
1737330f729Sjoerg   case CudaArch::SM_75:
1747330f729Sjoerg     return CudaVersion::CUDA_100;
175*e038c9c4Sjoerg   case CudaArch::SM_80:
176*e038c9c4Sjoerg     return CudaVersion::CUDA_110;
177*e038c9c4Sjoerg   case CudaArch::SM_86:
178*e038c9c4Sjoerg     return CudaVersion::CUDA_111;
179*e038c9c4Sjoerg   default:
1807330f729Sjoerg     llvm_unreachable("invalid enum");
1817330f729Sjoerg   }
182*e038c9c4Sjoerg }
1837330f729Sjoerg 
MaxVersionForCudaArch(CudaArch A)1847330f729Sjoerg CudaVersion MaxVersionForCudaArch(CudaArch A) {
185*e038c9c4Sjoerg   // AMD GPUs do not depend on CUDA versions.
186*e038c9c4Sjoerg   if (IsAMDGpuArch(A))
187*e038c9c4Sjoerg     return CudaVersion::LATEST;
188*e038c9c4Sjoerg 
1897330f729Sjoerg   switch (A) {
1907330f729Sjoerg   case CudaArch::UNKNOWN:
1917330f729Sjoerg     return CudaVersion::UNKNOWN;
1927330f729Sjoerg   case CudaArch::SM_20:
1937330f729Sjoerg   case CudaArch::SM_21:
1947330f729Sjoerg     return CudaVersion::CUDA_80;
1957330f729Sjoerg   default:
1967330f729Sjoerg     return CudaVersion::LATEST;
1977330f729Sjoerg   }
1987330f729Sjoerg }
1997330f729Sjoerg 
ToCudaVersion(llvm::VersionTuple Version)200*e038c9c4Sjoerg CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
2017330f729Sjoerg   int IVer =
2027330f729Sjoerg       Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
2037330f729Sjoerg   switch(IVer) {
2047330f729Sjoerg   case 70:
2057330f729Sjoerg     return CudaVersion::CUDA_70;
2067330f729Sjoerg   case 75:
2077330f729Sjoerg     return CudaVersion::CUDA_75;
2087330f729Sjoerg   case 80:
2097330f729Sjoerg     return CudaVersion::CUDA_80;
2107330f729Sjoerg   case 90:
2117330f729Sjoerg     return CudaVersion::CUDA_90;
2127330f729Sjoerg   case 91:
2137330f729Sjoerg     return CudaVersion::CUDA_91;
2147330f729Sjoerg   case 92:
2157330f729Sjoerg     return CudaVersion::CUDA_92;
2167330f729Sjoerg   case 100:
2177330f729Sjoerg     return CudaVersion::CUDA_100;
2187330f729Sjoerg   case 101:
2197330f729Sjoerg     return CudaVersion::CUDA_101;
220*e038c9c4Sjoerg   case 102:
221*e038c9c4Sjoerg     return CudaVersion::CUDA_102;
222*e038c9c4Sjoerg   case 110:
223*e038c9c4Sjoerg     return CudaVersion::CUDA_110;
224*e038c9c4Sjoerg   case 111:
225*e038c9c4Sjoerg     return CudaVersion::CUDA_111;
226*e038c9c4Sjoerg   case 112:
227*e038c9c4Sjoerg     return CudaVersion::CUDA_112;
2287330f729Sjoerg   default:
2297330f729Sjoerg     return CudaVersion::UNKNOWN;
2307330f729Sjoerg   }
2317330f729Sjoerg }
2327330f729Sjoerg 
CudaFeatureEnabled(llvm::VersionTuple Version,CudaFeature Feature)2337330f729Sjoerg bool CudaFeatureEnabled(llvm::VersionTuple  Version, CudaFeature Feature) {
2347330f729Sjoerg   return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
2357330f729Sjoerg }
2367330f729Sjoerg 
CudaFeatureEnabled(CudaVersion Version,CudaFeature Feature)2377330f729Sjoerg bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
2387330f729Sjoerg   switch (Feature) {
2397330f729Sjoerg   case CudaFeature::CUDA_USES_NEW_LAUNCH:
2407330f729Sjoerg     return Version >= CudaVersion::CUDA_92;
2417330f729Sjoerg   case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
2427330f729Sjoerg     return Version >= CudaVersion::CUDA_101;
2437330f729Sjoerg   }
2447330f729Sjoerg   llvm_unreachable("Unknown CUDA feature.");
2457330f729Sjoerg }
2467330f729Sjoerg } // namespace clang
247