如何将编译器标志从 clang 传递给 nvcc
Posted
技术标签:
【中文标题】如何将编译器标志从 clang 传递给 nvcc【英文标题】:How to pass compiler flags to nvcc from clang 【发布时间】:2019-10-11 19:33:29 【问题描述】:我正在尝试compile CUDA with clang,但我尝试编译的代码取决于特定的 nvcc 标志 (-default-stream per-thread
)。如何告诉 clang 将 flag 传递给 nvcc?
例如,我可以使用 nvcc 进行编译,并且一切正常:
nvcc -default-stream per-thread *.cu -o app
但是当我从 clang 编译时,程序运行不正确,因为我无法通过 default-steam
标志:
clang++ --cuda-gpu-arch=sm_35 -L/usr/local/cuda/lib64 *.cu -o app -lcudart_static -ldl -lrt -pthread
如何让 clang 将标志传递给 nvcc?
【问题讨论】:
这不是关于 clang 编译器标志的一般答案,但对于这个特定的 (-default-stream per-thread
),this blog 表示获得相同功能的另一种方法是“#define
@ 987654329@ 包含 CUDA 标头(cuda.h 或 cuda_runtime.h)之前的预处理器宏。”使用 clang 可能值得一试。
谢谢,这篇博文对这种情况非常有用。无论出于何种原因,在使用 clang 编译时添加定义不起作用(但在使用 nvcc 时会起作用?)。无论哪种方式,该帖子都为我提供了足够的信息来尝试找出其他东西。非常感谢!
请注意,定义必须在包含 cuda_runtime_api.h 之前就位。因此,正如博客所述,该定义不适用于 nvcc,因为在处理任何文件之前,nvcc 会将包含在您的文件中。我对clang不太熟悉,所以我不确定clang在处理cuda文件时是否这样做。可能确实如此,这可以解释为什么它在那里不起作用。
我尝试直接在 cuda_runtime.h 顶部添加定义,这对 nvcc 有效,但对 clang 无效。
【参考方案1】:
看来不可能。
nvcc 在后台调用 clang/gcc 并使用一些自定义生成的标志,然后调用 ptxas 和其他一些东西来创建二进制文件。
例如
nvcc -default-stream per-thread foo.cu
# Behind the scenes
gcc -custom-nvcc-generated-flag -DCUDA_API_PER_THREAD_DEFAULT_STREAM=1 -o foo.ptx
ptxas foo.ptx -o foo.cubin
从clang编译成CUDA时,clang直接编译成ptx,然后调用ptxas:
clang++ foo.cu -o app -lcudart_static -ldl -lrt -pthread
# Behind the scenes
clang++ -triple nvptx64-nvidia-cuda foo.cu -o foo.ptx
ptxas foo.ptx -o foo.cubin
clang 从来没有真正调用过 nvcc。它只是针对 ptx 并调用 ptx 汇编器。
除非您知道 nvcc 将生成哪些自定义后端标志并在调用 clang 时手动包含它们,否则我不确定您是否可以自动从 clang 传递一个 nvcc 标志。
【讨论】:
如果需要在包含 cuda_runtime.h 之前定义宏,则需要通过-D
将其传递给 clang。在引擎盖下,clang 确实预先包含了一堆 CUDA 头文件(nvcc 也是如此),因此在源代码中定义宏不会产生影响,因为编译器 在包含 cuda_runtime 之后会看到.h.【参考方案2】:
如果您仅在主机端使用特定于 clang 的功能,而在设备端实际上并不需要它 - 您可能正在寻找这个:
https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/
正如@Increasingly-Idiotic 指出的那样——我相信clang 不会在内部“调用”nvcc,因此我认为你不能向它传递参数。
【讨论】:
以上是关于如何将编译器标志从 clang 传递给 nvcc的主要内容,如果未能解决你的问题,请参考以下文章
如何将编译器标志从 Autoconf 传递给 Automake?
Visual Studio 2019 LLVM clang 标志
使用带有 nvcc 的 -G 标志编译为 cubin 后,Cublas 无法在内核中工作