【问题标题】:How can I compile a CUDA program for sm_1X AND sm_2X when I have a surface declaration当我有表面声明时,如何为 sm_1X 和 sm_2X 编译 CUDA 程序
【发布时间】:2012-04-27 00:44:42
【问题描述】:

我正在编写一个使用表面(重新采样并写入纹理)以获得性能提升的库:

...
surface<void,  2> my_surf2D; //allows writing to a texture
...

目标平台 GPU 具有计算能力 2.0,我可以使用以下代码编译代码:

nvcc -arch=sm_20 ...

而且效果很好。

问题是当我尝试在我的笔记本电脑上开发和调试库时,该笔记本电脑具有计算能力为 1.1 的 NVIDIA ION GPU(我还希望我的库向后兼容)。我知道这个架构不支持表面,所以我在我的设备代码中使用了 nvcc 宏来为这个旧架构定义一个备用代码路径:

#if (__CUDA_ARCH__ < 200)
#warning using kernel for CUDA ARCH < 2.0
...
temp_array[...] =  tex3D(my_tex,X,Y,Z+0.5f);
#else
...
surf2Dwrite( tex3D(my_tex,X,Y,Z+0.5f), my_surf2D, ix*4, iy,cudaBoundaryModeTrap);
#endif

问题是当我这样做时:

nvcc -gencode arch=compute_11,code=sm_11

我收到此错误:

ptxas PTX/myLibrary.ptx, line 1784; fatal  : Parsing error near '.surf': syntax error

当我查看 PTX 文件时,可以看到表面声明:

.surf .u32 _ZN16LIB_15my_surf2DE;

如果我尝试在源代码中的表面声明周围放置一个类似的宏:

#ifdef __CUDACC__
#if __CUDA_ARCH__ < 200
#warning skipping surface declaration for nvcc trajectory
#else
surface ...
#endif
#else
#warning keeping surface declaration by default
surface ...
#endif

我收到一条错误消息,指出在将 cuda 表面绑定到数组的主机代码调用中未定义表面变量。我是否也应该在绑定函数周围添加宏

我不确定这是否可能,或者如果我在某个地方搞砸了,请帮忙。

【问题讨论】:

  • 您是否在表面声明以及设备代码内部的访问调用周围使用预处理器“保护”?
  • 您正在尝试做的事情听起来应该可以正常工作。您的错误中未定义哪个变量?
  • 我将更新我的帖子,详细介绍我如何尝试包装表面声明。

标签: c++ cuda macros c-preprocessor nvcc


【解决方案1】:

认为这个帖子应该显示为已回答...

我让它工作了(实际上很简单)。您必须在所有三个可能使用表面参考的地方放置一个宏,并小心正确使用宏(事实证明,__CUDACC__ 不是必需的)。

以下仅更改计算能力编译时的代码

表面声明:

//enable backwards compatability:
#if defined(__CUDA_ARCH__) & (__CUDA_ARCH__ < 200)
#warning skipping surface declarations for compute capability < 2.0
#else
surface<void,  2> my_surf2D; //allows writing to a texture
#endif

表面绑定:

#if defined(__CUDA_ARCH__) & (__CUDA_ARCH__ < 200)
#warning skipping cudaBindSurfaceToArray for compute capability < 2.0
...
#else
errorCode = cudaBindSurfaceToArray(my_surf2D, my_cudaArray2D);
#endif

和Surface写作:

#if defined(__CUDA_ARCH__) & (__CUDA_ARCH__ < 200)
#warning using kernel for compute capability < 2.0
...
temp_array[...] =  tex3D(my_tex,X,Y,Z+0.5f);
#else
...
surf2Dwrite( tex3D(my_tex,X,Y,Z+0.5f), my_surf2D, ix*4, iy,cudaBoundaryModeTrap);
#endif

这适用于虚拟和真实目标(分别为 -arch=compute_XX 和 -arch=sm_XX)。

感谢talonmiesRoger Dahl 为我指明了正确的方向,以及来自talonmiesthis answer 对nvcc/CUDA 宏也有很好的解释。

【讨论】:

  • 让我感到奇怪的是,表面定义和表面绑定都是宿主代码,理论上__CUDA_ARCH__ 没有在宿主代码中定义。但如果它有效,它就会有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多