Path: blob/main/contrib/llvm-project/clang/lib/Basic/Cuda.cpp
35232 views
#include "clang/Basic/Cuda.h"12#include "llvm/ADT/StringRef.h"3#include "llvm/ADT/Twine.h"4#include "llvm/Support/ErrorHandling.h"5#include "llvm/Support/VersionTuple.h"67namespace clang {89struct CudaVersionMapEntry {10const char *Name;11CudaVersion Version;12llvm::VersionTuple TVersion;13};14#define CUDA_ENTRY(major, minor) \15{ \16#major "." #minor, CudaVersion::CUDA_##major##minor, \17llvm::VersionTuple(major, minor) \18}1920static const CudaVersionMapEntry CudaNameVersionMap[] = {21CUDA_ENTRY(7, 0),22CUDA_ENTRY(7, 5),23CUDA_ENTRY(8, 0),24CUDA_ENTRY(9, 0),25CUDA_ENTRY(9, 1),26CUDA_ENTRY(9, 2),27CUDA_ENTRY(10, 0),28CUDA_ENTRY(10, 1),29CUDA_ENTRY(10, 2),30CUDA_ENTRY(11, 0),31CUDA_ENTRY(11, 1),32CUDA_ENTRY(11, 2),33CUDA_ENTRY(11, 3),34CUDA_ENTRY(11, 4),35CUDA_ENTRY(11, 5),36CUDA_ENTRY(11, 6),37CUDA_ENTRY(11, 7),38CUDA_ENTRY(11, 8),39CUDA_ENTRY(12, 0),40CUDA_ENTRY(12, 1),41CUDA_ENTRY(12, 2),42CUDA_ENTRY(12, 3),43CUDA_ENTRY(12, 4),44CUDA_ENTRY(12, 5),45{"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())},46{"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone.47};48#undef CUDA_ENTRY4950const char *CudaVersionToString(CudaVersion V) {51for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)52if (I->Version == V)53return I->Name;5455return CudaVersionToString(CudaVersion::UNKNOWN);56}5758CudaVersion CudaStringToVersion(const llvm::Twine &S) {59std::string VS = S.str();60for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)61if (I->Name == VS)62return I->Version;63return CudaVersion::UNKNOWN;64}6566CudaVersion ToCudaVersion(llvm::VersionTuple Version) {67for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)68if (I->TVersion == Version)69return I->Version;70return CudaVersion::UNKNOWN;71}7273namespace {74struct OffloadArchToStringMap {75OffloadArch arch;76const char *arch_name;77const char *virtual_arch_name;78};79} // namespace8081#define SM2(sm, ca) {OffloadArch::SM_##sm, "sm_" #sm, ca}82#define SM(sm) SM2(sm, "compute_" #sm)83#define GFX(gpu) {OffloadArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn"}84static const OffloadArchToStringMap arch_names[] = {85// clang-format off86{OffloadArch::UNUSED, "", ""},87SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi88SM(30), {OffloadArch::SM_32_, "sm_32", "compute_32"}, SM(35), SM(37), // Kepler89SM(50), SM(52), SM(53), // Maxwell90SM(60), SM(61), SM(62), // Pascal91SM(70), SM(72), // Volta92SM(75), // Turing93SM(80), SM(86), // Ampere94SM(87), // Jetson/Drive AGX Orin95SM(89), // Ada Lovelace96SM(90), // Hopper97SM(90a), // Hopper98GFX(600), // gfx60099GFX(601), // gfx601100GFX(602), // gfx602101GFX(700), // gfx700102GFX(701), // gfx701103GFX(702), // gfx702104GFX(703), // gfx703105GFX(704), // gfx704106GFX(705), // gfx705107GFX(801), // gfx801108GFX(802), // gfx802109GFX(803), // gfx803110GFX(805), // gfx805111GFX(810), // gfx810112{OffloadArch::GFX9_GENERIC, "gfx9-generic", "compute_amdgcn"},113GFX(900), // gfx900114GFX(902), // gfx902115GFX(904), // gfx903116GFX(906), // gfx906117GFX(908), // gfx908118GFX(909), // gfx909119GFX(90a), // gfx90a120GFX(90c), // gfx90c121GFX(940), // gfx940122GFX(941), // gfx941123GFX(942), // gfx942124{OffloadArch::GFX10_1_GENERIC, "gfx10-1-generic", "compute_amdgcn"},125GFX(1010), // gfx1010126GFX(1011), // gfx1011127GFX(1012), // gfx1012128GFX(1013), // gfx1013129{OffloadArch::GFX10_3_GENERIC, "gfx10-3-generic", "compute_amdgcn"},130GFX(1030), // gfx1030131GFX(1031), // gfx1031132GFX(1032), // gfx1032133GFX(1033), // gfx1033134GFX(1034), // gfx1034135GFX(1035), // gfx1035136GFX(1036), // gfx1036137{OffloadArch::GFX11_GENERIC, "gfx11-generic", "compute_amdgcn"},138GFX(1100), // gfx1100139GFX(1101), // gfx1101140GFX(1102), // gfx1102141GFX(1103), // gfx1103142GFX(1150), // gfx1150143GFX(1151), // gfx1151144GFX(1152), // gfx1152145{OffloadArch::GFX12_GENERIC, "gfx12-generic", "compute_amdgcn"},146GFX(1200), // gfx1200147GFX(1201), // gfx1201148{OffloadArch::AMDGCNSPIRV, "amdgcnspirv", "compute_amdgcn"},149{OffloadArch::Generic, "generic", ""},150// clang-format on151};152#undef SM153#undef SM2154#undef GFX155156const char *OffloadArchToString(OffloadArch A) {157auto result = std::find_if(158std::begin(arch_names), std::end(arch_names),159[A](const OffloadArchToStringMap &map) { return A == map.arch; });160if (result == std::end(arch_names))161return "unknown";162return result->arch_name;163}164165const char *OffloadArchToVirtualArchString(OffloadArch A) {166auto result = std::find_if(167std::begin(arch_names), std::end(arch_names),168[A](const OffloadArchToStringMap &map) { return A == map.arch; });169if (result == std::end(arch_names))170return "unknown";171return result->virtual_arch_name;172}173174OffloadArch StringToOffloadArch(llvm::StringRef S) {175auto result = std::find_if(176std::begin(arch_names), std::end(arch_names),177[S](const OffloadArchToStringMap &map) { return S == map.arch_name; });178if (result == std::end(arch_names))179return OffloadArch::UNKNOWN;180return result->arch;181}182183CudaVersion MinVersionForOffloadArch(OffloadArch A) {184if (A == OffloadArch::UNKNOWN)185return CudaVersion::UNKNOWN;186187// AMD GPUs do not depend on CUDA versions.188if (IsAMDOffloadArch(A))189return CudaVersion::CUDA_70;190191switch (A) {192case OffloadArch::SM_20:193case OffloadArch::SM_21:194case OffloadArch::SM_30:195case OffloadArch::SM_32_:196case OffloadArch::SM_35:197case OffloadArch::SM_37:198case OffloadArch::SM_50:199case OffloadArch::SM_52:200case OffloadArch::SM_53:201return CudaVersion::CUDA_70;202case OffloadArch::SM_60:203case OffloadArch::SM_61:204case OffloadArch::SM_62:205return CudaVersion::CUDA_80;206case OffloadArch::SM_70:207return CudaVersion::CUDA_90;208case OffloadArch::SM_72:209return CudaVersion::CUDA_91;210case OffloadArch::SM_75:211return CudaVersion::CUDA_100;212case OffloadArch::SM_80:213return CudaVersion::CUDA_110;214case OffloadArch::SM_86:215return CudaVersion::CUDA_111;216case OffloadArch::SM_87:217return CudaVersion::CUDA_114;218case OffloadArch::SM_89:219case OffloadArch::SM_90:220return CudaVersion::CUDA_118;221case OffloadArch::SM_90a:222return CudaVersion::CUDA_120;223default:224llvm_unreachable("invalid enum");225}226}227228CudaVersion MaxVersionForOffloadArch(OffloadArch A) {229// AMD GPUs do not depend on CUDA versions.230if (IsAMDOffloadArch(A))231return CudaVersion::NEW;232233switch (A) {234case OffloadArch::UNKNOWN:235return CudaVersion::UNKNOWN;236case OffloadArch::SM_20:237case OffloadArch::SM_21:238return CudaVersion::CUDA_80;239case OffloadArch::SM_30:240case OffloadArch::SM_32_:241return CudaVersion::CUDA_102;242case OffloadArch::SM_35:243case OffloadArch::SM_37:244return CudaVersion::CUDA_118;245default:246return CudaVersion::NEW;247}248}249250bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {251return CudaFeatureEnabled(ToCudaVersion(Version), Feature);252}253254bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {255switch (Feature) {256case CudaFeature::CUDA_USES_NEW_LAUNCH:257return Version >= CudaVersion::CUDA_92;258case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:259return Version >= CudaVersion::CUDA_101;260}261llvm_unreachable("Unknown CUDA feature.");262}263} // namespace clang264265266