什么是__CUDABE__和__CUDA_LIBDEVICE__?

时间:2018-04-13 10:07:11

标签: gcc cuda

让我们说我对预处理(使用gcc)hpp / cpp文件感兴趣,这些文件包含CUDA内核声明。我希望预处理器不要废弃__global__说明符,否则我将无法链接.cu文件中的定义。

例如,文件t1.hpp

__global__ void foo(int* v, int n);

预处理:

gcc -E t1.hpp  -I/usr/local/cuda/include -include cuda_runtime.h

但结果会废弃全球!:

...    
# 1888 "/usr/local/cuda/include/cuda_runtime.h"
#pragma GCC diagnostic pop
# 1 "<command-line>" 2
# 1 "t1.hpp"
 void foo();

但如果我在CUDA 9.0+中定义__CUDABE__(在CUDA 8.0上)或__CUDA_LIBDEVICE__,我就可以保留这些信息:

gcc -E t1.hpp  -I/usr/local/cuda/include -include cuda_runtime.h -D__CUDABE__

最终结果:

...
# 1888 "/usr/local/cuda/include/cuda_runtime.h"
#pragma GCC diagnostic pop
# 1 "<command-line>" 2
# 1 "t1.hpp"
__attribute__((global)) void foo();

所以我的问题是,__CUDABE____CUDA_LIBDEVICE__是什么,以及可能是副作用。

我还看到clang在__clang_cuda_runtime_wrapper.h中定义了这些宏。那么这可以安全吗?

1 个答案:

答案 0 :(得分:1)

由于它没有在任何地方记录,它是他们使用的某种内部标志(可以,因为你已经注意到编译器之间的变化),所以你可能不应该依赖它。它在crt/host_defines.h中定义,没有很好的文档记录,所以我无法破译它的含义。

有没有理由不能使用nvcc预处理文件? 这应该做你想做的事情,并用正确的参数调用gcc(至少在我的系统上):

nvcc -E --x=cu t1.hpp`

如果由于某种原因无法使用nvcc,则可以始终以详细模式(nvcc -E -v --x=cu t1.hpp)调用它,并查看它设置的标志。在我的带有CUDA 9.1的linux系统上,我得到了:

gcc -std=c++14 -D__CUDA_ARCH__=300 -E -x c++ \
    -DCUDA_DOUBLE_MATH_FUNCTIONS -D__CUDACC__ \
    -D__NVCC__  "-I/opt/cuda/bin/..//include" \
    -D"__CUDACC_VER_BUILD__=85" -D"__CUDACC_VER_MINOR__=1" \
    -D"__CUDACC_VER_MAJOR__=9" -include "cuda_runtime.h" \
    -m64 "t1.hpp"

但是,您可能必须为要使用的每个CUDA版本执行此操作,因为这些标记可能会更改。