问题: 我们正在编写 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();
问题: 到目前为止,我没有发现这种方法有任何问题(除了见下面的Note)。因此,
注意:我知道,我的解决方案是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();
但是用这种方法我必须使用特殊的名称,破坏全局命名空间,它看起来非常难看。
。
#if defined(__CUDACC__)
#define HOST_FUN __host__
#define DEVICE_FUN __device__
#define HOST_DEVICE_FUN __host__ __device__
#include <cuda_runtime.h>
#else
#define HOST_FUN
#define DEVICE_FUN
#define HOST_DEVICE_FUN
#endif
此设置自动处理 GPU 架构的编译,定义 CUDA 设备、主机和主机设备的函数。对于内核,您可以使用相同的宏编写 CPU 和 GPU 版本:
#ifdef __CUDACC__
__global__ void my_gpu_kernel(){}
#else
void my_cpu_kernel(){}
#endif
此方法可确保您的代码针对 CPU 和 GPU 环境进行编译。