1 #include "clang/Basic/Cuda.h" 2 3 #include "llvm/ADT/Twine.h" 4 #include "llvm/Support/ErrorHandling.h" 5 #include "llvm/Support/VersionTuple.h" 6 7 namespace clang { 8 9 struct CudaVersionMapEntry { 10 const char *Name; 11 CudaVersion Version; 12 llvm::VersionTuple TVersion; 13 }; 14 #define CUDA_ENTRY(major, minor) \ 15 { \ 16 #major "." #minor, CudaVersion::CUDA_##major##minor, \ 17 llvm::VersionTuple(major, minor) \ 18 } 19 20 static const CudaVersionMapEntry CudaNameVersionMap[] = { 21 CUDA_ENTRY(7, 0), 22 CUDA_ENTRY(7, 5), 23 CUDA_ENTRY(8, 0), 24 CUDA_ENTRY(9, 0), 25 CUDA_ENTRY(9, 1), 26 CUDA_ENTRY(9, 2), 27 CUDA_ENTRY(10, 0), 28 CUDA_ENTRY(10, 1), 29 CUDA_ENTRY(10, 2), 30 CUDA_ENTRY(11, 0), 31 CUDA_ENTRY(11, 1), 32 CUDA_ENTRY(11, 2), 33 CUDA_ENTRY(11, 3), 34 CUDA_ENTRY(11, 4), 35 CUDA_ENTRY(11, 5), 36 CUDA_ENTRY(11, 6), 37 CUDA_ENTRY(11, 7), 38 CUDA_ENTRY(11, 8), 39 CUDA_ENTRY(12, 0), 40 CUDA_ENTRY(12, 1), 41 CUDA_ENTRY(12, 2), 42 CUDA_ENTRY(12, 3), 43 CUDA_ENTRY(12, 4), 44 CUDA_ENTRY(12, 5), 45 CUDA_ENTRY(12, 6), 46 CUDA_ENTRY(12, 8), 47 {"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())}, 48 {"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone. 49 }; 50 #undef CUDA_ENTRY 51 52 const char *CudaVersionToString(CudaVersion V) { 53 for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I) 54 if (I->Version == V) 55 return I->Name; 56 57 return CudaVersionToString(CudaVersion::UNKNOWN); 58 } 59 60 CudaVersion CudaStringToVersion(const llvm::Twine &S) { 61 std::string VS = S.str(); 62 for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I) 63 if (I->Name == VS) 64 return I->Version; 65 return CudaVersion::UNKNOWN; 66 } 67 68 CudaVersion ToCudaVersion(llvm::VersionTuple Version) { 69 for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I) 70 if (I->TVersion == Version) 71 return I->Version; 72 return CudaVersion::UNKNOWN; 73 } 74 75 CudaVersion MinVersionForOffloadArch(OffloadArch A) { 76 if (A == OffloadArch::UNKNOWN) 77 return CudaVersion::UNKNOWN; 78 79 // AMD GPUs do not depend on CUDA versions. 80 if (IsAMDOffloadArch(A)) 81 return CudaVersion::CUDA_70; 82 83 switch (A) { 84 case OffloadArch::SM_20: 85 case OffloadArch::SM_21: 86 case OffloadArch::SM_30: 87 case OffloadArch::SM_32_: 88 case OffloadArch::SM_35: 89 case OffloadArch::SM_37: 90 case OffloadArch::SM_50: 91 case OffloadArch::SM_52: 92 case OffloadArch::SM_53: 93 return CudaVersion::CUDA_70; 94 case OffloadArch::SM_60: 95 case OffloadArch::SM_61: 96 case OffloadArch::SM_62: 97 return CudaVersion::CUDA_80; 98 case OffloadArch::SM_70: 99 return CudaVersion::CUDA_90; 100 case OffloadArch::SM_72: 101 return CudaVersion::CUDA_91; 102 case OffloadArch::SM_75: 103 return CudaVersion::CUDA_100; 104 case OffloadArch::SM_80: 105 return CudaVersion::CUDA_110; 106 case OffloadArch::SM_86: 107 return CudaVersion::CUDA_111; 108 case OffloadArch::SM_87: 109 return CudaVersion::CUDA_114; 110 case OffloadArch::SM_89: 111 case OffloadArch::SM_90: 112 return CudaVersion::CUDA_118; 113 case OffloadArch::SM_90a: 114 return CudaVersion::CUDA_120; 115 case OffloadArch::SM_100: 116 case OffloadArch::SM_100a: 117 case OffloadArch::SM_101: 118 case OffloadArch::SM_101a: 119 case OffloadArch::SM_120: 120 case OffloadArch::SM_120a: 121 return CudaVersion::CUDA_128; 122 default: 123 llvm_unreachable("invalid enum"); 124 } 125 } 126 127 CudaVersion MaxVersionForOffloadArch(OffloadArch A) { 128 // AMD GPUs do not depend on CUDA versions. 129 if (IsAMDOffloadArch(A)) 130 return CudaVersion::NEW; 131 132 switch (A) { 133 case OffloadArch::UNKNOWN: 134 return CudaVersion::UNKNOWN; 135 case OffloadArch::SM_20: 136 case OffloadArch::SM_21: 137 return CudaVersion::CUDA_80; 138 case OffloadArch::SM_30: 139 case OffloadArch::SM_32_: 140 return CudaVersion::CUDA_102; 141 case OffloadArch::SM_35: 142 case OffloadArch::SM_37: 143 return CudaVersion::CUDA_118; 144 default: 145 return CudaVersion::NEW; 146 } 147 } 148 149 bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) { 150 return CudaFeatureEnabled(ToCudaVersion(Version), Feature); 151 } 152 153 bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) { 154 switch (Feature) { 155 case CudaFeature::CUDA_USES_NEW_LAUNCH: 156 return Version >= CudaVersion::CUDA_92; 157 case CudaFeature::CUDA_USES_FATBIN_REGISTER_END: 158 return Version >= CudaVersion::CUDA_101; 159 } 160 llvm_unreachable("Unknown CUDA feature."); 161 } 162 } // namespace clang 163