Cuda.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "clang/Basic/Cuda.h"
  2. #include "llvm/ADT/StringRef.h"
  3. #include "llvm/ADT/StringSwitch.h"
  4. #include "llvm/ADT/Twine.h"
  5. #include "llvm/Support/ErrorHandling.h"
  6. #include "llvm/Support/VersionTuple.h"
  7. namespace clang {
  8. const char *CudaVersionToString(CudaVersion V) {
  9. switch (V) {
  10. case CudaVersion::UNKNOWN:
  11. return "unknown";
  12. case CudaVersion::CUDA_70:
  13. return "7.0";
  14. case CudaVersion::CUDA_75:
  15. return "7.5";
  16. case CudaVersion::CUDA_80:
  17. return "8.0";
  18. case CudaVersion::CUDA_90:
  19. return "9.0";
  20. case CudaVersion::CUDA_91:
  21. return "9.1";
  22. case CudaVersion::CUDA_92:
  23. return "9.2";
  24. case CudaVersion::CUDA_100:
  25. return "10.0";
  26. case CudaVersion::CUDA_101:
  27. return "10.1";
  28. case CudaVersion::CUDA_102:
  29. return "10.2";
  30. case CudaVersion::CUDA_110:
  31. return "11.0";
  32. case CudaVersion::CUDA_111:
  33. return "11.1";
  34. case CudaVersion::CUDA_112:
  35. return "11.2";
  36. case CudaVersion::CUDA_113:
  37. return "11.3";
  38. case CudaVersion::CUDA_114:
  39. return "11.4";
  40. case CudaVersion::CUDA_115:
  41. return "11.5";
  42. case CudaVersion::NEW:
  43. return "";
  44. }
  45. llvm_unreachable("invalid enum");
  46. }
  47. CudaVersion CudaStringToVersion(const llvm::Twine &S) {
  48. return llvm::StringSwitch<CudaVersion>(S.str())
  49. .Case("7.0", CudaVersion::CUDA_70)
  50. .Case("7.5", CudaVersion::CUDA_75)
  51. .Case("8.0", CudaVersion::CUDA_80)
  52. .Case("9.0", CudaVersion::CUDA_90)
  53. .Case("9.1", CudaVersion::CUDA_91)
  54. .Case("9.2", CudaVersion::CUDA_92)
  55. .Case("10.0", CudaVersion::CUDA_100)
  56. .Case("10.1", CudaVersion::CUDA_101)
  57. .Case("10.2", CudaVersion::CUDA_102)
  58. .Case("11.0", CudaVersion::CUDA_110)
  59. .Case("11.1", CudaVersion::CUDA_111)
  60. .Case("11.2", CudaVersion::CUDA_112)
  61. .Case("11.3", CudaVersion::CUDA_113)
  62. .Case("11.4", CudaVersion::CUDA_114)
  63. .Case("11.5", CudaVersion::CUDA_115)
  64. .Default(CudaVersion::UNKNOWN);
  65. }
  66. namespace {
  67. struct CudaArchToStringMap {
  68. CudaArch arch;
  69. const char *arch_name;
  70. const char *virtual_arch_name;
  71. };
  72. } // namespace
  73. #define SM2(sm, ca) \
  74. { CudaArch::SM_##sm, "sm_" #sm, ca }
  75. #define SM(sm) SM2(sm, "compute_" #sm)
  76. #define GFX(gpu) \
  77. { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" }
  78. static const CudaArchToStringMap arch_names[] = {
  79. // clang-format off
  80. {CudaArch::UNUSED, "", ""},
  81. SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi
  82. SM(30), SM(32), SM(35), SM(37), // Kepler
  83. SM(50), SM(52), SM(53), // Maxwell
  84. SM(60), SM(61), SM(62), // Pascal
  85. SM(70), SM(72), // Volta
  86. SM(75), // Turing
  87. SM(80), SM(86), // Ampere
  88. GFX(600), // gfx600
  89. GFX(601), // gfx601
  90. GFX(602), // gfx602
  91. GFX(700), // gfx700
  92. GFX(701), // gfx701
  93. GFX(702), // gfx702
  94. GFX(703), // gfx703
  95. GFX(704), // gfx704
  96. GFX(705), // gfx705
  97. GFX(801), // gfx801
  98. GFX(802), // gfx802
  99. GFX(803), // gfx803
  100. GFX(805), // gfx805
  101. GFX(810), // gfx810
  102. GFX(900), // gfx900
  103. GFX(902), // gfx902
  104. GFX(904), // gfx903
  105. GFX(906), // gfx906
  106. GFX(908), // gfx908
  107. GFX(909), // gfx909
  108. GFX(90a), // gfx90a
  109. GFX(90c), // gfx90c
  110. GFX(1010), // gfx1010
  111. GFX(1011), // gfx1011
  112. GFX(1012), // gfx1012
  113. GFX(1013), // gfx1013
  114. GFX(1030), // gfx1030
  115. GFX(1031), // gfx1031
  116. GFX(1032), // gfx1032
  117. GFX(1033), // gfx1033
  118. GFX(1034), // gfx1034
  119. GFX(1035), // gfx1035
  120. {CudaArch::Generic, "generic", ""},
  121. // clang-format on
  122. };
  123. #undef SM
  124. #undef SM2
  125. #undef GFX
  126. const char *CudaArchToString(CudaArch A) {
  127. auto result = std::find_if(
  128. std::begin(arch_names), std::end(arch_names),
  129. [A](const CudaArchToStringMap &map) { return A == map.arch; });
  130. if (result == std::end(arch_names))
  131. return "unknown";
  132. return result->arch_name;
  133. }
  134. const char *CudaArchToVirtualArchString(CudaArch A) {
  135. auto result = std::find_if(
  136. std::begin(arch_names), std::end(arch_names),
  137. [A](const CudaArchToStringMap &map) { return A == map.arch; });
  138. if (result == std::end(arch_names))
  139. return "unknown";
  140. return result->virtual_arch_name;
  141. }
  142. CudaArch StringToCudaArch(llvm::StringRef S) {
  143. auto result = std::find_if(
  144. std::begin(arch_names), std::end(arch_names),
  145. [S](const CudaArchToStringMap &map) { return S == map.arch_name; });
  146. if (result == std::end(arch_names))
  147. return CudaArch::UNKNOWN;
  148. return result->arch;
  149. }
  150. CudaVersion MinVersionForCudaArch(CudaArch A) {
  151. if (A == CudaArch::UNKNOWN)
  152. return CudaVersion::UNKNOWN;
  153. // AMD GPUs do not depend on CUDA versions.
  154. if (IsAMDGpuArch(A))
  155. return CudaVersion::CUDA_70;
  156. switch (A) {
  157. case CudaArch::SM_20:
  158. case CudaArch::SM_21:
  159. case CudaArch::SM_30:
  160. case CudaArch::SM_32:
  161. case CudaArch::SM_35:
  162. case CudaArch::SM_37:
  163. case CudaArch::SM_50:
  164. case CudaArch::SM_52:
  165. case CudaArch::SM_53:
  166. return CudaVersion::CUDA_70;
  167. case CudaArch::SM_60:
  168. case CudaArch::SM_61:
  169. case CudaArch::SM_62:
  170. return CudaVersion::CUDA_80;
  171. case CudaArch::SM_70:
  172. return CudaVersion::CUDA_90;
  173. case CudaArch::SM_72:
  174. return CudaVersion::CUDA_91;
  175. case CudaArch::SM_75:
  176. return CudaVersion::CUDA_100;
  177. case CudaArch::SM_80:
  178. return CudaVersion::CUDA_110;
  179. case CudaArch::SM_86:
  180. return CudaVersion::CUDA_111;
  181. default:
  182. llvm_unreachable("invalid enum");
  183. }
  184. }
  185. CudaVersion MaxVersionForCudaArch(CudaArch A) {
  186. // AMD GPUs do not depend on CUDA versions.
  187. if (IsAMDGpuArch(A))
  188. return CudaVersion::NEW;
  189. switch (A) {
  190. case CudaArch::UNKNOWN:
  191. return CudaVersion::UNKNOWN;
  192. case CudaArch::SM_20:
  193. case CudaArch::SM_21:
  194. return CudaVersion::CUDA_80;
  195. case CudaArch::SM_30:
  196. return CudaVersion::CUDA_110;
  197. default:
  198. return CudaVersion::NEW;
  199. }
  200. }
  201. CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
  202. int IVer =
  203. Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
  204. switch(IVer) {
  205. case 70:
  206. return CudaVersion::CUDA_70;
  207. case 75:
  208. return CudaVersion::CUDA_75;
  209. case 80:
  210. return CudaVersion::CUDA_80;
  211. case 90:
  212. return CudaVersion::CUDA_90;
  213. case 91:
  214. return CudaVersion::CUDA_91;
  215. case 92:
  216. return CudaVersion::CUDA_92;
  217. case 100:
  218. return CudaVersion::CUDA_100;
  219. case 101:
  220. return CudaVersion::CUDA_101;
  221. case 102:
  222. return CudaVersion::CUDA_102;
  223. case 110:
  224. return CudaVersion::CUDA_110;
  225. case 111:
  226. return CudaVersion::CUDA_111;
  227. case 112:
  228. return CudaVersion::CUDA_112;
  229. case 113:
  230. return CudaVersion::CUDA_113;
  231. case 114:
  232. return CudaVersion::CUDA_114;
  233. case 115:
  234. return CudaVersion::CUDA_115;
  235. default:
  236. return CudaVersion::UNKNOWN;
  237. }
  238. }
  239. bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
  240. return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
  241. }
  242. bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
  243. switch (Feature) {
  244. case CudaFeature::CUDA_USES_NEW_LAUNCH:
  245. return Version >= CudaVersion::CUDA_92;
  246. case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
  247. return Version >= CudaVersion::CUDA_101;
  248. }
  249. llvm_unreachable("Unknown CUDA feature.");
  250. }
  251. } // namespace clang