Skip to content

Commit 68fabc3

Browse files
feat: Add initial support for CUDA (#433)
1 parent ecab783 commit 68fabc3

File tree

5 files changed

+109
-3
lines changed

5 files changed

+109
-3
lines changed

docs/Development.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- [Stacktraces](#stacktraces)
1212
- [Attaching a debugger](#attaching-a-debugger)
1313
- [Debugging on Linux](#debugging-on-linux)
14+
- [Testing CUDA/NVCC support](#testing-cudanvcc-support)
1415
- [Inspecting Clang ASTs](#inspecting-clang-asts)
1516
- [Automated test case reduction](#automated-test-case-reduction)
1617
- [Debugging preprocessor issues](#debugging-preprocessor-issues)
@@ -162,6 +163,14 @@ There is a [VM setup script](/tools/vm-setup.sh) available
162163
to configure a GCP VM for building scip-clang.
163164
We recommend using Ubuntu 20.04+ with 16 cores or more.
164165

166+
#### Testing CUDA/NVCC support
167+
168+
There is a [CUDA-specific VM setup script](/tools/vm-setup-cuda.sh)
169+
which installs the CUDA SDK. Use it in a GCP VM
170+
which has a GPU attached.
171+
172+
You may need to restart your shell for changes to take effect.
173+
165174
### Inspecting Clang ASTs
166175

167176
Print the AST nodes:

docs/IndexingProjects.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [Redpanda](#redpanda)
77
- [Postgres](#postgres)
88
- [Boost](#boost)
9+
- [Apache MXNet](#apache-mxnet)
910

1011
## scip-clang
1112

@@ -224,3 +225,25 @@ for d in dirs:
224225
print("Indexing failed for {}; skipping upload".format(d))
225226
continue
226227
```
228+
229+
## Apache MXNet
230+
231+
Apache MXNet is an interesting project to test because
232+
it has over 100 CUDA files.
233+
234+
The indexing steps below are based on the [official instructions](https://mxnet.apache.org/versions/1.9.1/get_started/build_from_source.html).
235+
236+
```
237+
git clone --recursive https://github.com/apache/mxnet
238+
cd mxnet
239+
sudo apt-get update
240+
sudo apt-get install -y build-essential git ninja-build ccache libopenblas-dev libopencv-dev cmake gfortran clang++-14 clang libomp-dev
241+
```
242+
243+
```
244+
cmake -B build -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DUSE_CUDA=ON
245+
246+
cat build/compile_commands.json | jq --arg rdir "$(clang -print-resource-dir)" 'map(if .command | contains("nvcc") then .command += " -resource-dir " + $rdir else . end)' > build/modified.json
247+
248+
scip-clang --compdb-path build/modified.json
249+
```

indexer/CompilationDatabase.cc

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,38 @@ struct GccToolchainInfo : ToolchainInfo {
118118
}
119119
};
120120

121+
struct NvccToolchainInfo : ToolchainInfo {
122+
scip_clang::AbsolutePath cudaDir;
123+
124+
NvccToolchainInfo(scip_clang::AbsolutePath cudaDir)
125+
: ToolchainInfo(), cudaDir(cudaDir) {}
126+
127+
virtual CompilerKind kind() const override {
128+
return CompilerKind::Nvcc;
129+
}
130+
131+
virtual bool isWellFormed() const override {
132+
auto path = scip_clang::joinPath(cudaDir.asStringRef(), "include");
133+
if (!std::filesystem::exists(path)) {
134+
spdlog::error(
135+
"directory '{}' does not exist; expected to find CUDA SDK headers"
136+
" there because nvcc was found at {}",
137+
path,
138+
scip_clang::joinPath(cudaDir.asStringRef(),
139+
scip_clang::joinPath("bin", "nvcc")));
140+
return false;
141+
}
142+
return true;
143+
}
144+
145+
virtual void
146+
adjustCommandLine(std::vector<std::string> &commandLine) const override {
147+
commandLine.push_back(
148+
fmt::format("-isystem{}{}include", this->cudaDir.asStringRef(),
149+
std::filesystem::path::preferred_separator));
150+
}
151+
};
152+
121153
} // namespace
122154

123155
static CompletedProcess runProcess(std::vector<std::string> &args,
@@ -231,7 +263,20 @@ ToolchainInfo::infer(const scip_clang::AbsolutePath &compilerPath) {
231263
findSearchDirsInvocation);
232264
}
233265

234-
spdlog::warn("compiler at '{}' is not one of clang/clang++/gcc/g++",
266+
std::vector<std::string> argv = {compilerPath.asStringRef(), "--version"};
267+
auto compilerVersionResult = ::runProcess(argv, "checking for NVCC");
268+
if (compilerVersionResult.isSuccess()
269+
&& !compilerVersionResult.stdoutLines.empty()
270+
&& absl::StrContains(compilerVersionResult.stdoutLines[0], "NVIDIA")) {
271+
if (auto binDir = compilerPath.asRef().prefix()) {
272+
if (auto cudaDir = binDir->prefix()) {
273+
return std::make_unique<NvccToolchainInfo>(
274+
scip_clang::AbsolutePath(*cudaDir));
275+
}
276+
}
277+
}
278+
279+
spdlog::warn("compiler at '{}' is not one of clang/clang++/gcc/g++/nvcc",
235280
compilerPath.asStringRef());
236281
noteStdlib();
237282
return failure;
@@ -693,8 +738,12 @@ void ResumableParser::initialize(compdb::File compdb, ParseOptions options) {
693738
this->reader.IterativeParseInit();
694739
this->options = options;
695740
std::vector<std::string> extensions;
696-
// Via https://stackoverflow.com/a/3223792/2682729
697-
for (auto ext : {"c", "C", "cc", "cpp", "CPP", "cxx", "c++"}) {
741+
// clang-format off
742+
// Via https://stackoverflow.com/a/3223792/2682729 (for C and C++)
743+
// For CUDA, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#basics-cdp1
744+
// and https://github.com/github-linguist/linguist/blob/master/lib/linguist/languages.yml#L1342-L1346
745+
// clang-format on
746+
for (auto ext : {"c", "C", "cc", "cpp", "CPP", "cxx", "c++", "cu"}) {
698747
extensions.emplace_back(llvm::Regex::escape(fmt::format(".{}", ext)));
699748
};
700749
this->fileExtensionRegex =

indexer/CompilationDatabase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class CommandObjectHandler
108108
enum class CompilerKind {
109109
Gcc,
110110
Clang,
111+
Nvcc,
111112
};
112113

113114
struct ToolchainInfo {

tools/vm-setup-cuda.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
3+
sudo dpkg -i cuda-keyring_1.1-1_all.deb
4+
rm -rf cuda-keyring_1.1-1_all.deb
5+
sudo apt-get update
6+
sudo apt-get -y install cuda
7+
8+
ZSH_INIT="$HOME/.zshrc"
9+
if [ -f "$ZSH_INIT" ] && ! grep -q "cuda" "$ZSH_INIT"; then
10+
echo 'export PATH="/usr/local/cuda/bin:$PATH"' >> "$ZSH_INIT"
11+
echo "Added CUDA path to $ZSH_INIT"
12+
fi
13+
14+
BASH_INIT="$HOME/.bashrc"
15+
if [ -f "$BASH_INIT" ] && ! grep -q "cuda" "$BASH_INIT"; then
16+
echo 'export PATH="/usr/local/cuda/bin:$PATH"' >> "$BASH_INIT"
17+
echo "Added CUDA path to $BASH_INIT"
18+
fi
19+
20+
FISH_INIT="$HOME/.config/fish/config.fish"
21+
if [ -f "$FISH_INIT" ] && ! grep -q "cuda" "$FISH_INIT"; then
22+
echo "fish_add_path /usr/local/cuda/bin" >> "$FISH_INIT"
23+
echo "Added CUDA path to $FISH_INIT"
24+
fi

0 commit comments

Comments
 (0)