【发布时间】:2015-02-18 15:43:43
【问题描述】:
我想在一个程序中调用具有动态分配共享内存的模板化 CUDA 内核的不同实例。我的第一个天真的方法是写:
template<typename T>
__global__ void kernel(T* ptr)
{
extern __shared__ T smem[];
// calculations here ...
}
template<typename T>
void call_kernel( T* ptr, const int n )
{
dim3 dimBlock(n), dimGrid;
kernel<<<dimGrid, dimBlock, n*sizeof(T)>>>(ptr);
}
int main(int argc, char *argv[])
{
const int n = 32;
float *float_ptr;
double *double_ptr;
cudaMalloc( (void**)&float_ptr, n*sizeof(float) );
cudaMalloc( (void**)&double_ptr, n*sizeof(double) );
call_kernel( float_ptr, n );
call_kernel( double_ptr, n ); // problem, 2nd instantiation
cudaFree( (void*)float_ptr );
cudaFree( (void*)double_ptr );
return 0;
}
但是,无法编译此代码。 nvcc 给了我以下错误信息:
main.cu(4): error: declaration is incompatible with previous "smem"
(4): here
detected during:
instantiation of "void kernel(T *) [with T=double]"
(12): here
instantiation of "void call_kernel(T *, int) [with T=double]"
(24): here
我知道我遇到了名称冲突,因为共享内存被声明为 extern。然而,据我所知,如果我想在运行时定义它的大小,那是没有办法的。
所以,我的问题是:有什么优雅的方式来获得所需的行为吗?优雅是指没有代码重复等。
【问题讨论】:
-
可能是 CUDA 编译器的疏忽,因为 C++ 中允许这样做(没有
__shared__限定符)。