0

我正在尝试使用 MSVS 2012 和 CUDA 编译一个包含内核的程序。我使用共享内存,但与关于同一问题的这个问题不同,我只将我的变量名用于此内核的共享内存一次,因此不存在重新定义的问题。使用这样的代码:

template<typename T>
__global__ void mykernel(
    const T* __restrict__ data,
    T*       __restrict__ results) 
{
    extern __shared__ T warp_partial_results[];
    /* ... */
    warp_partial_results[lane_id] = something;
    /* ... */
    results[something_else] = warp_partial_results[something_else];
    /* ... */
}

它被实例化为几种类型(例如float,int,unsigned int),我得到了可怕的

declaration is incompatible with previous "warp_partial_results"

信息。什么可能导致这种情况?

4

1 回答 1

3

CUDA 不会立即在模板函数中“支持”动态分配的共享内存数组,因为它(显然)会生成这些 extern 的实际定义。如果您为多种类型实例化模板化函数,则定义会发生冲突。

一种解决方法是通过类以模板专业化的形式提供。看:

http://www.ecse.rpi.edu/~wrf/wiki/ParallelComputingSpring2015/cuda/nvidia/samples/0_Simple/simpleTemplates/sharedmem.cuh

您可以使用以下解决方法:

template<class T> __global__ void foo( T* g_idata, T* g_odata)
{
    // shared memory
    // the size is determined by the host application

    SharedMem<T> shared;
    T* sdata = shared.getPointer();

    // .. the rest of the code remains unchanged!
}

*对每种类型getPointer()都有一个专门的实现,它返回一个不同的指针,例如or等​​。extern __shared__ float* shared_mem_floatextern __shared__ int* shared_mem_int

(*) - 并不真地。在 NVidia 提供的头文件中,它们专门针对一些基本类型,仅此而已。

于 2013-12-10T15:48:22.167 回答