3

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

...
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 表面绑定到数组的主机代码调用中未定义表面变量。我也应该在绑定函数周围添加宏吗?

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

4

1 回答 1

3

认为该线程应显示为已回答...

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

以下仅在编译计算能力 < 2.0 时更改代码

表面声明:

//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

和表面写作:

#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为我指明了正确的方向,以及来自talonmies的回答,其中也对 nvcc/CUDA 宏进行了很好的解释。

于 2012-04-16T07:44:14.297 回答