1 #include "clang/Basic/Cuda.h"
3 #include "llvm/ADT/StringRef.h"
4 #include "llvm/ADT/Twine.h"
5 #include "llvm/Support/ErrorHandling.h"
6 #include "llvm/Support/VersionTuple.h"
10 struct CudaVersionMapEntry
{
13 llvm::VersionTuple TVersion
;
15 #define CUDA_ENTRY(major, minor) \
17 #major "." #minor, CudaVersion::CUDA_##major##minor, \
18 llvm::VersionTuple(major, minor) \
21 static const CudaVersionMapEntry CudaNameVersionMap
[] = {
42 {"", CudaVersion::NEW
, llvm::VersionTuple(std::numeric_limits
<int>::max())},
43 {"unknown", CudaVersion::UNKNOWN
, {}} // End of list tombstone.
47 const char *CudaVersionToString(CudaVersion V
) {
48 for (auto *I
= CudaNameVersionMap
; I
->Version
!= CudaVersion::UNKNOWN
; ++I
)
52 return CudaVersionToString(CudaVersion::UNKNOWN
);
55 CudaVersion
CudaStringToVersion(const llvm::Twine
&S
) {
56 std::string VS
= S
.str();
57 for (auto *I
= CudaNameVersionMap
; I
->Version
!= CudaVersion::UNKNOWN
; ++I
)
60 return CudaVersion::UNKNOWN
;
63 CudaVersion
ToCudaVersion(llvm::VersionTuple Version
) {
64 for (auto *I
= CudaNameVersionMap
; I
->Version
!= CudaVersion::UNKNOWN
; ++I
)
65 if (I
->TVersion
== Version
)
67 return CudaVersion::UNKNOWN
;
71 struct CudaArchToStringMap
{
73 const char *arch_name
;
74 const char *virtual_arch_name
;
79 { CudaArch::SM_##sm, "sm_" #sm, ca }
80 #define SM(sm) SM2(sm, "compute_" #sm)
82 { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
83 static const CudaArchToStringMap arch_names
[] = {
85 {CudaArch::UNUSED
, "", ""},
86 SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
87 SM(30), SM(32), SM(35), SM(37), // Kepler
88 SM(50), SM(52), SM(53), // Maxwell
89 SM(60), SM(61), SM(62), // Pascal
90 SM(70), SM(72), // Volta
92 SM(80), SM(86), // Ampere
93 SM(87), // Jetson/Drive AGX Orin
94 SM(89), // Ada Lovelace
121 GFX(1010), // gfx1010
122 GFX(1011), // gfx1011
123 GFX(1012), // gfx1012
124 GFX(1013), // gfx1013
125 GFX(1030), // gfx1030
126 GFX(1031), // gfx1031
127 GFX(1032), // gfx1032
128 GFX(1033), // gfx1033
129 GFX(1034), // gfx1034
130 GFX(1035), // gfx1035
131 GFX(1036), // gfx1036
132 GFX(1100), // gfx1100
133 GFX(1101), // gfx1101
134 GFX(1102), // gfx1102
135 GFX(1103), // gfx1103
136 {CudaArch::Generic
, "generic", ""},
143 const char *CudaArchToString(CudaArch A
) {
144 auto result
= std::find_if(
145 std::begin(arch_names
), std::end(arch_names
),
146 [A
](const CudaArchToStringMap
&map
) { return A
== map
.arch
; });
147 if (result
== std::end(arch_names
))
149 return result
->arch_name
;
152 const char *CudaArchToVirtualArchString(CudaArch A
) {
153 auto result
= std::find_if(
154 std::begin(arch_names
), std::end(arch_names
),
155 [A
](const CudaArchToStringMap
&map
) { return A
== map
.arch
; });
156 if (result
== std::end(arch_names
))
158 return result
->virtual_arch_name
;
161 CudaArch
StringToCudaArch(llvm::StringRef S
) {
162 auto result
= std::find_if(
163 std::begin(arch_names
), std::end(arch_names
),
164 [S
](const CudaArchToStringMap
&map
) { return S
== map
.arch_name
; });
165 if (result
== std::end(arch_names
))
166 return CudaArch::UNKNOWN
;
170 CudaVersion
MinVersionForCudaArch(CudaArch A
) {
171 if (A
== CudaArch::UNKNOWN
)
172 return CudaVersion::UNKNOWN
;
174 // AMD GPUs do not depend on CUDA versions.
176 return CudaVersion::CUDA_70
;
179 case CudaArch::SM_20
:
180 case CudaArch::SM_21
:
181 case CudaArch::SM_30
:
182 case CudaArch::SM_32
:
183 case CudaArch::SM_35
:
184 case CudaArch::SM_37
:
185 case CudaArch::SM_50
:
186 case CudaArch::SM_52
:
187 case CudaArch::SM_53
:
188 return CudaVersion::CUDA_70
;
189 case CudaArch::SM_60
:
190 case CudaArch::SM_61
:
191 case CudaArch::SM_62
:
192 return CudaVersion::CUDA_80
;
193 case CudaArch::SM_70
:
194 return CudaVersion::CUDA_90
;
195 case CudaArch::SM_72
:
196 return CudaVersion::CUDA_91
;
197 case CudaArch::SM_75
:
198 return CudaVersion::CUDA_100
;
199 case CudaArch::SM_80
:
200 return CudaVersion::CUDA_110
;
201 case CudaArch::SM_86
:
202 return CudaVersion::CUDA_111
;
203 case CudaArch::SM_87
:
204 return CudaVersion::CUDA_114
;
205 case CudaArch::SM_89
:
206 case CudaArch::SM_90
:
207 return CudaVersion::CUDA_118
;
209 llvm_unreachable("invalid enum");
213 CudaVersion
MaxVersionForCudaArch(CudaArch A
) {
214 // AMD GPUs do not depend on CUDA versions.
216 return CudaVersion::NEW
;
219 case CudaArch::UNKNOWN
:
220 return CudaVersion::UNKNOWN
;
221 case CudaArch::SM_20
:
222 case CudaArch::SM_21
:
223 return CudaVersion::CUDA_80
;
224 case CudaArch::SM_30
:
225 case CudaArch::SM_32
:
226 return CudaVersion::CUDA_102
;
227 case CudaArch::SM_35
:
228 case CudaArch::SM_37
:
229 return CudaVersion::CUDA_118
;
231 return CudaVersion::NEW
;
235 bool CudaFeatureEnabled(llvm::VersionTuple Version
, CudaFeature Feature
) {
236 return CudaFeatureEnabled(ToCudaVersion(Version
), Feature
);
239 bool CudaFeatureEnabled(CudaVersion Version
, CudaFeature Feature
) {
241 case CudaFeature::CUDA_USES_NEW_LAUNCH
:
242 return Version
>= CudaVersion::CUDA_92
;
243 case CudaFeature::CUDA_USES_FATBIN_REGISTER_END
:
244 return Version
>= CudaVersion::CUDA_101
;
246 llvm_unreachable("Unknown CUDA feature.");