首先,请确保您告诉 CLion 进行治疗.cu
and .cuh
使用 C++ 文件File Types
设置菜单。
CLion 无法解析 CUDA 的语言扩展,但它确实提供了一个预处理器宏,该宏仅在 clion 解析代码时定义。您可以使用它自己实现几乎完整的 CUDA 支持。
Much of the problem is that CLion's parser is derailed by keywords like __host__
or __device__
, causing it to fail to do things it otherwise knows how to do:
CLion没能理解Dtype
在这个例子中,因为 CUDA 的东西混淆了它的解析。
这个问题的最简单的解决方案是让 clion 预处理器宏忽略新关键字,修复最严重的损坏:
#ifdef __JETBRAINS_IDE__
#define __host__
#define __device__
#define __shared__
#define __constant__
#define __global__
#endif
这修复了上面的示例:
然而,CUDA 的功能如下__syncthreads
, __popc
仍然无法索引。那么 CUDA 内置函数会像threadIdx
。一种选择是为它们提供无尽的预处理器宏(甚至结构定义),但这很丑陋并且牺牲了类型安全。
如果您使用 Clang 的 CUDA 前端,您可以做得更好。 Clang 通过在标头中定义隐式定义的 CUDA 内置函数来实现它们,然后在编译代码时将其包含在内。这些提供了诸如此类的定义threadIdx
。通过假装是 CUDA 编译器的预处理器并包含device_functions.h
, 我们可以得到__popc
和朋友一起工作:
#ifdef __JETBRAINS_IDE__
#define __host__
#define __device__
#define __shared__
#define __constant__
#define __global__
// This is slightly mental, but gets it to properly index device function calls like __popc and whatever.
#define __CUDACC__
#include <device_functions.h>
// These headers are all implicitly present when you compile CUDA with clang. Clion doesn't know that, so
// we include them explicitly to make the indexer happy. Doing this when you actually build is, obviously,
// a terrible idea :D
#include <__clang_cuda_builtin_vars.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_math_forward_declares.h>
#include <__clang_cuda_complex_builtins.h>
#include <__clang_cuda_cmath.h>
#endif // __JETBRAINS_IDE__
这将为您提供几乎所有 CUDA 代码的完美索引。 CLion甚至可以优雅地应对<<<...>>>
句法。它在启动块每一端的一个字符下放置了一条小红线,但在其他方面将其视为函数调用 - 这完全没问题: