为 cuda 和非 cuda 编译器编写代码

Writing code for cuda and non-cuda compilers

提问人:tommsch 提问时间:7/13/2023 更新时间:7/13/2023 访问量:64

问:

问题:我们正在编写 Cuda 代码,这些代码也应该可以由非 cuda 编译器编译(我们使用:nvcc、gcc 和 clang。 由于 Cuda 需要这些注释,因此我们通过在每个相关文件中包含以下标头来解决它:__host__ __device__

我们的解决方案:

// CudaTags.hpp
#ifndef CUDAFLAGS
    #define CUDAFLAGS
    #ifndef __CUDACC__
        #define __host__
        #define __device__
    #endif
#endif

因此,我们可以在源文件中执行以下操作:

#include "CudaTags.hpp"
__host__ __device__ func();

问题:到目前为止,我没有看到这种方法有任何问题(除了,请参阅下面的注释)。因此

  • 你看到我遗漏的任何问题了吗?
  • 还有什么其他可能性可以解决这个问题?

注意:我知道,我的解决方案是 UB,因为我使用以两个下划线开头的标识符。但也要注意,这不太可能导致 UB,因为主机编译器永远不会将此标识符用于主题本身(因为 Cuda 已经使用了它们)。

我当然也可以

#ifndef CUDAFLAGS2
    #define CUDAFLAGS2
    #ifndef __CUDACC__
        #define CUDA_HOST
        #define CUDA_DEVICE
        #define CUDA_MANAGED
        #define CUDA_GLOBAL
    #else
        #define CUDA_HOST    __host__
        #define CUDA_DEVICE  __device__
        #define CUDA_MANAGED __managed__
        #define CUDA_GLOBAL  __global__
    #endif
#endif

并将其用作

CUDA_HOST CUDA_DEVICE void func();

但是使用这种方法,我必须使用特殊名称,破坏全局命名空间,它看起来非常丑陋。

C++ CUDA 预处理器

评论

0赞 Quxflux 7/13/2023
这取决于您要实现的函数类型,但通常我可以标记这些函数并使用 --expt-relaxed-constexpr 进行编译。然后,共享功能可以由 CUDA 和非 CUDA 编译器编译,无需宏魔术。constexpr
0赞 tommsch 7/13/2023
@Quxflux 我犹豫是否要使用它,因为 1) 这个功能已经实验了很多年了,2) C++20 年代的新 constexpr 规则允许内存分配,我认为这仍然有效。您能否详细说明一下,您如何以及何时使用它,存在哪些陷阱以及如何防止未捕获的逻辑错误?
0赞 paleonix 7/15/2023
另一种解决方案是定义自己的宏,以便在函数前面使用。看看 gsl-lite 是如何做到的。

答: 暂无答案