Joseph Huber 9e7aab951f
[CUDA] Rename SM_32 to SM_32_ to work around AIX headers (#88779)
Summary:
AIX headers define this, so we need to work around it. In the future
this will be removed but for now we should just rename it to avoid these
issues.
2024-04-16 07:43:13 -05:00

258 lines
7.2 KiB
C++

#include "clang/Basic/Cuda.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
namespace clang {
struct CudaVersionMapEntry {
const char *Name;
CudaVersion Version;
llvm::VersionTuple TVersion;
};
#define CUDA_ENTRY(major, minor) \
{ \
#major "." #minor, CudaVersion::CUDA_##major##minor, \
llvm::VersionTuple(major, minor) \
}
static const CudaVersionMapEntry CudaNameVersionMap[] = {
CUDA_ENTRY(7, 0),
CUDA_ENTRY(7, 5),
CUDA_ENTRY(8, 0),
CUDA_ENTRY(9, 0),
CUDA_ENTRY(9, 1),
CUDA_ENTRY(9, 2),
CUDA_ENTRY(10, 0),
CUDA_ENTRY(10, 1),
CUDA_ENTRY(10, 2),
CUDA_ENTRY(11, 0),
CUDA_ENTRY(11, 1),
CUDA_ENTRY(11, 2),
CUDA_ENTRY(11, 3),
CUDA_ENTRY(11, 4),
CUDA_ENTRY(11, 5),
CUDA_ENTRY(11, 6),
CUDA_ENTRY(11, 7),
CUDA_ENTRY(11, 8),
CUDA_ENTRY(12, 0),
CUDA_ENTRY(12, 1),
CUDA_ENTRY(12, 2),
CUDA_ENTRY(12, 3),
{"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())},
{"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone.
};
#undef CUDA_ENTRY
const char *CudaVersionToString(CudaVersion V) {
for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
if (I->Version == V)
return I->Name;
return CudaVersionToString(CudaVersion::UNKNOWN);
}
CudaVersion CudaStringToVersion(const llvm::Twine &S) {
std::string VS = S.str();
for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
if (I->Name == VS)
return I->Version;
return CudaVersion::UNKNOWN;
}
CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
if (I->TVersion == Version)
return I->Version;
return CudaVersion::UNKNOWN;
}
namespace {
struct CudaArchToStringMap {
CudaArch arch;
const char *arch_name;
const char *virtual_arch_name;
};
} // namespace
#define SM2(sm, ca) \
{ CudaArch::SM_##sm, "sm_" #sm, ca }
#define SM(sm) SM2(sm, "compute_" #sm)
#define GFX(gpu) \
{ CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
static const CudaArchToStringMap arch_names[] = {
// clang-format off
{CudaArch::UNUSED, "", ""},
SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
SM(30), {CudaArch::SM_32_, "sm_32", "compute_32"}, SM(35), SM(37), // Kepler
SM(50), SM(52), SM(53), // Maxwell
SM(60), SM(61), SM(62), // Pascal
SM(70), SM(72), // Volta
SM(75), // Turing
SM(80), SM(86), // Ampere
SM(87), // Jetson/Drive AGX Orin
SM(89), // Ada Lovelace
SM(90), // Hopper
SM(90a), // Hopper
GFX(600), // gfx600
GFX(601), // gfx601
GFX(602), // gfx602
GFX(700), // gfx700
GFX(701), // gfx701
GFX(702), // gfx702
GFX(703), // gfx703
GFX(704), // gfx704
GFX(705), // gfx705
GFX(801), // gfx801
GFX(802), // gfx802
GFX(803), // gfx803
GFX(805), // gfx805
GFX(810), // gfx810
GFX(900), // gfx900
GFX(902), // gfx902
GFX(904), // gfx903
GFX(906), // gfx906
GFX(908), // gfx908
GFX(909), // gfx909
GFX(90a), // gfx90a
GFX(90c), // gfx90c
GFX(940), // gfx940
GFX(941), // gfx941
GFX(942), // gfx942
GFX(1010), // gfx1010
GFX(1011), // gfx1011
GFX(1012), // gfx1012
GFX(1013), // gfx1013
GFX(1030), // gfx1030
GFX(1031), // gfx1031
GFX(1032), // gfx1032
GFX(1033), // gfx1033
GFX(1034), // gfx1034
GFX(1035), // gfx1035
GFX(1036), // gfx1036
GFX(1100), // gfx1100
GFX(1101), // gfx1101
GFX(1102), // gfx1102
GFX(1103), // gfx1103
GFX(1150), // gfx1150
GFX(1151), // gfx1151
GFX(1200), // gfx1200
GFX(1201), // gfx1201
{CudaArch::Generic, "generic", ""},
// clang-format on
};
#undef SM
#undef SM2
#undef GFX
const char *CudaArchToString(CudaArch A) {
auto result = std::find_if(
std::begin(arch_names), std::end(arch_names),
[A](const CudaArchToStringMap &map) { return A == map.arch; });
if (result == std::end(arch_names))
return "unknown";
return result->arch_name;
}
const char *CudaArchToVirtualArchString(CudaArch A) {
auto result = std::find_if(
std::begin(arch_names), std::end(arch_names),
[A](const CudaArchToStringMap &map) { return A == map.arch; });
if (result == std::end(arch_names))
return "unknown";
return result->virtual_arch_name;
}
CudaArch StringToCudaArch(llvm::StringRef S) {
auto result = std::find_if(
std::begin(arch_names), std::end(arch_names),
[S](const CudaArchToStringMap &map) { return S == map.arch_name; });
if (result == std::end(arch_names))
return CudaArch::UNKNOWN;
return result->arch;
}
CudaVersion MinVersionForCudaArch(CudaArch A) {
if (A == CudaArch::UNKNOWN)
return CudaVersion::UNKNOWN;
// AMD GPUs do not depend on CUDA versions.
if (IsAMDGpuArch(A))
return CudaVersion::CUDA_70;
switch (A) {
case CudaArch::SM_20:
case CudaArch::SM_21:
case CudaArch::SM_30:
case CudaArch::SM_32_:
case CudaArch::SM_35:
case CudaArch::SM_37:
case CudaArch::SM_50:
case CudaArch::SM_52:
case CudaArch::SM_53:
return CudaVersion::CUDA_70;
case CudaArch::SM_60:
case CudaArch::SM_61:
case CudaArch::SM_62:
return CudaVersion::CUDA_80;
case CudaArch::SM_70:
return CudaVersion::CUDA_90;
case CudaArch::SM_72:
return CudaVersion::CUDA_91;
case CudaArch::SM_75:
return CudaVersion::CUDA_100;
case CudaArch::SM_80:
return CudaVersion::CUDA_110;
case CudaArch::SM_86:
return CudaVersion::CUDA_111;
case CudaArch::SM_87:
return CudaVersion::CUDA_114;
case CudaArch::SM_89:
case CudaArch::SM_90:
return CudaVersion::CUDA_118;
case CudaArch::SM_90a:
return CudaVersion::CUDA_120;
default:
llvm_unreachable("invalid enum");
}
}
CudaVersion MaxVersionForCudaArch(CudaArch A) {
// AMD GPUs do not depend on CUDA versions.
if (IsAMDGpuArch(A))
return CudaVersion::NEW;
switch (A) {
case CudaArch::UNKNOWN:
return CudaVersion::UNKNOWN;
case CudaArch::SM_20:
case CudaArch::SM_21:
return CudaVersion::CUDA_80;
case CudaArch::SM_30:
case CudaArch::SM_32_:
return CudaVersion::CUDA_102;
case CudaArch::SM_35:
case CudaArch::SM_37:
return CudaVersion::CUDA_118;
default:
return CudaVersion::NEW;
}
}
bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
}
bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
switch (Feature) {
case CudaFeature::CUDA_USES_NEW_LAUNCH:
return Version >= CudaVersion::CUDA_92;
case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
return Version >= CudaVersion::CUDA_101;
}
llvm_unreachable("Unknown CUDA feature.");
}
} // namespace clang