CUDA 5.5 cudaMemcpyToSymbol,__constant__和范围外错误

CUDA 5.5 cudaMemcpyToSymbol, __constant__ and out of scope error

本文关键字:范围 错误 constant cudaMemcpyToSymbol CUDA      更新时间:2023-10-16

我正在尝试编译一个CUDA示例,它具有;

cuda.cu:

__constant__ unsigned VERTICES;
__constant__ unsigned TRIANGLES;

以及main.cpp中的相应代码;

cudaMemcpyToSymbol(VERTICES, &verticesNo, sizeof(int));
cudaMemcpyToSymbol(TRIANGLES, &trianglesNo, sizeof(int));

如何避免编译main.cpp时出现"VERTICES not declared in this scope"错误?

TIA。

欢呼,

CUDA __constant__变量具有文件作用域链接。这意味着cudaMemcpyToSymbol必须位于定义__constant__变量的相同.cu文件中。

您可以向.cu文件添加一个包装器函数,并从.cpp文件中调用该函数。

cuda.cu样本:

__constant__ unsigned VERTICES;
__constant__ unsigned TRIANGLES;
void wrapper_fn(unsigned *verticesNo, unsigned *trianglesNo)
{
  cudaMemcpyToSymbol(VERTICES, verticesNo, sizeof(unsigned));
  cudaMemcpyToSymbol(TRIANGLES, trianglesNo, sizeof(unsigned));
}

然后只调用main.cpp.中的wrapper_fn

CUDA由nvcc编译器定义,nvcc编译器本身是C99的扩展。听起来你真正想做的是分离CUDA,这样你就有了一个通用的头文件。然后您可以从C或C++中使用它。我个人更喜欢使用C++中的数据,因此我发现最好的方法是使用以下文件和包含路径:

               WRAPPER_HEADER.h          CUDA_HEADER.cuh
                 /                         /       
                /                         /         
            #include      #include    #include     #include
              /                         /             
             /                         /               
            /                         /                 
  CALL.cpp/CALL.c            CUDA_WRAPPER.cu         CUDA_KERNEL.cu

CALL.c/CALL.cpp是c/c++,包含您想要调用包装函数的任何内容

CUDA_WRAPPER.cu是包装函数,它:

  • 使用cudaMalloc/cudaMemcpy/cudaMemcpyToSymbol/cudaFree创建/释放设备内存,并管理从C或C++调用的原始调用函数的I/O
  • 在内核<lt;>>(…)格式

WRAPPER_HEADER.h包含一个C版本的:

  • 包装器函数的声明(必须仅在C99中编写)
  • 通用C形式的常量
  • 每个线程或每个块的输入不同
  • 计算结果的指针
  • 每个块的线程数
  • 块的数量

CUDA_HEADER.cuh包含:

  • 包装器可以通过cudaMemcpyToSymbol(…)写入的__constant__内存的声明
  • 使用__global__说明符的内核函数的声明

CUDA_KERNEL.cu包含:

  • 内核__global__ void内核(…)函数的实现
  • __device__说明符声明的设备函数的声明和实现
  • __shared__内存的声明(它只有一个块的生存期,所以不能根据我所能告诉的从包装器调用……任何人都可以随意更正)

CUDA文献中已经展示了其中的一些内容,我喜欢它,因为它确实将CUDA C作为一种专门的语言来区分。只有在处理设置和运行内核时,它才是必要的。