162907617SJustin Lebar #include "clang/Basic/Cuda.h"
262907617SJustin Lebar
362907617SJustin Lebar #include "llvm/ADT/StringRef.h"
462907617SJustin Lebar #include "llvm/ADT/StringSwitch.h"
512fefeefSArtem Belevich #include "llvm/ADT/Twine.h"
6d9bc485cSJustin Lebar #include "llvm/Support/ErrorHandling.h"
78fa28a0dSArtem Belevich #include "llvm/Support/VersionTuple.h"
862907617SJustin Lebar
962907617SJustin Lebar namespace clang {
1062907617SJustin Lebar
CudaVersionToString(CudaVersion V)1162907617SJustin Lebar const char *CudaVersionToString(CudaVersion V) {
1262907617SJustin Lebar switch (V) {
1362907617SJustin Lebar case CudaVersion::UNKNOWN:
1462907617SJustin Lebar return "unknown";
1562907617SJustin Lebar case CudaVersion::CUDA_70:
1662907617SJustin Lebar return "7.0";
1762907617SJustin Lebar case CudaVersion::CUDA_75:
1862907617SJustin Lebar return "7.5";
1962907617SJustin Lebar case CudaVersion::CUDA_80:
2062907617SJustin Lebar return "8.0";
218af4e23dSArtem Belevich case CudaVersion::CUDA_90:
228af4e23dSArtem Belevich return "9.0";
23fbc56a90SArtem Belevich case CudaVersion::CUDA_91:
24fbc56a90SArtem Belevich return "9.1";
253cce3077SArtem Belevich case CudaVersion::CUDA_92:
263cce3077SArtem Belevich return "9.2";
2744ecb0e3SArtem Belevich case CudaVersion::CUDA_100:
2844ecb0e3SArtem Belevich return "10.0";
294071763bSArtem Belevich case CudaVersion::CUDA_101:
304071763bSArtem Belevich return "10.1";
31a9627b7eSArtem Belevich case CudaVersion::CUDA_102:
32a9627b7eSArtem Belevich return "10.2";
33a9627b7eSArtem Belevich case CudaVersion::CUDA_110:
34a9627b7eSArtem Belevich return "11.0";
352aa01cceSArtem Belevich case CudaVersion::CUDA_111:
362aa01cceSArtem Belevich return "11.1";
372aa01cceSArtem Belevich case CudaVersion::CUDA_112:
382aa01cceSArtem Belevich return "11.2";
3949d982d8SArtem Belevich case CudaVersion::CUDA_113:
4049d982d8SArtem Belevich return "11.3";
4149d982d8SArtem Belevich case CudaVersion::CUDA_114:
4249d982d8SArtem Belevich return "11.4";
437ecec3f0SCarlos Galvez case CudaVersion::CUDA_115:
447ecec3f0SCarlos Galvez return "11.5";
453db8e486SArtem Belevich case CudaVersion::NEW:
463db8e486SArtem Belevich return "";
4762907617SJustin Lebar }
48d9bc485cSJustin Lebar llvm_unreachable("invalid enum");
4962907617SJustin Lebar }
5062907617SJustin Lebar
CudaStringToVersion(const llvm::Twine & S)5112fefeefSArtem Belevich CudaVersion CudaStringToVersion(const llvm::Twine &S) {
5212fefeefSArtem Belevich return llvm::StringSwitch<CudaVersion>(S.str())
538fa28a0dSArtem Belevich .Case("7.0", CudaVersion::CUDA_70)
548fa28a0dSArtem Belevich .Case("7.5", CudaVersion::CUDA_75)
558fa28a0dSArtem Belevich .Case("8.0", CudaVersion::CUDA_80)
568fa28a0dSArtem Belevich .Case("9.0", CudaVersion::CUDA_90)
578fa28a0dSArtem Belevich .Case("9.1", CudaVersion::CUDA_91)
588fa28a0dSArtem Belevich .Case("9.2", CudaVersion::CUDA_92)
594071763bSArtem Belevich .Case("10.0", CudaVersion::CUDA_100)
6012fefeefSArtem Belevich .Case("10.1", CudaVersion::CUDA_101)
61a9627b7eSArtem Belevich .Case("10.2", CudaVersion::CUDA_102)
62a9627b7eSArtem Belevich .Case("11.0", CudaVersion::CUDA_110)
632aa01cceSArtem Belevich .Case("11.1", CudaVersion::CUDA_111)
642aa01cceSArtem Belevich .Case("11.2", CudaVersion::CUDA_112)
6549d982d8SArtem Belevich .Case("11.3", CudaVersion::CUDA_113)
6649d982d8SArtem Belevich .Case("11.4", CudaVersion::CUDA_114)
677ecec3f0SCarlos Galvez .Case("11.5", CudaVersion::CUDA_115)
6812fefeefSArtem Belevich .Default(CudaVersion::UNKNOWN);
698fa28a0dSArtem Belevich }
708fa28a0dSArtem Belevich
711fcf9247SFangrui Song namespace {
7233386b20SArtem Belevich struct CudaArchToStringMap {
7333386b20SArtem Belevich CudaArch arch;
7433386b20SArtem Belevich const char *arch_name;
7533386b20SArtem Belevich const char *virtual_arch_name;
7633386b20SArtem Belevich };
771fcf9247SFangrui Song } // namespace
7833386b20SArtem Belevich
7933386b20SArtem Belevich #define SM2(sm, ca) \
8033386b20SArtem Belevich { CudaArch::SM_##sm, "sm_" #sm, ca }
8133386b20SArtem Belevich #define SM(sm) SM2(sm, "compute_" #sm)
8233386b20SArtem Belevich #define GFX(gpu) \
8333386b20SArtem Belevich { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
841fcf9247SFangrui Song static const CudaArchToStringMap arch_names[] = {
8533386b20SArtem Belevich // clang-format off
86cbd420c5SYaxun (Sam) Liu {CudaArch::UNUSED, "", ""},
8733386b20SArtem Belevich SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
8833386b20SArtem Belevich SM(30), SM(32), SM(35), SM(37), // Kepler
8933386b20SArtem Belevich SM(50), SM(52), SM(53), // Maxwell
9033386b20SArtem Belevich SM(60), SM(61), SM(62), // Pascal
9133386b20SArtem Belevich SM(70), SM(72), // Volta
9233386b20SArtem Belevich SM(75), // Turing
932aa01cceSArtem Belevich SM(80), SM(86), // Ampere
945ad202ceSTony GFX(600), // gfx600
955ad202ceSTony GFX(601), // gfx601
965ad202ceSTony GFX(602), // gfx602
975ad202ceSTony GFX(700), // gfx700
985ad202ceSTony GFX(701), // gfx701
995ad202ceSTony GFX(702), // gfx702
1005ad202ceSTony GFX(703), // gfx703
1015ad202ceSTony GFX(704), // gfx704
1025ad202ceSTony GFX(705), // gfx705
1035ad202ceSTony GFX(801), // gfx801
1045ad202ceSTony GFX(802), // gfx802
1055ad202ceSTony GFX(803), // gfx803
1065ad202ceSTony GFX(805), // gfx805
1075ad202ceSTony GFX(810), // gfx810
1085ad202ceSTony GFX(900), // gfx900
1095ad202ceSTony GFX(902), // gfx902
1105ad202ceSTony GFX(904), // gfx903
1115ad202ceSTony GFX(906), // gfx906
1125ad202ceSTony GFX(908), // gfx908
1135ad202ceSTony GFX(909), // gfx909
114a8d9d507SStanislav Mekhanoshin GFX(90a), // gfx90a
1155ad202ceSTony GFX(90c), // gfx90c
1162e2e64dfSStanislav Mekhanoshin GFX(940), // gfx940
1175ad202ceSTony GFX(1010), // gfx1010
1185ad202ceSTony GFX(1011), // gfx1011
1195ad202ceSTony GFX(1012), // gfx1012
120294efbbdSBrendon Cahoon GFX(1013), // gfx1013
1215ad202ceSTony GFX(1030), // gfx1030
1225ad202ceSTony GFX(1031), // gfx1031
1235ad202ceSTony GFX(1032), // gfx1032
1245ad202ceSTony GFX(1033), // gfx1033
125464e4dc5SAakanksha Patil GFX(1034), // gfx1034
1263453f3ddSAakanksha Patil GFX(1035), // gfx1035
12784069581SAakanksha GFX(1036), // gfx1036
1288bdfc73fSJoe Nash GFX(1100), // gfx1100
1298bdfc73fSJoe Nash GFX(1101), // gfx1101
1308bdfc73fSJoe Nash GFX(1102), // gfx1102
1318bdfc73fSJoe Nash GFX(1103), // gfx1103
132a6786cddSYaxun (Sam) Liu {CudaArch::Generic, "generic", ""},
13333386b20SArtem Belevich // clang-format on
13433386b20SArtem Belevich };
13533386b20SArtem Belevich #undef SM
13633386b20SArtem Belevich #undef SM2
13733386b20SArtem Belevich #undef GFX
13833386b20SArtem Belevich
CudaArchToString(CudaArch A)13962907617SJustin Lebar const char *CudaArchToString(CudaArch A) {
14033386b20SArtem Belevich auto result = std::find_if(
14133386b20SArtem Belevich std::begin(arch_names), std::end(arch_names),
14233386b20SArtem Belevich [A](const CudaArchToStringMap &map) { return A == map.arch; });
14333386b20SArtem Belevich if (result == std::end(arch_names))
14462907617SJustin Lebar return "unknown";
14533386b20SArtem Belevich return result->arch_name;
14662907617SJustin Lebar }
14733386b20SArtem Belevich
CudaArchToVirtualArchString(CudaArch A)14833386b20SArtem Belevich const char *CudaArchToVirtualArchString(CudaArch A) {
14933386b20SArtem Belevich auto result = std::find_if(
15033386b20SArtem Belevich std::begin(arch_names), std::end(arch_names),
15133386b20SArtem Belevich [A](const CudaArchToStringMap &map) { return A == map.arch; });
15233386b20SArtem Belevich if (result == std::end(arch_names))
15333386b20SArtem Belevich return "unknown";
15433386b20SArtem Belevich return result->virtual_arch_name;
15562907617SJustin Lebar }
15662907617SJustin Lebar
StringToCudaArch(llvm::StringRef S)15762907617SJustin Lebar CudaArch StringToCudaArch(llvm::StringRef S) {
15833386b20SArtem Belevich auto result = std::find_if(
15933386b20SArtem Belevich std::begin(arch_names), std::end(arch_names),
16033386b20SArtem Belevich [S](const CudaArchToStringMap &map) { return S == map.arch_name; });
16133386b20SArtem Belevich if (result == std::end(arch_names))
16233386b20SArtem Belevich return CudaArch::UNKNOWN;
16333386b20SArtem Belevich return result->arch;
16462907617SJustin Lebar }
16562907617SJustin Lebar
MinVersionForCudaArch(CudaArch A)16662907617SJustin Lebar CudaVersion MinVersionForCudaArch(CudaArch A) {
16733386b20SArtem Belevich if (A == CudaArch::UNKNOWN)
16862907617SJustin Lebar return CudaVersion::UNKNOWN;
16933386b20SArtem Belevich
17033386b20SArtem Belevich // AMD GPUs do not depend on CUDA versions.
17133386b20SArtem Belevich if (IsAMDGpuArch(A))
17233386b20SArtem Belevich return CudaVersion::CUDA_70;
17333386b20SArtem Belevich
17433386b20SArtem Belevich switch (A) {
17562907617SJustin Lebar case CudaArch::SM_20:
17662907617SJustin Lebar case CudaArch::SM_21:
17762907617SJustin Lebar case CudaArch::SM_30:
17862907617SJustin Lebar case CudaArch::SM_32:
17962907617SJustin Lebar case CudaArch::SM_35:
18062907617SJustin Lebar case CudaArch::SM_37:
18162907617SJustin Lebar case CudaArch::SM_50:
18262907617SJustin Lebar case CudaArch::SM_52:
18362907617SJustin Lebar case CudaArch::SM_53:
18462907617SJustin Lebar return CudaVersion::CUDA_70;
18562907617SJustin Lebar case CudaArch::SM_60:
18662907617SJustin Lebar case CudaArch::SM_61:
18762907617SJustin Lebar case CudaArch::SM_62:
18862907617SJustin Lebar return CudaVersion::CUDA_80;
1898af4e23dSArtem Belevich case CudaArch::SM_70:
1908af4e23dSArtem Belevich return CudaVersion::CUDA_90;
191fbc56a90SArtem Belevich case CudaArch::SM_72:
192fbc56a90SArtem Belevich return CudaVersion::CUDA_91;
19344ecb0e3SArtem Belevich case CudaArch::SM_75:
19444ecb0e3SArtem Belevich return CudaVersion::CUDA_100;
195a9627b7eSArtem Belevich case CudaArch::SM_80:
196a9627b7eSArtem Belevich return CudaVersion::CUDA_110;
1972aa01cceSArtem Belevich case CudaArch::SM_86:
1982aa01cceSArtem Belevich return CudaVersion::CUDA_111;
19933386b20SArtem Belevich default:
200d9bc485cSJustin Lebar llvm_unreachable("invalid enum");
20162907617SJustin Lebar }
20233386b20SArtem Belevich }
20362907617SJustin Lebar
MaxVersionForCudaArch(CudaArch A)204066494d8SJustin Lebar CudaVersion MaxVersionForCudaArch(CudaArch A) {
20533386b20SArtem Belevich // AMD GPUs do not depend on CUDA versions.
20633386b20SArtem Belevich if (IsAMDGpuArch(A))
2073db8e486SArtem Belevich return CudaVersion::NEW;
20833386b20SArtem Belevich
209066494d8SJustin Lebar switch (A) {
210066494d8SJustin Lebar case CudaArch::UNKNOWN:
211066494d8SJustin Lebar return CudaVersion::UNKNOWN;
212066494d8SJustin Lebar case CudaArch::SM_20:
213066494d8SJustin Lebar case CudaArch::SM_21:
214066494d8SJustin Lebar return CudaVersion::CUDA_80;
21549d982d8SArtem Belevich case CudaArch::SM_30:
21649d982d8SArtem Belevich return CudaVersion::CUDA_110;
217066494d8SJustin Lebar default:
2183db8e486SArtem Belevich return CudaVersion::NEW;
219066494d8SJustin Lebar }
220066494d8SJustin Lebar }
221066494d8SJustin Lebar
ToCudaVersion(llvm::VersionTuple Version)222b952d799SMichael Liao CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
223*06decd0bSKazu Hirata int IVer = Version.getMajor() * 10 + Version.getMinor().value_or(0);
2248fa28a0dSArtem Belevich switch(IVer) {
2258fa28a0dSArtem Belevich case 70:
2268fa28a0dSArtem Belevich return CudaVersion::CUDA_70;
2278fa28a0dSArtem Belevich case 75:
2288fa28a0dSArtem Belevich return CudaVersion::CUDA_75;
2298fa28a0dSArtem Belevich case 80:
2308fa28a0dSArtem Belevich return CudaVersion::CUDA_80;
2318fa28a0dSArtem Belevich case 90:
2328fa28a0dSArtem Belevich return CudaVersion::CUDA_90;
2338fa28a0dSArtem Belevich case 91:
2348fa28a0dSArtem Belevich return CudaVersion::CUDA_91;
2358fa28a0dSArtem Belevich case 92:
2368fa28a0dSArtem Belevich return CudaVersion::CUDA_92;
2378fa28a0dSArtem Belevich case 100:
2388fa28a0dSArtem Belevich return CudaVersion::CUDA_100;
2394071763bSArtem Belevich case 101:
2404071763bSArtem Belevich return CudaVersion::CUDA_101;
2418c635ba4SArtem Belevich case 102:
2428c635ba4SArtem Belevich return CudaVersion::CUDA_102;
2438c635ba4SArtem Belevich case 110:
2448c635ba4SArtem Belevich return CudaVersion::CUDA_110;
2452aa01cceSArtem Belevich case 111:
2462aa01cceSArtem Belevich return CudaVersion::CUDA_111;
2472aa01cceSArtem Belevich case 112:
2482aa01cceSArtem Belevich return CudaVersion::CUDA_112;
24949d982d8SArtem Belevich case 113:
25049d982d8SArtem Belevich return CudaVersion::CUDA_113;
25149d982d8SArtem Belevich case 114:
25249d982d8SArtem Belevich return CudaVersion::CUDA_114;
2537ecec3f0SCarlos Galvez case 115:
2547ecec3f0SCarlos Galvez return CudaVersion::CUDA_115;
2558fa28a0dSArtem Belevich default:
2568fa28a0dSArtem Belevich return CudaVersion::UNKNOWN;
2578fa28a0dSArtem Belevich }
2588fa28a0dSArtem Belevich }
2598fa28a0dSArtem Belevich
CudaFeatureEnabled(llvm::VersionTuple Version,CudaFeature Feature)2608fa28a0dSArtem Belevich bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
2618fa28a0dSArtem Belevich return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
2628fa28a0dSArtem Belevich }
2638fa28a0dSArtem Belevich
CudaFeatureEnabled(CudaVersion Version,CudaFeature Feature)2648fa28a0dSArtem Belevich bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
2658fa28a0dSArtem Belevich switch (Feature) {
2668fa28a0dSArtem Belevich case CudaFeature::CUDA_USES_NEW_LAUNCH:
2678fa28a0dSArtem Belevich return Version >= CudaVersion::CUDA_92;
2684071763bSArtem Belevich case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
2694071763bSArtem Belevich return Version >= CudaVersion::CUDA_101;
2708fa28a0dSArtem Belevich }
2718fa28a0dSArtem Belevich llvm_unreachable("Unknown CUDA feature.");
2728fa28a0dSArtem Belevich }
27362907617SJustin Lebar } // namespace clang
274