Struct 如何在CUDA中定义dim3结构的常量数组
我正在编写一些CUDA代码以在设备上运行。代码将使用两个常量值的查找表。第一个是256个无符号整数的数组,我将其声明为:Struct 如何在CUDA中定义dim3结构的常量数组,struct,cuda,constants,static-initialization,Struct,Cuda,Constants,Static Initialization,我正在编写一些CUDA代码以在设备上运行。代码将使用两个常量值的查找表。第一个是256个无符号整数的数组,我将其声明为: __constant__ uint16_t edgeTable[256]={ 0x000, 0x019, ... etc. }; 这看起来很好 第二个是dim3的固定大小数组,我尝试了以下方法: __constant__ dim3 offsets[8] = { {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, ... et
__constant__
uint16_t edgeTable[256]={
0x000,
0x019,
... etc.
};
这看起来很好
第二个是dim3的固定大小数组,我尝试了以下方法:
__constant__
dim3 offsets[8] = {
{0, 0, 0}, {0, 0, 1}, {0, 1, 0},
... etc
};
编译器反对的对象。出现以下错误消息:
error: dynamic initialization is not supported for __device__, __constant__ and __shared__ variables.
也许我误解了动态初始化,但在我看来,这是静态初始化,编译器可以计算出所有内容的大小,并提供所有值
我错过了什么
我怎样才能实现我想做的事
谢谢
我使用Ubuntu 14.04的CUAD7.5工具包,GCC 4.84/P>< P>这个问题的重要特征是CUDA使用C++编译模型,DIM3被当作一个类。因此,尽管:
dim3 foo = {1,1,1};
在C++11中是合法的,因为参数化构造函数初始化支持,这:
__constant__ dim3 foo = {1,1,1};
不是,因为这意味着常量内存对象的动态初始化,CUDA执行模型不允许这样做
如果恒定内存方面对您很重要,并且您想要dim3的便利性,您可以这样做:
#include <cstdio>
__constant__ int offsets[3*8];
__global__ void kernel()
{
if (threadIdx.x < 8) {
dim3 val = *reinterpret_cast<dim3*>(&offsets[3*threadIdx.x]);
printf("%d (%d,%d,%d)\n", threadIdx.x, val.x, val.y, val.z);
}
}
void setup_offsets()
{
// This requires C++11 support
dim3 ovals[8] = { {0,0,0},
{1,0,0}, {0,1,0}, {0,0,1},
{1,1,0}, {1,0,1}, {0,1,1},
{1,1,1} };
cudaMemcpyToSymbol(offsets, &ovals[0], sizeof(ovals));
}
int main(void)
{
setup_offsets();
kernel<<<1,8>>>();
cudaDeviceSynchronize();
cudaDeviceReset();
return 0;
}
这有点老套,但可能是在这种情况下你所能期望的最好的。查看PTX的代码,编译器已经正确地发射了LD C.U32来获取DIM3的每个成员。< P>这个问题的重要特征是CUDA使用C++编译模型,DIM3被当作一个类。因此,尽管:
dim3 foo = {1,1,1};
在C++11中是合法的,因为参数化构造函数初始化支持,这:
__constant__ dim3 foo = {1,1,1};
不是,因为这意味着常量内存对象的动态初始化,CUDA执行模型不允许这样做
如果恒定内存方面对您很重要,并且您想要dim3的便利性,您可以这样做:
#include <cstdio>
__constant__ int offsets[3*8];
__global__ void kernel()
{
if (threadIdx.x < 8) {
dim3 val = *reinterpret_cast<dim3*>(&offsets[3*threadIdx.x]);
printf("%d (%d,%d,%d)\n", threadIdx.x, val.x, val.y, val.z);
}
}
void setup_offsets()
{
// This requires C++11 support
dim3 ovals[8] = { {0,0,0},
{1,0,0}, {0,1,0}, {0,0,1},
{1,1,0}, {1,0,1}, {0,1,1},
{1,1,1} };
cudaMemcpyToSymbol(offsets, &ovals[0], sizeof(ovals));
}
int main(void)
{
setup_offsets();
kernel<<<1,8>>>();
cudaDeviceSynchronize();
cudaDeviceReset();
return 0;
}
这有点老套,但可能是在这种情况下你所能期望的最好的。查看PTX中的代码,编译器正确地发射了LD C.U32来获取DIM3../P>的每个成员可能是愚蠢的问题——你是否通过了标志使C++ 11?参数化构造函数初始化DIM3是C++之前不支持C++的类,也许你的问题的答案是这实际上是一种动态初始化的形式。这些变量类型不支持上述和动态初始化,正如编译器所指出的,无论c++11编译器开关如何。作为一种可能的解决方法,您可以创建一个int数组,静态初始化为_uconstant _uuint,然后将其转换为内核代码中的dim3数组,可能类似于。我想你自己可能已经找到了这样的解决方法,所以,我不是说这是一个答案!谢谢我确实通过了-std=c++11,但是完全没有考虑到结构是一个类,因此当然会被动态初始化这一事实。我想,Robert Crovella,你的答案是我唯一能做的…可能是愚蠢的问题——你是否通过了标志使C++ 11?参数化构造函数初始化DIM3是C++之前不支持C++的类,也许你的问题的答案是这实际上是一种动态初始化的形式。这些变量类型不支持初始化,正如编译器所指出的,无论c++11编译器开关如何。作为一种可能的解决方法,您可以创建一个int数组,静态初始化为_uconstant _uuint,然后将其转换为内核代码中的dim3数组,可能类似于。我想你自己可能已经找到了这样的解决方法,所以,我不是说这是一个答案!谢谢我确实通过了-std=c++11,但是完全没有考虑到结构是一个类,因此当然会被动态初始化这一事实。我想@Robert Crovella你的回答是我唯一能做的。。