Coverage Report

Created: 2024-01-17 10:31

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