| #include "clang/Basic/Cuda.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), |
| CUDA_ENTRY(12, 4), |
| CUDA_ENTRY(12, 5), |
| CUDA_ENTRY(12, 6), |
| CUDA_ENTRY(12, 8), |
| CUDA_ENTRY(12, 9), |
| {"", 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; |
| } |
| |
| CudaVersion MinVersionForOffloadArch(OffloadArch A) { |
| if (A == OffloadArch::UNKNOWN) |
| return CudaVersion::UNKNOWN; |
| |
| // AMD GPUs do not depend on CUDA versions. |
| if (IsAMDOffloadArch(A)) |
| return CudaVersion::CUDA_70; |
| |
| switch (A) { |
| case OffloadArch::SM_20: |
| case OffloadArch::SM_21: |
| case OffloadArch::SM_30: |
| case OffloadArch::SM_32_: |
| case OffloadArch::SM_35: |
| case OffloadArch::SM_37: |
| case OffloadArch::SM_50: |
| case OffloadArch::SM_52: |
| case OffloadArch::SM_53: |
| return CudaVersion::CUDA_70; |
| case OffloadArch::SM_60: |
| case OffloadArch::SM_61: |
| case OffloadArch::SM_62: |
| return CudaVersion::CUDA_80; |
| case OffloadArch::SM_70: |
| return CudaVersion::CUDA_90; |
| case OffloadArch::SM_72: |
| return CudaVersion::CUDA_91; |
| case OffloadArch::SM_75: |
| return CudaVersion::CUDA_100; |
| case OffloadArch::SM_80: |
| return CudaVersion::CUDA_110; |
| case OffloadArch::SM_86: |
| return CudaVersion::CUDA_111; |
| case OffloadArch::SM_87: |
| return CudaVersion::CUDA_114; |
| case OffloadArch::SM_89: |
| case OffloadArch::SM_90: |
| return CudaVersion::CUDA_118; |
| case OffloadArch::SM_90a: |
| return CudaVersion::CUDA_120; |
| case OffloadArch::SM_100: |
| case OffloadArch::SM_100a: |
| case OffloadArch::SM_101: |
| case OffloadArch::SM_101a: |
| case OffloadArch::SM_120: |
| case OffloadArch::SM_120a: |
| return CudaVersion::CUDA_128; |
| case OffloadArch::SM_103: |
| case OffloadArch::SM_103a: |
| case OffloadArch::SM_121: |
| case OffloadArch::SM_121a: |
| return CudaVersion::CUDA_129; |
| default: |
| llvm_unreachable("invalid enum"); |
| } |
| } |
| |
| CudaVersion MaxVersionForOffloadArch(OffloadArch A) { |
| // AMD GPUs do not depend on CUDA versions. |
| if (IsAMDOffloadArch(A)) |
| return CudaVersion::NEW; |
| |
| switch (A) { |
| case OffloadArch::UNKNOWN: |
| return CudaVersion::UNKNOWN; |
| case OffloadArch::SM_20: |
| case OffloadArch::SM_21: |
| return CudaVersion::CUDA_80; |
| case OffloadArch::SM_30: |
| case OffloadArch::SM_32_: |
| return CudaVersion::CUDA_102; |
| case OffloadArch::SM_35: |
| case OffloadArch::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 |