150
|
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";
|
173
|
31 case CudaVersion::CUDA_102:
|
|
32 return "10.2";
|
|
33 case CudaVersion::CUDA_110:
|
|
34 return "11.0";
|
150
|
35 }
|
|
36 llvm_unreachable("invalid enum");
|
|
37 }
|
|
38
|
|
39 CudaVersion CudaStringToVersion(const llvm::Twine &S) {
|
|
40 return llvm::StringSwitch<CudaVersion>(S.str())
|
|
41 .Case("7.0", CudaVersion::CUDA_70)
|
|
42 .Case("7.5", CudaVersion::CUDA_75)
|
|
43 .Case("8.0", CudaVersion::CUDA_80)
|
|
44 .Case("9.0", CudaVersion::CUDA_90)
|
|
45 .Case("9.1", CudaVersion::CUDA_91)
|
|
46 .Case("9.2", CudaVersion::CUDA_92)
|
|
47 .Case("10.0", CudaVersion::CUDA_100)
|
|
48 .Case("10.1", CudaVersion::CUDA_101)
|
173
|
49 .Case("10.2", CudaVersion::CUDA_102)
|
|
50 .Case("11.0", CudaVersion::CUDA_110)
|
150
|
51 .Default(CudaVersion::UNKNOWN);
|
|
52 }
|
|
53
|
173
|
54 struct CudaArchToStringMap {
|
|
55 CudaArch arch;
|
|
56 const char *arch_name;
|
|
57 const char *virtual_arch_name;
|
|
58 };
|
|
59
|
|
60 #define SM2(sm, ca) \
|
|
61 { CudaArch::SM_##sm, "sm_" #sm, ca }
|
|
62 #define SM(sm) SM2(sm, "compute_" #sm)
|
|
63 #define GFX(gpu) \
|
|
64 { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
|
|
65 CudaArchToStringMap arch_names[] = {
|
|
66 // clang-format off
|
|
67 SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
|
|
68 SM(30), SM(32), SM(35), SM(37), // Kepler
|
|
69 SM(50), SM(52), SM(53), // Maxwell
|
|
70 SM(60), SM(61), SM(62), // Pascal
|
|
71 SM(70), SM(72), // Volta
|
|
72 SM(75), // Turing
|
|
73 SM(80), // Ampere
|
|
74 GFX(600), // tahiti
|
|
75 GFX(601), // pitcairn, verde, oland,hainan
|
|
76 GFX(700), // kaveri
|
|
77 GFX(701), // hawaii
|
|
78 GFX(702), // 290,290x,R390,R390x
|
|
79 GFX(703), // kabini mullins
|
|
80 GFX(704), // bonaire
|
|
81 GFX(801), // carrizo
|
|
82 GFX(802), // tonga,iceland
|
|
83 GFX(803), // fiji,polaris10
|
|
84 GFX(810), // stoney
|
|
85 GFX(900), // vega, instinct
|
|
86 GFX(902), GFX(904), GFX(906), GFX(908), GFX(909),
|
|
87 GFX(1010), GFX(1011), GFX(1012),
|
|
88 // clang-format on
|
|
89 };
|
|
90 #undef SM
|
|
91 #undef SM2
|
|
92 #undef GFX
|
|
93
|
150
|
94 const char *CudaArchToString(CudaArch A) {
|
173
|
95 auto result = std::find_if(
|
|
96 std::begin(arch_names), std::end(arch_names),
|
|
97 [A](const CudaArchToStringMap &map) { return A == map.arch; });
|
|
98 if (result == std::end(arch_names))
|
150
|
99 return "unknown";
|
173
|
100 return result->arch_name;
|
|
101 }
|
|
102
|
|
103 const char *CudaArchToVirtualArchString(CudaArch A) {
|
|
104 auto result = std::find_if(
|
|
105 std::begin(arch_names), std::end(arch_names),
|
|
106 [A](const CudaArchToStringMap &map) { return A == map.arch; });
|
|
107 if (result == std::end(arch_names))
|
|
108 return "unknown";
|
|
109 return result->virtual_arch_name;
|
150
|
110 }
|
|
111
|
|
112 CudaArch StringToCudaArch(llvm::StringRef S) {
|
173
|
113 auto result = std::find_if(
|
|
114 std::begin(arch_names), std::end(arch_names),
|
|
115 [S](const CudaArchToStringMap &map) { return S == map.arch_name; });
|
|
116 if (result == std::end(arch_names))
|
|
117 return CudaArch::UNKNOWN;
|
|
118 return result->arch;
|
150
|
119 }
|
|
120
|
|
121 CudaVersion MinVersionForCudaArch(CudaArch A) {
|
173
|
122 if (A == CudaArch::UNKNOWN)
|
|
123 return CudaVersion::UNKNOWN;
|
|
124
|
|
125 // AMD GPUs do not depend on CUDA versions.
|
|
126 if (IsAMDGpuArch(A))
|
|
127 return CudaVersion::CUDA_70;
|
|
128
|
150
|
129 switch (A) {
|
|
130 case CudaArch::SM_20:
|
|
131 case CudaArch::SM_21:
|
|
132 case CudaArch::SM_30:
|
|
133 case CudaArch::SM_32:
|
|
134 case CudaArch::SM_35:
|
|
135 case CudaArch::SM_37:
|
|
136 case CudaArch::SM_50:
|
|
137 case CudaArch::SM_52:
|
|
138 case CudaArch::SM_53:
|
|
139 return CudaVersion::CUDA_70;
|
|
140 case CudaArch::SM_60:
|
|
141 case CudaArch::SM_61:
|
|
142 case CudaArch::SM_62:
|
|
143 return CudaVersion::CUDA_80;
|
|
144 case CudaArch::SM_70:
|
|
145 return CudaVersion::CUDA_90;
|
|
146 case CudaArch::SM_72:
|
|
147 return CudaVersion::CUDA_91;
|
|
148 case CudaArch::SM_75:
|
|
149 return CudaVersion::CUDA_100;
|
173
|
150 case CudaArch::SM_80:
|
|
151 return CudaVersion::CUDA_110;
|
|
152 default:
|
|
153 llvm_unreachable("invalid enum");
|
150
|
154 }
|
|
155 }
|
|
156
|
|
157 CudaVersion MaxVersionForCudaArch(CudaArch A) {
|
173
|
158 // AMD GPUs do not depend on CUDA versions.
|
|
159 if (IsAMDGpuArch(A))
|
|
160 return CudaVersion::LATEST;
|
|
161
|
150
|
162 switch (A) {
|
|
163 case CudaArch::UNKNOWN:
|
|
164 return CudaVersion::UNKNOWN;
|
|
165 case CudaArch::SM_20:
|
|
166 case CudaArch::SM_21:
|
|
167 return CudaVersion::CUDA_80;
|
|
168 default:
|
|
169 return CudaVersion::LATEST;
|
|
170 }
|
|
171 }
|
|
172
|
173
|
173 CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
|
150
|
174 int IVer =
|
|
175 Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
|
|
176 switch(IVer) {
|
|
177 case 70:
|
|
178 return CudaVersion::CUDA_70;
|
|
179 case 75:
|
|
180 return CudaVersion::CUDA_75;
|
|
181 case 80:
|
|
182 return CudaVersion::CUDA_80;
|
|
183 case 90:
|
|
184 return CudaVersion::CUDA_90;
|
|
185 case 91:
|
|
186 return CudaVersion::CUDA_91;
|
|
187 case 92:
|
|
188 return CudaVersion::CUDA_92;
|
|
189 case 100:
|
|
190 return CudaVersion::CUDA_100;
|
|
191 case 101:
|
|
192 return CudaVersion::CUDA_101;
|
173
|
193 case 102:
|
|
194 return CudaVersion::CUDA_102;
|
|
195 case 110:
|
|
196 return CudaVersion::CUDA_110;
|
150
|
197 default:
|
|
198 return CudaVersion::UNKNOWN;
|
|
199 }
|
|
200 }
|
|
201
|
|
202 bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
|
|
203 return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
|
|
204 }
|
|
205
|
|
206 bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
|
|
207 switch (Feature) {
|
|
208 case CudaFeature::CUDA_USES_NEW_LAUNCH:
|
|
209 return Version >= CudaVersion::CUDA_92;
|
|
210 case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
|
|
211 return Version >= CudaVersion::CUDA_101;
|
|
212 }
|
|
213 llvm_unreachable("Unknown CUDA feature.");
|
|
214 }
|
|
215 } // namespace clang
|