Merge CUDA support

This commit is contained in:
Max Rietmann 2019-04-12 14:16:26 +02:00
commit 26076cb2da
3 changed files with 86 additions and 8 deletions

View File

@ -3,7 +3,7 @@
[![Telegram](https://img.shields.io/badge/telegram-@cclsp-blue.svg)](https://telegram.me/cclsp)
[![Gitter](https://img.shields.io/badge/gitter-ccls--project-blue.svg?logo=gitter-white)](https://gitter.im/ccls-project/ccls)
ccls, which originates from [cquery](https://github.com/cquery-project/cquery), is a C/C++/Objective-C language server.
This is a temporary fork of ccls with experimental CUDA support. `ccls` originates from [cquery](https://github.com/cquery-project/cquery), is a C/C++/Objective-C language server.
* code completion (with both signature help and snippets)
* [definition](src/messages/textDocument_definition.cc)/[references](src/messages/textDocument_references.cc), and other cross references
@ -17,6 +17,26 @@ ccls, which originates from [cquery](https://github.com/cquery-project/cquery),
* semantic highlighting and preprocessor skipped regions
* semantic navigation: `$ccls/navigate`
## CUDA quickstart
Your `.ccls` configuration should look something like:
```
%compile_commands.json
%cu --cuda-gpu-arch=sm_70
%cu --cuda-path=/usr/local/cuda-9.2/
```
This fork changes the compile commands from the `compile_commands.json` file that look like:
/usr/local/cuda/bin/nvcc -ccbin=gcc-6 -I../src -I../external/cutlass -I../external/cub -isystem=../external/googletest/googletest/include -Xcompiler -fopenmp --expt-extended-lambda --std=c++11 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_70,code=compute_70 -g -x cu -c /home/max/dev/cuml/ml-prims/test/add.cu -o test/CMakeFiles/mlcommon_test.dir/add.cu.o && /usr/local/cuda/bin/nvcc -ccbin=gcc-6 -I../src -I../external/cutlass -I../external/cub -isystem=../external/googletest/googletest/include -Xcompiler -fopenmp --expt-extended-lambda --std=c++11 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_70,code=compute_70 -g -x cu -M /home/max/dev/cuml/ml-prims/test/add.cu -MT test/CMakeFiles/mlcommon_test.dir/add.cu.o -o $DEP_FILE
To something more like:
clang -I../src -I../external/cutlass -I../external/cub -isystem=../external/googletest/googletest/include --std=c++11 --cuda-gpu-arch=sm_70 --cuda-path=/usr/local/cuda-9.2/ -c add.cu
In other words, it whitelists includes (`-I`) and c++ standard flags, but ignores all the `nvcc` switches that `clang` doesn't understand. Note that clang understands CUDA files by default.
## General Info
It has a global view of the code base and support a lot of cross reference features, see [wiki/FAQ](../../wiki/FAQ).
It starts indexing the whole project (including subprojects if exist) parallelly when you open the first file, while the main thread can serve requests before the indexing is complete.
Saving files will incrementally update the index.

View File

@ -261,6 +261,6 @@ struct ShowMessageParam {
// Used to identify the language at a file level. The ordering is important, as
// a file previously identified as `C`, will be changed to `Cpp` if it
// encounters a c++ declaration.
enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 };
enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3, CUDA = 4 };
} // namespace ccls

View File

@ -51,6 +51,15 @@ using namespace clang;
using namespace llvm;
namespace ccls {
template <typename Enumeration>
auto as_integer(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
std::pair<LanguageId, bool> lookupExtension(std::string_view filename) {
using namespace clang::driver;
auto I = types::lookupTypeForExtension(
@ -59,7 +68,9 @@ std::pair<LanguageId, bool> lookupExtension(std::string_view filename) {
I == types::TY_ObjCXXHeader;
bool objc = types::isObjC(I);
LanguageId ret;
if (types::isCXX(I))
if (I == types::TY_CUDA)
ret = LanguageId::CUDA;
else if (types::isCXX(I))
ret = objc ? LanguageId::ObjCpp : LanguageId::Cpp;
else if (objc)
ret = LanguageId::ObjC;
@ -123,6 +134,8 @@ struct ProjectProcessor {
ok |= lang == LanguageId::ObjC;
else if (A.consume_front("%objective-cpp "))
ok |= lang == LanguageId::ObjCpp;
else if (A.consume_front("%cu "))
ok |= lang == LanguageId::CUDA;
else
break;
}
@ -132,6 +145,7 @@ struct ProjectProcessor {
args.push_back(arg);
}
}
entry.args = args;
GetSearchDirs(entry);
}
@ -326,6 +340,7 @@ int ComputeGuessScore(std::string_view a, std::string_view b) {
} // namespace
void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
SmallString<256> CDBDir, Path, StdinPath;
std::string err_msg;
@ -412,11 +427,54 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
DoPathMapping(entry.filename);
std::vector<std::string> args = std::move(Cmd.CommandLine);
entry.args.reserve(args.size());
for (std::string &arg : args) {
DoPathMapping(arg);
if (!proc.ExcludesArg(arg))
entry.args.push_back(Intern(arg));
auto [lang, header] = lookupExtension(entry.filename);
// CMAKE splits nvcc compiles into 2 seperates commands, and has (mostly) non-clang arguments. Replace these with a simple call to clang with only "-I /path/header.h" arguments.
// .ccls will also need:
// clang
// %cu --cuda-gpu-arch=sm_70 --cuda-path=/usr/local/cuda-9.2/ --std=c++11
if(lang == LanguageId::CUDA) {
entry.args.push_back(Intern("/usr/bin/clang-7"));
// entry.args.push_back(Intern("--cuda-gpu-arch=sm_70"));
// entry.args.push_back(Intern("--cuda-path=/usr/local/cuda-9.2/"));
// entry.args.push_back(Intern("-I/home/max/dev/cuml/thirdparty/cuml/googletest/googletest/include"));
// entry.args.push_back(Intern("--std=c++11"));
entry.args.push_back(Intern("-c"));
entry.args.push_back(Intern(entry.filename));
LOG_S(INFO) << entry.filename << ": (CUDA) clang-7 -c filename";
for (std::string &arg : args) {
// take header includes (-I/path/to/header.h)
if((arg.find("-I") != std::string::npos)
) {
LOG_S(INFO) << entry.filename << ": (CUDA) Adding Arg: " << arg;
entry.args.push_back(Intern(arg));
}
else if(arg.find("-isystem") != std::string::npos) {
auto equals = arg.find("=");
arg.replace(equals,1," ");
LOG_S(INFO) << entry.filename << ": (CUDA) Adding Arg: " << arg;
entry.args.push_back(Intern(arg));
}
else if(arg.find("-std=") != std::string::npos) {
LOG_S(INFO) << entry.filename << ": (CUDA) Adding Arg: " << arg;
entry.args.push_back(Intern(arg));
}
else {
LOG_S(INFO) << entry.filename << ": (CUDA) Ignoring arg: " << arg;
}
}
}
else {
entry.args.reserve(args.size());
for (std::string &arg : args) {
DoPathMapping(arg);
if (!proc.ExcludesArg(arg)) {
// LOG_S(INFO) << entry.filename << ": Accepted arg: " << arg <<
// "\n";
entry.args.push_back(Intern(arg));
}
}
}
entry.compdb_size = entry.args.size();