clang: Store vendor GPU kinds in OffloadArch instead of re-listing GPUs (#213362)
OffloadArch was a flat enum that hand-duplicated every AMDGPU and NVPTX target, plus a few edge cases. This was yet another place that needed updating every time a new target is added, which should now be avoided. Replace with a tagged union-like scheme. Co-authored-by: Claude (Claude-Opus-4.8) <noreply@anthropic.com>
This commit is contained in:
parent
b94b699857
commit
3c3a18e239
14 changed files with 304 additions and 381 deletions
|
|
@ -10,161 +10,121 @@
|
|||
#define LLVM_CLANG_BASIC_OFFLOADARCH_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
|
||||
namespace llvm {
|
||||
class Triple;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
namespace NVPTX {
|
||||
enum GPUKind : uint8_t;
|
||||
}
|
||||
namespace AMDGPU {
|
||||
enum GPUKind : uint8_t;
|
||||
}
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
enum class OffloadArch {
|
||||
Unused,
|
||||
Unknown,
|
||||
// TODO: Deprecate and remove GPU architectures older than sm_52.
|
||||
SM_20,
|
||||
SM_21,
|
||||
SM_30,
|
||||
// This has a name conflict with sys/mac.h on AIX, rename it as a workaround.
|
||||
SM_32_,
|
||||
SM_35,
|
||||
SM_37,
|
||||
SM_50,
|
||||
SM_52,
|
||||
SM_53,
|
||||
SM_60,
|
||||
SM_61,
|
||||
SM_62,
|
||||
SM_70,
|
||||
SM_72,
|
||||
SM_75,
|
||||
SM_80,
|
||||
SM_86,
|
||||
SM_87,
|
||||
SM_88,
|
||||
SM_89,
|
||||
SM_90,
|
||||
SM_90a,
|
||||
SM_100,
|
||||
SM_100a,
|
||||
SM_100f,
|
||||
SM_101,
|
||||
SM_101a,
|
||||
SM_101f,
|
||||
SM_103,
|
||||
SM_103a,
|
||||
SM_103f,
|
||||
SM_110,
|
||||
SM_110a,
|
||||
SM_110f,
|
||||
SM_120,
|
||||
SM_120a,
|
||||
SM_120f,
|
||||
SM_121,
|
||||
SM_121a,
|
||||
SM_121f,
|
||||
GFX600,
|
||||
GFX601,
|
||||
GFX602,
|
||||
GFX700,
|
||||
GFX701,
|
||||
GFX702,
|
||||
GFX703,
|
||||
GFX704,
|
||||
GFX705,
|
||||
GFX801,
|
||||
GFX802,
|
||||
GFX803,
|
||||
GFX805,
|
||||
GFX810,
|
||||
GFX9_GENERIC,
|
||||
GFX900,
|
||||
GFX902,
|
||||
GFX904,
|
||||
GFX906,
|
||||
GFX908,
|
||||
GFX909,
|
||||
GFX90a,
|
||||
GFX90c,
|
||||
GFX9_4_GENERIC,
|
||||
GFX942,
|
||||
GFX950,
|
||||
GFX10_1_GENERIC,
|
||||
GFX1010,
|
||||
GFX1011,
|
||||
GFX1012,
|
||||
GFX1013,
|
||||
GFX10_3_GENERIC,
|
||||
GFX1030,
|
||||
GFX1031,
|
||||
GFX1032,
|
||||
GFX1033,
|
||||
GFX1034,
|
||||
GFX1035,
|
||||
GFX1036,
|
||||
GFX11_GENERIC,
|
||||
GFX1100,
|
||||
GFX1101,
|
||||
GFX1102,
|
||||
GFX1103,
|
||||
GFX1150,
|
||||
GFX1151,
|
||||
GFX1152,
|
||||
GFX1153,
|
||||
GFX1154,
|
||||
GFX11_7_GENERIC,
|
||||
GFX1170,
|
||||
GFX1171,
|
||||
GFX1172,
|
||||
GFX12_GENERIC,
|
||||
GFX1200,
|
||||
GFX1201,
|
||||
GFX12_5_GENERIC,
|
||||
GFX1250,
|
||||
GFX1251,
|
||||
GFX13_GENERIC,
|
||||
GFX1310,
|
||||
AMDGCNSPIRV,
|
||||
Generic, // A processor model named 'generic' if the target backend defines a
|
||||
// public one.
|
||||
// Intel CPUs
|
||||
GRANITERAPIDS,
|
||||
// Intel GPUs
|
||||
BMG_G21,
|
||||
LAST = BMG_G21,
|
||||
/// A processor an offloading action can target. This is a tagged handle pairing
|
||||
/// a TargetArch with the matching TargetParser GPU kind; it does not enumerate
|
||||
/// individual GPUs, so new targets are added in the TargetParser data alone.
|
||||
class OffloadArch {
|
||||
public:
|
||||
enum class TargetArch : uint8_t {
|
||||
Unused, // Default-constructed; no architecture bound.
|
||||
Unknown, // A name that matched no known architecture.
|
||||
NVPTX, // Kind is an llvm::NVPTX::GPUKind.
|
||||
AMDGPU, // Kind is an llvm::AMDGPU::GPUKind.
|
||||
SPIRV, // The 'amdgcnspirv' pseudo target.
|
||||
IntelCPU, // Kind is an IntelArch.
|
||||
IntelGPU, // Kind is an IntelArch.
|
||||
Generic, // The 'generic' processor model.
|
||||
};
|
||||
|
||||
CudaDefault = OffloadArch::SM_52,
|
||||
HIPDefault = OffloadArch::GFX906,
|
||||
// Intel architectures, which have no TargetParser list yet.
|
||||
enum class IntelArch : uint32_t {
|
||||
GRANITERAPIDS,
|
||||
BMG_G21,
|
||||
};
|
||||
|
||||
private:
|
||||
// Interpreted according to V; unused for the tagless TargetArch values.
|
||||
uint32_t Kind = 0;
|
||||
TargetArch V = TargetArch::Unused;
|
||||
|
||||
constexpr OffloadArch(TargetArch V, uint32_t Kind) : Kind(Kind), V(V) {}
|
||||
|
||||
public:
|
||||
constexpr OffloadArch() = default;
|
||||
|
||||
static OffloadArch getNVPTX(llvm::NVPTX::GPUKind K) {
|
||||
return {TargetArch::NVPTX, static_cast<uint32_t>(K)};
|
||||
}
|
||||
static OffloadArch getAMDGPU(llvm::AMDGPU::GPUKind K) {
|
||||
return {TargetArch::AMDGPU, static_cast<uint32_t>(K)};
|
||||
}
|
||||
static constexpr OffloadArch getIntel(TargetArch V, IntelArch A) {
|
||||
return {V, static_cast<uint32_t>(A)};
|
||||
}
|
||||
static constexpr OffloadArch getUnused() { return {TargetArch::Unused, 0}; }
|
||||
static constexpr OffloadArch getUnknown() { return {TargetArch::Unknown, 0}; }
|
||||
static constexpr OffloadArch getSPIRV() { return {TargetArch::SPIRV, 0}; }
|
||||
static constexpr OffloadArch getGeneric() { return {TargetArch::Generic, 0}; }
|
||||
|
||||
/// Default architectures used when the user does not specify one.
|
||||
static OffloadArch CudaDefault();
|
||||
static OffloadArch HIPDefault();
|
||||
|
||||
TargetArch targetArch() const { return V; }
|
||||
|
||||
bool isNVPTX() const { return V == TargetArch::NVPTX; }
|
||||
bool isAMDGPU() const { return V == TargetArch::AMDGPU; }
|
||||
bool isSPIRV() const { return V == TargetArch::SPIRV; }
|
||||
bool isIntelCPU() const { return V == TargetArch::IntelCPU; }
|
||||
bool isIntelGPU() const { return V == TargetArch::IntelGPU; }
|
||||
bool isIntel() const { return isIntelCPU() || isIntelGPU(); }
|
||||
bool isGeneric() const { return V == TargetArch::Generic; }
|
||||
bool isUnused() const { return V == TargetArch::Unused; }
|
||||
bool isUnknown() const { return V == TargetArch::Unknown; }
|
||||
|
||||
// Only valid when isNVPTX() / isAMDGPU() respectively.
|
||||
llvm::NVPTX::GPUKind nvptxKind() const {
|
||||
return static_cast<llvm::NVPTX::GPUKind>(Kind);
|
||||
}
|
||||
llvm::AMDGPU::GPUKind amdgpuKind() const {
|
||||
return static_cast<llvm::AMDGPU::GPUKind>(Kind);
|
||||
}
|
||||
|
||||
bool operator==(const OffloadArch &Other) const {
|
||||
return V == Other.V && Kind == Other.Kind;
|
||||
}
|
||||
bool operator!=(const OffloadArch &Other) const { return !(*this == Other); }
|
||||
|
||||
bool operator<(const OffloadArch &Other) const {
|
||||
return std::tie(V, Kind) < std::tie(Other.V, Other.Kind);
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool IsNVIDIAOffloadArch(OffloadArch A) {
|
||||
return A >= OffloadArch::SM_20 && A < OffloadArch::GFX600;
|
||||
}
|
||||
|
||||
static inline bool IsAMDOffloadArch(OffloadArch A) {
|
||||
// Generic processor model is for testing only.
|
||||
return A >= OffloadArch::GFX600 && A < OffloadArch::Generic;
|
||||
}
|
||||
|
||||
static inline bool IsIntelCPUOffloadArch(OffloadArch Arch) {
|
||||
return Arch >= OffloadArch::GRANITERAPIDS && Arch < OffloadArch::BMG_G21;
|
||||
}
|
||||
|
||||
static inline bool IsIntelGPUOffloadArch(OffloadArch Arch) {
|
||||
return Arch >= OffloadArch::BMG_G21 && Arch <= OffloadArch::LAST;
|
||||
}
|
||||
|
||||
static inline bool IsIntelOffloadArch(OffloadArch Arch) {
|
||||
return IsIntelCPUOffloadArch(Arch) || IsIntelGPUOffloadArch(Arch);
|
||||
inline bool IsNVIDIAOffloadArch(OffloadArch A) { return A.isNVPTX(); }
|
||||
inline bool IsAMDOffloadArch(OffloadArch A) {
|
||||
// amdgcnspirv is compiled through the AMDGPU toolchain.
|
||||
return A.isAMDGPU() || A.isSPIRV();
|
||||
}
|
||||
inline bool IsIntelCPUOffloadArch(OffloadArch A) { return A.isIntelCPU(); }
|
||||
inline bool IsIntelGPUOffloadArch(OffloadArch A) { return A.isIntelGPU(); }
|
||||
inline bool IsIntelOffloadArch(OffloadArch A) { return A.isIntel(); }
|
||||
|
||||
const char *OffloadArchToString(OffloadArch A);
|
||||
const char *OffloadArchToVirtualArchString(OffloadArch A);
|
||||
|
||||
// Convert a string to an OffloadArch enum value. Returns
|
||||
// OffloadArch::Unknown if the string is not recognized.
|
||||
// Convert a string to an OffloadArch. Returns an Unknown OffloadArch if the
|
||||
// string is not recognized.
|
||||
OffloadArch StringToOffloadArch(llvm::StringRef S);
|
||||
|
||||
/// Append the canonical names of all NVIDIA and AMDGPU GPUs.
|
||||
void fillValidOffloadArchList(llvm::SmallVectorImpl<llvm::StringRef> &Values);
|
||||
|
||||
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple,
|
||||
OffloadArch ID);
|
||||
|
||||
|
|
@ -173,19 +133,19 @@ llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple,
|
|||
struct BoundArch {
|
||||
llvm::StringRef ArchName;
|
||||
|
||||
/// The parsed offload architecture enum.
|
||||
/// Will be OffloadArch::Unknown if ArchName not recognized.
|
||||
OffloadArch Arch = OffloadArch::Unused;
|
||||
/// The parsed offload architecture.
|
||||
/// Will be an Unknown OffloadArch if ArchName is not recognized.
|
||||
OffloadArch Arch = OffloadArch::getUnused();
|
||||
|
||||
BoundArch() = default;
|
||||
explicit BoundArch(llvm::StringRef Name)
|
||||
: ArchName(Name),
|
||||
Arch(Name.empty() ? OffloadArch::Unknown : StringToOffloadArch(Name)) {}
|
||||
: ArchName(Name), Arch(Name.empty() ? OffloadArch::getUnknown()
|
||||
: StringToOffloadArch(Name)) {}
|
||||
|
||||
BoundArch(llvm::StringRef Name, OffloadArch A) : ArchName(Name), Arch(A) {}
|
||||
|
||||
bool empty() const { return ArchName.empty(); }
|
||||
explicit operator bool() const { return Arch != OffloadArch::Unused; }
|
||||
explicit operator bool() const { return !Arch.isUnused(); }
|
||||
|
||||
bool operator==(const BoundArch &Other) const {
|
||||
return Arch == Other.Arch && ArchName == Other.ArchName;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "clang/Basic/Cuda.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.h"
|
||||
#include <bitset>
|
||||
|
||||
namespace clang {
|
||||
|
|
@ -28,9 +29,9 @@ private:
|
|||
std::string IncludePath;
|
||||
llvm::StringMap<std::string> LibDeviceMap;
|
||||
|
||||
// CUDA architectures for which we have raised an error in
|
||||
// CheckCudaVersionSupportsArch.
|
||||
mutable std::bitset<(int)OffloadArch::LAST> ArchsWithBadVersion;
|
||||
// NVIDIA architectures (indexed by GPUKind) for which we have raised an error
|
||||
// in CheckCudaVersionSupportsArch.
|
||||
mutable std::bitset<llvm::NVPTX::GK_LAST + 1> ArchsWithBadVersion;
|
||||
|
||||
public:
|
||||
CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/VersionTuple.h"
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
|
@ -78,16 +79,16 @@ CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
|
|||
}
|
||||
|
||||
CudaVersion MinVersionForOffloadArch(OffloadArch A) {
|
||||
if (A == OffloadArch::Unknown)
|
||||
if (A.isUnknown())
|
||||
return CudaVersion::UNKNOWN;
|
||||
|
||||
// AMD GPUs do not depend on CUDA versions.
|
||||
if (IsAMDOffloadArch(A))
|
||||
return CudaVersion::CUDA_70;
|
||||
|
||||
switch (A) {
|
||||
switch (A.nvptxKind()) {
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
case OffloadArch::KIND: \
|
||||
case llvm::NVPTX::GK_##KIND: \
|
||||
return CudaVersion::MIN_VER;
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
default:
|
||||
|
|
@ -100,11 +101,12 @@ CudaVersion MaxVersionForOffloadArch(OffloadArch A) {
|
|||
if (IsAMDOffloadArch(A))
|
||||
return CudaVersion::NEW;
|
||||
|
||||
switch (A) {
|
||||
case OffloadArch::Unknown:
|
||||
if (!A.isNVPTX())
|
||||
return CudaVersion::UNKNOWN;
|
||||
|
||||
switch (A.nvptxKind()) {
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
case OffloadArch::KIND: \
|
||||
case llvm::NVPTX::GK_##KIND: \
|
||||
return CudaVersion::MAX_VER;
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
default:
|
||||
|
|
@ -127,33 +129,15 @@ bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
|
|||
}
|
||||
|
||||
unsigned CudaArchToID(OffloadArch Arch) {
|
||||
switch (Arch) {
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
case OffloadArch::KIND: \
|
||||
return SM_ID;
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("invalid NVIDIA GPU architecture");
|
||||
}
|
||||
|
||||
static llvm::NVPTX::GPUKind OffloadArchToNVPTXKind(OffloadArch Arch) {
|
||||
switch (Arch) {
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
case OffloadArch::KIND: \
|
||||
return llvm::NVPTX::GK_##KIND;
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
default:
|
||||
return llvm::NVPTX::GK_NONE;
|
||||
}
|
||||
assert(Arch.isNVPTX() && "invalid NVIDIA GPU architecture");
|
||||
return llvm::NVPTX::getSmVersion(Arch.nvptxKind());
|
||||
}
|
||||
|
||||
bool IsNVIDIAAcceleratedOffloadArch(OffloadArch Arch) {
|
||||
return llvm::NVPTX::isAcceleratedArch(OffloadArchToNVPTXKind(Arch));
|
||||
return Arch.isNVPTX() && llvm::NVPTX::isAcceleratedArch(Arch.nvptxKind());
|
||||
}
|
||||
|
||||
bool IsNVIDIAFamilySpecificOffloadArch(OffloadArch Arch) {
|
||||
return llvm::NVPTX::isFamilySpecificArch(OffloadArchToNVPTXKind(Arch));
|
||||
return Arch.isNVPTX() && llvm::NVPTX::isFamilySpecificArch(Arch.nvptxKind());
|
||||
}
|
||||
} // namespace clang
|
||||
|
|
|
|||
|
|
@ -7,164 +7,101 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
#include "clang/Basic/OffloadArch.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/TargetParser/AMDGPUTargetParser.h"
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace {
|
||||
struct OffloadArchToStringMap {
|
||||
OffloadArch Arch;
|
||||
const char *ArchName;
|
||||
const char *VirtualArchName;
|
||||
};
|
||||
} // namespace
|
||||
OffloadArch OffloadArch::CudaDefault() {
|
||||
return getNVPTX(llvm::NVPTX::parseArch("sm_52"));
|
||||
}
|
||||
|
||||
#define SM(sm) {OffloadArch::SM_##sm, "sm_" #sm, "compute_" #sm}
|
||||
#define GFX(gpu) {OffloadArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn"}
|
||||
static const OffloadArchToStringMap ArchNames[] = {
|
||||
// clang-format off
|
||||
{OffloadArch::Unused, "", ""},
|
||||
SM(20), {OffloadArch::SM_21, "sm_21", "compute_20"}, // Fermi
|
||||
SM(30), {OffloadArch::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(88), // Ampere
|
||||
SM(89), // Ada Lovelace
|
||||
SM(90), // Hopper
|
||||
SM(90a), // Hopper
|
||||
SM(100), // Blackwell
|
||||
SM(100a), // Blackwell
|
||||
SM(100f), // Blackwell
|
||||
SM(101), // Blackwell
|
||||
SM(101a), // Blackwell
|
||||
SM(101f), // Blackwell
|
||||
SM(103), // Blackwell
|
||||
SM(103a), // Blackwell
|
||||
SM(103f), // Blackwell
|
||||
SM(110), // Blackwell
|
||||
SM(110a), // Blackwell
|
||||
SM(110f), // Blackwell
|
||||
SM(120), // Blackwell
|
||||
SM(120a), // Blackwell
|
||||
SM(120f), // Blackwell
|
||||
SM(121), // Blackwell
|
||||
SM(121a), // Blackwell
|
||||
SM(121f), // Blackwell
|
||||
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
|
||||
{OffloadArch::GFX9_GENERIC, "gfx9-generic", "compute_amdgcn"},
|
||||
GFX(900), // gfx900
|
||||
GFX(902), // gfx902
|
||||
GFX(904), // gfx903
|
||||
GFX(906), // gfx906
|
||||
GFX(908), // gfx908
|
||||
GFX(909), // gfx909
|
||||
GFX(90a), // gfx90a
|
||||
GFX(90c), // gfx90c
|
||||
{OffloadArch::GFX9_4_GENERIC, "gfx9-4-generic", "compute_amdgcn"},
|
||||
GFX(942), // gfx942
|
||||
GFX(950), // gfx950
|
||||
{OffloadArch::GFX10_1_GENERIC, "gfx10-1-generic", "compute_amdgcn"},
|
||||
GFX(1010), // gfx1010
|
||||
GFX(1011), // gfx1011
|
||||
GFX(1012), // gfx1012
|
||||
GFX(1013), // gfx1013
|
||||
{OffloadArch::GFX10_3_GENERIC, "gfx10-3-generic", "compute_amdgcn"},
|
||||
GFX(1030), // gfx1030
|
||||
GFX(1031), // gfx1031
|
||||
GFX(1032), // gfx1032
|
||||
GFX(1033), // gfx1033
|
||||
GFX(1034), // gfx1034
|
||||
GFX(1035), // gfx1035
|
||||
GFX(1036), // gfx1036
|
||||
{OffloadArch::GFX11_GENERIC, "gfx11-generic", "compute_amdgcn"},
|
||||
GFX(1100), // gfx1100
|
||||
GFX(1101), // gfx1101
|
||||
GFX(1102), // gfx1102
|
||||
GFX(1103), // gfx1103
|
||||
GFX(1150), // gfx1150
|
||||
GFX(1151), // gfx1151
|
||||
GFX(1152), // gfx1152
|
||||
GFX(1153), // gfx1153
|
||||
GFX(1154), // gfx1154
|
||||
{OffloadArch::GFX11_7_GENERIC, "gfx11-7-generic", "compute_amdgcn"},
|
||||
GFX(1170), // gfx1170
|
||||
GFX(1171), // gfx1171
|
||||
GFX(1172), // gfx1172
|
||||
{OffloadArch::GFX12_GENERIC, "gfx12-generic", "compute_amdgcn"},
|
||||
GFX(1200), // gfx1200
|
||||
GFX(1201), // gfx1201
|
||||
{OffloadArch::GFX12_5_GENERIC, "gfx12-5-generic", "compute_amdgcn"},
|
||||
GFX(1250), // gfx1250
|
||||
GFX(1251), // gfx1251
|
||||
{OffloadArch::GFX13_GENERIC, "gfx13-generic", "compute_amdgcn"},
|
||||
GFX(1310), // gfx1310
|
||||
{OffloadArch::AMDGCNSPIRV, "amdgcnspirv", "compute_amdgcn"},
|
||||
// Intel CPUs
|
||||
{OffloadArch::GRANITERAPIDS, "graniterapids", ""},
|
||||
// Intel GPUS
|
||||
{OffloadArch::BMG_G21, "bmg_g21", ""},
|
||||
{OffloadArch::Generic, "generic", ""},
|
||||
// clang-format on
|
||||
};
|
||||
#undef SM
|
||||
#undef GFX
|
||||
OffloadArch OffloadArch::HIPDefault() {
|
||||
return getAMDGPU(llvm::AMDGPU::parseArchAMDGCN("gfx906"));
|
||||
}
|
||||
|
||||
const char *OffloadArchToString(OffloadArch A) {
|
||||
auto Result =
|
||||
llvm::find_if(ArchNames, [A](const OffloadArchToStringMap &Map) {
|
||||
return A == Map.Arch;
|
||||
});
|
||||
if (Result == std::end(ArchNames))
|
||||
switch (A.targetArch()) {
|
||||
case OffloadArch::TargetArch::Unused:
|
||||
return "";
|
||||
case OffloadArch::TargetArch::Unknown:
|
||||
return "unknown";
|
||||
return Result->ArchName;
|
||||
case OffloadArch::TargetArch::NVPTX:
|
||||
return llvm::NVPTX::getArchName(A.nvptxKind()).data();
|
||||
case OffloadArch::TargetArch::AMDGPU:
|
||||
return llvm::AMDGPU::getArchNameAMDGCN(A.amdgpuKind()).data();
|
||||
case OffloadArch::TargetArch::SPIRV:
|
||||
return "amdgcnspirv";
|
||||
case OffloadArch::TargetArch::IntelCPU:
|
||||
return "graniterapids";
|
||||
case OffloadArch::TargetArch::IntelGPU:
|
||||
return "bmg_g21";
|
||||
case OffloadArch::TargetArch::Generic:
|
||||
return "generic";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const char *OffloadArchToVirtualArchString(OffloadArch A) {
|
||||
auto Result =
|
||||
llvm::find_if(ArchNames, [A](const OffloadArchToStringMap &Map) {
|
||||
return A == Map.Arch;
|
||||
});
|
||||
if (Result == std::end(ArchNames))
|
||||
switch (A.targetArch()) {
|
||||
case OffloadArch::TargetArch::NVPTX:
|
||||
return llvm::NVPTX::getVirtualArch(A.nvptxKind()).data();
|
||||
case OffloadArch::TargetArch::AMDGPU:
|
||||
case OffloadArch::TargetArch::SPIRV:
|
||||
return "compute_amdgcn";
|
||||
case OffloadArch::TargetArch::Unknown:
|
||||
return "unknown";
|
||||
return Result->VirtualArchName;
|
||||
case OffloadArch::TargetArch::Unused:
|
||||
case OffloadArch::TargetArch::IntelCPU:
|
||||
case OffloadArch::TargetArch::IntelGPU:
|
||||
case OffloadArch::TargetArch::Generic:
|
||||
return "";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
OffloadArch StringToOffloadArch(llvm::StringRef S) {
|
||||
auto Result =
|
||||
llvm::find_if(ArchNames, [S](const OffloadArchToStringMap &Map) {
|
||||
return S == Map.ArchName;
|
||||
});
|
||||
if (Result == std::end(ArchNames))
|
||||
return OffloadArch::Unknown;
|
||||
return Result->Arch;
|
||||
// The empty string denotes the "unused" architecture.
|
||||
if (S.empty())
|
||||
return OffloadArch::getUnused();
|
||||
|
||||
// Non-GPU-table pseudo/sentinel architectures.
|
||||
if (S == "amdgcnspirv")
|
||||
return OffloadArch::getSPIRV();
|
||||
if (S == "generic")
|
||||
return OffloadArch::getGeneric();
|
||||
if (S == "graniterapids")
|
||||
return OffloadArch::getIntel(OffloadArch::TargetArch::IntelCPU,
|
||||
OffloadArch::IntelArch::GRANITERAPIDS);
|
||||
if (S == "bmg_g21")
|
||||
return OffloadArch::getIntel(OffloadArch::TargetArch::IntelGPU,
|
||||
OffloadArch::IntelArch::BMG_G21);
|
||||
|
||||
// Otherwise defer to the vendor TargetParser GPU lists.
|
||||
if (llvm::NVPTX::GPUKind NV = llvm::NVPTX::parseArch(S))
|
||||
return OffloadArch::getNVPTX(NV);
|
||||
if (llvm::AMDGPU::GPUKind AK = llvm::AMDGPU::parseArchAMDGCN(S))
|
||||
return OffloadArch::getAMDGPU(AK);
|
||||
return OffloadArch::getUnknown();
|
||||
}
|
||||
|
||||
void fillValidOffloadArchList(llvm::SmallVectorImpl<llvm::StringRef> &Values) {
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
Values.push_back(NAME);
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
llvm::AMDGPU::fillValidArchListAMDGCN(Values, llvm::Triple::NoSubArch);
|
||||
}
|
||||
|
||||
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple,
|
||||
OffloadArch ID) {
|
||||
if (ID == OffloadArch::AMDGCNSPIRV)
|
||||
if (ID.isSPIRV())
|
||||
return llvm::Triple(llvm::Triple::spirv64, llvm::Triple::NoSubArch,
|
||||
llvm::Triple::AMD, llvm::Triple::AMDHSA);
|
||||
|
||||
if (IsNVIDIAOffloadArch(ID)) {
|
||||
if (ID.isNVPTX()) {
|
||||
llvm::Triple::ArchType Arch = DefaultToolchainTriple.isArch64Bit()
|
||||
? llvm::Triple::nvptx64
|
||||
: llvm::Triple::nvptx;
|
||||
|
|
@ -172,7 +109,7 @@ llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple,
|
|||
llvm::Triple::CUDA);
|
||||
}
|
||||
|
||||
if (IsAMDOffloadArch(ID))
|
||||
if (ID.isAMDGPU())
|
||||
return llvm::Triple("amdgcn-amd-amdhsa");
|
||||
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
|
|||
// Define available target features
|
||||
// These must be defined in sorted order!
|
||||
NoAsmVariants = true;
|
||||
GPU = OffloadArch::Unused;
|
||||
GPU = OffloadArch::getUnused();
|
||||
|
||||
// PTX supports f16 as a fundamental type.
|
||||
HasFastHalfType = true;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public:
|
|||
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
||||
StringRef CPU,
|
||||
const std::vector<std::string> &FeaturesVec) const override {
|
||||
if (GPU != OffloadArch::Unused)
|
||||
if (!GPU.isUnused())
|
||||
Features[OffloadArchToString(GPU)] = true;
|
||||
// Only add PTX feature if explicitly requested. Otherwise, let the backend
|
||||
// use the minimum required PTX version for the target SM.
|
||||
|
|
@ -131,18 +131,16 @@ public:
|
|||
}
|
||||
|
||||
bool isValidCPUName(StringRef Name) const override {
|
||||
return StringToOffloadArch(Name) != OffloadArch::Unknown;
|
||||
return !StringToOffloadArch(Name).isUnknown();
|
||||
}
|
||||
|
||||
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {
|
||||
for (int i = static_cast<int>(OffloadArch::SM_20);
|
||||
i < static_cast<int>(OffloadArch::Generic); ++i)
|
||||
Values.emplace_back(OffloadArchToString(static_cast<OffloadArch>(i)));
|
||||
fillValidOffloadArchList(Values);
|
||||
}
|
||||
|
||||
bool setCPU(StringRef Name) override {
|
||||
GPU = StringToOffloadArch(Name);
|
||||
return GPU != OffloadArch::Unknown;
|
||||
return !GPU.isUnknown();
|
||||
}
|
||||
|
||||
void setSupportedOpenCLOpts() override {
|
||||
|
|
|
|||
|
|
@ -961,7 +961,7 @@ static TripleSet inferOffloadToolchains(Compilation &C,
|
|||
TripleSet Triples;
|
||||
for (llvm::StringRef Arch : Archs) {
|
||||
OffloadArch ID = StringToOffloadArch(Arch);
|
||||
if (ID == OffloadArch::Unknown)
|
||||
if (ID.isUnknown())
|
||||
ID = StringToOffloadArch(
|
||||
getProcessorFromTargetID(llvm::Triple("amdgcn-amd-amdhsa"), Arch));
|
||||
|
||||
|
|
@ -975,13 +975,12 @@ static TripleSet inferOffloadToolchains(Compilation &C,
|
|||
<< "CUDA" << Arch;
|
||||
return {};
|
||||
}
|
||||
if (Kind == Action::OFK_OpenMP &&
|
||||
(ID == OffloadArch::Unknown || ID == OffloadArch::Unused)) {
|
||||
if (Kind == Action::OFK_OpenMP && (ID.isUnknown() || ID.isUnused())) {
|
||||
C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
|
||||
<< Arch;
|
||||
return {};
|
||||
}
|
||||
if (ID == OffloadArch::Unknown || ID == OffloadArch::Unused) {
|
||||
if (ID.isUnknown() || ID.isUnused()) {
|
||||
C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
|
||||
<< "offload" << Arch;
|
||||
return {};
|
||||
|
|
@ -3466,7 +3465,7 @@ class OffloadingActionBuilder final {
|
|||
bool Relocatable = false;
|
||||
|
||||
/// Default GPU architecture if there's no one specified.
|
||||
OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
|
||||
OffloadArch DefaultOffloadArch = OffloadArch::getUnknown();
|
||||
|
||||
/// Compilation unit ID specified by option '-fuse-cuid=' or'-cuid='.
|
||||
const CUIDOptions &CUIDOpts;
|
||||
|
|
@ -3644,7 +3643,7 @@ class OffloadingActionBuilder final {
|
|||
CudaActionBuilder(Compilation &C, DerivedArgList &Args,
|
||||
const InputList &Inputs)
|
||||
: CudaActionBuilderBase(C, Args, Inputs, Action::OFK_Cuda) {
|
||||
DefaultOffloadArch = OffloadArch::CudaDefault;
|
||||
DefaultOffloadArch = OffloadArch::CudaDefault();
|
||||
}
|
||||
|
||||
ActionBuilderReturnCode
|
||||
|
|
@ -3769,7 +3768,7 @@ class OffloadingActionBuilder final {
|
|||
const InputList &Inputs)
|
||||
: CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) {
|
||||
|
||||
DefaultOffloadArch = OffloadArch::HIPDefault;
|
||||
DefaultOffloadArch = OffloadArch::HIPDefault();
|
||||
|
||||
if (Args.hasArg(options::OPT_fhip_emit_relocatable,
|
||||
options::OPT_fno_hip_emit_relocatable)) {
|
||||
|
|
@ -4882,13 +4881,12 @@ static StringRef getCanonicalArchString(Compilation &C,
|
|||
// expecting the triple to be only NVPTX / AMDGPU.
|
||||
OffloadArch Arch =
|
||||
StringToOffloadArch(getProcessorFromTargetID(Triple, ArchStr));
|
||||
if (Triple.isNVPTX() &&
|
||||
(Arch == OffloadArch::Unknown || !IsNVIDIAOffloadArch(Arch))) {
|
||||
if (Triple.isNVPTX() && (Arch.isUnknown() || !IsNVIDIAOffloadArch(Arch))) {
|
||||
C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
|
||||
<< "CUDA" << ArchStr;
|
||||
return StringRef();
|
||||
} else if (Triple.isAMDGPU() &&
|
||||
(Arch == OffloadArch::Unknown || !IsAMDOffloadArch(Arch))) {
|
||||
(Arch.isUnknown() || !IsAMDOffloadArch(Arch))) {
|
||||
C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
|
||||
<< "HIP" << ArchStr;
|
||||
return StringRef();
|
||||
|
|
@ -4992,12 +4990,12 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
|
|||
if (Archs.empty()) {
|
||||
if (Kind == Action::OFK_Cuda) {
|
||||
Archs.insert(OffloadArchToString(TC.getTriple().isSPIRV()
|
||||
? OffloadArch::Unused
|
||||
: OffloadArch::CudaDefault));
|
||||
? OffloadArch::getUnused()
|
||||
: OffloadArch::CudaDefault()));
|
||||
} else if (Kind == Action::OFK_HIP) {
|
||||
Archs.insert(OffloadArchToString(TC.getTriple().isSPIRV()
|
||||
? OffloadArch::Generic
|
||||
: OffloadArch::HIPDefault));
|
||||
? OffloadArch::getGeneric()
|
||||
: OffloadArch::HIPDefault()));
|
||||
} else if (Kind == Action::OFK_SYCL) {
|
||||
Archs.insert(StringRef());
|
||||
} else if (Kind == Action::OFK_OpenMP) {
|
||||
|
|
|
|||
|
|
@ -83,8 +83,7 @@ OffloadTargetInfo::OffloadTargetInfo(const StringRef Target,
|
|||
StringRef TargetIdWithFeature =
|
||||
Components.size() == 6 ? Components.back() : "";
|
||||
StringRef TargetId = TargetIdWithFeature.split(':').first;
|
||||
if (!TargetId.empty() &&
|
||||
clang::StringToOffloadArch(TargetId) != clang::OffloadArch::Unknown)
|
||||
if (!TargetId.empty() && !clang::StringToOffloadArch(TargetId).isUnknown())
|
||||
this->TargetID = TargetIdWithFeature;
|
||||
else
|
||||
this->TargetID = "";
|
||||
|
|
|
|||
|
|
@ -235,14 +235,12 @@ CudaInstallationDetector::CudaInstallationDetector(
|
|||
// CUDA-9+ uses single libdevice file for all GPU variants.
|
||||
std::string FilePath = LibDevicePath + "/libdevice.10.bc";
|
||||
if (FS.exists(FilePath)) {
|
||||
for (int Arch = (int)OffloadArch::SM_30, E = (int)OffloadArch::LAST;
|
||||
Arch < E; ++Arch) {
|
||||
OffloadArch OA = static_cast<OffloadArch>(Arch);
|
||||
if (!IsNVIDIAOffloadArch(OA))
|
||||
continue;
|
||||
std::string OffloadArchName(OffloadArchToString(OA));
|
||||
LibDeviceMap[OffloadArchName] = FilePath;
|
||||
}
|
||||
// CUDA-9+ uses a single libdevice file for every NVIDIA GPU variant
|
||||
// (sm_30 and newer).
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
if ((SM_ID) >= 300) \
|
||||
LibDeviceMap[NAME] = FilePath;
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
}
|
||||
} else {
|
||||
std::error_code EC;
|
||||
|
|
@ -326,14 +324,15 @@ void CudaInstallationDetector::AddCudaIncludeArgs(
|
|||
|
||||
void CudaInstallationDetector::CheckCudaVersionSupportsArch(
|
||||
OffloadArch Arch) const {
|
||||
if (Arch == OffloadArch::Unknown || Version == CudaVersion::UNKNOWN ||
|
||||
ArchsWithBadVersion[(int)Arch])
|
||||
// Only NVIDIA architectures depend on the CUDA toolkit version.
|
||||
if (!Arch.isNVPTX() || Version == CudaVersion::UNKNOWN ||
|
||||
ArchsWithBadVersion[Arch.nvptxKind()])
|
||||
return;
|
||||
|
||||
auto MinVersion = MinVersionForOffloadArch(Arch);
|
||||
auto MaxVersion = MaxVersionForOffloadArch(Arch);
|
||||
if (Version < MinVersion || Version > MaxVersion) {
|
||||
ArchsWithBadVersion[(int)Arch] = true;
|
||||
ArchsWithBadVersion[Arch.nvptxKind()] = true;
|
||||
D.Diag(diag::err_drv_cuda_version_unsupported)
|
||||
<< OffloadArchToString(Arch) << CudaVersionToString(MinVersion)
|
||||
<< CudaVersionToString(MaxVersion) << InstallPath
|
||||
|
|
@ -414,7 +413,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
}
|
||||
|
||||
// Obtain architecture from the action.
|
||||
assert(GPUArch.Arch != OffloadArch::Unknown &&
|
||||
assert(!GPUArch.Arch.isUnknown() &&
|
||||
"Device action expected to have an architecture.");
|
||||
|
||||
// Check that our installation's ptxas supports gpu_arch.
|
||||
|
|
@ -778,7 +777,7 @@ NVPTXToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
|
|||
|
||||
if (!DAL->hasArg(options::OPT_march_EQ) && OffloadKind != Action::OFK_None) {
|
||||
DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
|
||||
OffloadArchToString(OffloadArch::CudaDefault));
|
||||
OffloadArchToString(OffloadArch::CudaDefault()));
|
||||
} else if (DAL->getLastArgValue(options::OPT_march_EQ) == "generic" &&
|
||||
OffloadKind == Action::OFK_None) {
|
||||
DAL->eraseArg(options::OPT_march_EQ);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
#include <optional>
|
||||
|
||||
|
|
@ -6129,8 +6130,8 @@ Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads,
|
|||
// launch bounds attribute within ompx_attribute to support other archs.
|
||||
if (!IgnoreArch) {
|
||||
// '.maxclusterrank' ptx directive requires .target sm_90 or higher.
|
||||
auto SM = getOffloadArch(Context.getTargetInfo());
|
||||
if (SM == OffloadArch::Unknown || SM < OffloadArch::SM_90) {
|
||||
OffloadArch SM = getOffloadArch(Context.getTargetInfo());
|
||||
if (SM.isUnknown() || llvm::NVPTX::getSmVersion(SM.nvptxKind()) < 900) {
|
||||
Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)
|
||||
<< OffloadArchToString(SM) << CI << MaxBlocks->getSourceRange();
|
||||
// Ignore it by setting MaxBlocks to null;
|
||||
|
|
@ -6244,7 +6245,8 @@ void Sema::addNoClusterAttr(Decl *D, const AttributeCommonInfo &CI) {
|
|||
static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
const TargetInfo &TTI = S.Context.getTargetInfo();
|
||||
OffloadArch Arch = StringToOffloadArch(TTI.getTargetOpts().CPU);
|
||||
if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
|
||||
if ((TTI.getTriple().isNVPTX() &&
|
||||
llvm::NVPTX::getSmVersion(Arch.nvptxKind()) < 900) ||
|
||||
(TTI.getTriple().isAMDGPU() &&
|
||||
!TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) {
|
||||
S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL;
|
||||
|
|
@ -6263,7 +6265,8 @@ static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
|||
static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
const TargetInfo &TTI = S.Context.getTargetInfo();
|
||||
OffloadArch Arch = StringToOffloadArch(TTI.getTargetOpts().CPU);
|
||||
if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
|
||||
if ((TTI.getTriple().isNVPTX() &&
|
||||
llvm::NVPTX::getSmVersion(Arch.nvptxKind()) < 900) ||
|
||||
(TTI.getTriple().isAMDGPU() &&
|
||||
!TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) {
|
||||
S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@
|
|||
// CHECK-SAME: {{^}}, gfx803
|
||||
// CHECK-SAME: {{^}}, gfx805
|
||||
// CHECK-SAME: {{^}}, gfx810
|
||||
// CHECK-SAME: {{^}}, gfx9-generic
|
||||
// CHECK-SAME: {{^}}, gfx900
|
||||
// CHECK-SAME: {{^}}, gfx902
|
||||
// CHECK-SAME: {{^}}, gfx904
|
||||
|
|
@ -68,15 +67,12 @@
|
|||
// CHECK-SAME: {{^}}, gfx909
|
||||
// CHECK-SAME: {{^}}, gfx90a
|
||||
// CHECK-SAME: {{^}}, gfx90c
|
||||
// CHECK-SAME: {{^}}, gfx9-4-generic
|
||||
// CHECK-SAME: {{^}}, gfx942
|
||||
// CHECK-SAME: {{^}}, gfx950
|
||||
// CHECK-SAME: {{^}}, gfx10-1-generic
|
||||
// CHECK-SAME: {{^}}, gfx1010
|
||||
// CHECK-SAME: {{^}}, gfx1011
|
||||
// CHECK-SAME: {{^}}, gfx1012
|
||||
// CHECK-SAME: {{^}}, gfx1013
|
||||
// CHECK-SAME: {{^}}, gfx10-3-generic
|
||||
// CHECK-SAME: {{^}}, gfx1030
|
||||
// CHECK-SAME: {{^}}, gfx1031
|
||||
// CHECK-SAME: {{^}}, gfx1032
|
||||
|
|
@ -84,7 +80,6 @@
|
|||
// CHECK-SAME: {{^}}, gfx1034
|
||||
// CHECK-SAME: {{^}}, gfx1035
|
||||
// CHECK-SAME: {{^}}, gfx1036
|
||||
// CHECK-SAME: {{^}}, gfx11-generic
|
||||
// CHECK-SAME: {{^}}, gfx1100
|
||||
// CHECK-SAME: {{^}}, gfx1101
|
||||
// CHECK-SAME: {{^}}, gfx1102
|
||||
|
|
@ -94,17 +89,39 @@
|
|||
// CHECK-SAME: {{^}}, gfx1152
|
||||
// CHECK-SAME: {{^}}, gfx1153
|
||||
// CHECK-SAME: {{^}}, gfx1154
|
||||
// CHECK-SAME: {{^}}, gfx11-7-generic
|
||||
// CHECK-SAME: {{^}}, gfx1170
|
||||
// CHECK-SAME: {{^}}, gfx1171
|
||||
// CHECK-SAME: {{^}}, gfx1172
|
||||
// CHECK-SAME: {{^}}, gfx12-generic
|
||||
// CHECK-SAME: {{^}}, gfx1200
|
||||
// CHECK-SAME: {{^}}, gfx1201
|
||||
// CHECK-SAME: {{^}}, gfx12-5-generic
|
||||
// CHECK-SAME: {{^}}, gfx1250
|
||||
// CHECK-SAME: {{^}}, gfx1251
|
||||
// CHECK-SAME: {{^}}, gfx13-generic
|
||||
// CHECK-SAME: {{^}}, gfx1310
|
||||
// CHECK-SAME: {{^}}, amdgcnspirv
|
||||
// CHECK-SAME: {{^}}, gfx9-generic
|
||||
// CHECK-SAME: {{^}}, gfx9-4-generic
|
||||
// CHECK-SAME: {{^}}, gfx10-1-generic
|
||||
// CHECK-SAME: {{^}}, gfx10-3-generic
|
||||
// CHECK-SAME: {{^}}, gfx11-generic
|
||||
// CHECK-SAME: {{^}}, gfx11-7-generic
|
||||
// CHECK-SAME: {{^}}, gfx12-generic
|
||||
// CHECK-SAME: {{^}}, gfx12-5-generic
|
||||
// CHECK-SAME: {{^}}, gfx13-generic
|
||||
// CHECK-SAME: {{^}}, tahiti
|
||||
// CHECK-SAME: {{^}}, pitcairn
|
||||
// CHECK-SAME: {{^}}, verde
|
||||
// CHECK-SAME: {{^}}, hainan
|
||||
// CHECK-SAME: {{^}}, oland
|
||||
// CHECK-SAME: {{^}}, kaveri
|
||||
// CHECK-SAME: {{^}}, hawaii
|
||||
// CHECK-SAME: {{^}}, kabini
|
||||
// CHECK-SAME: {{^}}, mullins
|
||||
// CHECK-SAME: {{^}}, bonaire
|
||||
// CHECK-SAME: {{^}}, carrizo
|
||||
// CHECK-SAME: {{^}}, iceland
|
||||
// CHECK-SAME: {{^}}, tonga
|
||||
// CHECK-SAME: {{^}}, fiji
|
||||
// CHECK-SAME: {{^}}, polaris10
|
||||
// CHECK-SAME: {{^}}, polaris11
|
||||
// CHECK-SAME: {{^}}, tongapro
|
||||
// CHECK-SAME: {{^}}, stoney
|
||||
// CHECK-SAME: {{$}}
|
||||
|
|
|
|||
|
|
@ -11,26 +11,49 @@
|
|||
|
||||
using namespace clang;
|
||||
|
||||
TEST(OffloadArchTest, basic) {
|
||||
EXPECT_TRUE(IsNVIDIAOffloadArch(OffloadArch::SM_20));
|
||||
EXPECT_TRUE(IsNVIDIAOffloadArch(OffloadArch::SM_120a));
|
||||
EXPECT_FALSE(IsNVIDIAOffloadArch(OffloadArch::GFX600));
|
||||
static OffloadArch parse(llvm::StringRef S) { return StringToOffloadArch(S); }
|
||||
|
||||
EXPECT_FALSE(IsAMDOffloadArch(OffloadArch::SM_120a));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::GFX600));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::GFX1201));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::GFX12_GENERIC));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::AMDGCNSPIRV));
|
||||
EXPECT_FALSE(IsAMDOffloadArch(OffloadArch::GRANITERAPIDS));
|
||||
TEST(OffloadArchTest, VendorClassification) {
|
||||
EXPECT_TRUE(IsNVIDIAOffloadArch(parse("sm_20")));
|
||||
EXPECT_TRUE(IsNVIDIAOffloadArch(parse("sm_120a")));
|
||||
EXPECT_FALSE(IsNVIDIAOffloadArch(parse("gfx600")));
|
||||
|
||||
EXPECT_TRUE(IsIntelOffloadArch(OffloadArch::GRANITERAPIDS));
|
||||
EXPECT_TRUE(IsIntelCPUOffloadArch(OffloadArch::GRANITERAPIDS));
|
||||
EXPECT_FALSE(IsIntelGPUOffloadArch(OffloadArch::GRANITERAPIDS));
|
||||
EXPECT_TRUE(IsIntelOffloadArch(OffloadArch::BMG_G21));
|
||||
EXPECT_FALSE(IsIntelCPUOffloadArch(OffloadArch::BMG_G21));
|
||||
EXPECT_TRUE(IsIntelGPUOffloadArch(OffloadArch::BMG_G21));
|
||||
EXPECT_FALSE(IsAMDOffloadArch(parse("sm_120a")));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(parse("gfx600")));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(parse("gfx1201")));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(parse("gfx12-generic")));
|
||||
EXPECT_TRUE(IsAMDOffloadArch(parse("amdgcnspirv")));
|
||||
EXPECT_FALSE(IsAMDOffloadArch(parse("graniterapids")));
|
||||
|
||||
EXPECT_FALSE(IsNVIDIAOffloadArch(OffloadArch::Generic));
|
||||
EXPECT_FALSE(IsAMDOffloadArch(OffloadArch::Generic));
|
||||
EXPECT_FALSE(IsIntelOffloadArch(OffloadArch::Generic));
|
||||
EXPECT_TRUE(IsIntelOffloadArch(parse("graniterapids")));
|
||||
EXPECT_TRUE(IsIntelCPUOffloadArch(parse("graniterapids")));
|
||||
EXPECT_FALSE(IsIntelGPUOffloadArch(parse("graniterapids")));
|
||||
EXPECT_TRUE(IsIntelOffloadArch(parse("bmg_g21")));
|
||||
EXPECT_FALSE(IsIntelCPUOffloadArch(parse("bmg_g21")));
|
||||
EXPECT_TRUE(IsIntelGPUOffloadArch(parse("bmg_g21")));
|
||||
|
||||
EXPECT_FALSE(IsNVIDIAOffloadArch(parse("generic")));
|
||||
EXPECT_FALSE(IsAMDOffloadArch(parse("generic")));
|
||||
EXPECT_FALSE(IsIntelOffloadArch(parse("generic")));
|
||||
}
|
||||
|
||||
TEST(OffloadArchTest, Unknown) {
|
||||
EXPECT_TRUE(parse("not-a-real-arch").isUnknown());
|
||||
EXPECT_TRUE(parse("").isUnused());
|
||||
}
|
||||
|
||||
// Names must round-trip through parse -> string.
|
||||
TEST(OffloadArchTest, RoundTrip) {
|
||||
for (const char *Name :
|
||||
{"sm_52", "sm_90a", "gfx906", "gfx1201", "gfx12-generic", "amdgcnspirv",
|
||||
"graniterapids", "bmg_g21", "generic"}) {
|
||||
OffloadArch A = parse(Name);
|
||||
EXPECT_FALSE(A.isUnknown()) << Name;
|
||||
EXPECT_STREQ(OffloadArchToString(A), Name);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OffloadArchTest, Defaults) {
|
||||
EXPECT_STREQ(OffloadArchToString(OffloadArch::CudaDefault()), "sm_52");
|
||||
EXPECT_STREQ(OffloadArchToString(OffloadArch::HIPDefault()), "gfx906");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class Triple;
|
|||
namespace AMDGPU {
|
||||
|
||||
/// GPU kinds supported by the AMDGPU target.
|
||||
enum GPUKind : uint32_t {
|
||||
enum GPUKind : uint8_t {
|
||||
// Not specified processor.
|
||||
GK_NONE = 0,
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,15 @@ namespace llvm {
|
|||
namespace NVPTX {
|
||||
|
||||
/// GPU kinds supported by the NVPTX target.
|
||||
enum GPUKind : uint32_t {
|
||||
enum GPUKind : uint8_t {
|
||||
GK_NONE = 0,
|
||||
#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
|
||||
GK_##KIND,
|
||||
#include "llvm/TargetParser/NVPTXTargetParser.def"
|
||||
|
||||
// Alias for the last GPUKind. Keep in sync with the final .def row.
|
||||
// FIXME: Should be generated once the GPU list moves to TableGen.
|
||||
GK_LAST = GK_SM_121f,
|
||||
};
|
||||
|
||||
/// Suffix class of an NVPTX architecture name. Enumerator spellings match the
|
||||
|
|
|
|||
Loading…
Reference in a new issue