2017-08-31 83 views
0

我试图将double数组复制到设备上的一块常量内存。但是得到cudaInvalidValue错误。cuda-cudaInvalidValue error当cudaMemcpyToSymbol

这是我的代码。

#define kCIELEN 95 // length of CIE_X[] 

const double CIE_X[] = { 
     1.299000e-04, 2.321000e-04, 4.149000e-04, 7.416000e-04, 1.368000e-03, 
     2.236000e-03, 4.243000e-03, 7.650000e-03, 1.431000e-02, 2.319000e-02, 
     4.351000e-02, 7.763000e-02, 1.343800e-01, 2.147700e-01, 2.839000e-01, 
     3.285000e-01, 3.482800e-01, 3.480600e-01, 3.362000e-01, 3.187000e-01, 
     2.908000e-01, 2.511000e-01, 1.953600e-01, 1.421000e-01, 9.564000e-02, 
     5.795001e-02, 3.201000e-02, 1.470000e-02, 4.900000e-03, 2.400000e-03, 
     9.300000e-03, 2.910000e-02, 6.327000e-02, 1.096000e-01, 1.655000e-01, 
     2.257499e-01, 2.904000e-01, 3.597000e-01, 4.334499e-01, 5.120501e-01, 
     5.945000e-01, 6.784000e-01, 7.621000e-01, 8.425000e-01, 9.163000e-01, 
     9.786000e-01, 1.026300e+00, 1.056700e+00, 1.062200e+00, 1.045600e+00, 
     1.002600e+00, 9.384000e-01, 8.544499e-01, 7.514000e-01, 6.424000e-01, 
     5.419000e-01, 4.479000e-01, 3.608000e-01, 2.835000e-01, 2.187000e-01, 
     1.649000e-01, 1.212000e-01, 8.740000e-02, 6.360000e-02, 4.677000e-02, 
     3.290000e-02, 2.270000e-02, 1.584000e-02, 1.135916e-02, 8.110916e-03, 
     5.790346e-03, 4.106457e-03, 2.899327e-03, 2.049190e-03, 1.439971e-03, 
     9.999493e-04, 6.900786e-04, 4.760213e-04, 3.323011e-04, 2.348261e-04, 
     1.661505e-04, 1.174130e-04, 8.307527e-05, 5.870652e-05, 4.150994e-05, 
     2.935326e-05, 2.067383e-05, 1.455977e-05, 1.025398e-05, 7.221456e-06, 
     5.085868e-06, 3.581652e-06, 2.522525e-06, 1.776509e-06, 1.251141e-06 
}; 

__constant__ double *dev_CIE_X; 

cudaStatus = cudaMalloc((void**)&dev_CIE_X, kCIELEN * sizeof(double)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
} 

// below do not work, so try to use a pointer `*ciex` 
// cudaStatus = cudaMemcpyToSymbol(dev_CIE_X, &CIE_X, kCIELEN * sizeof(double)); 

double *ciex = new double[kCIELEN]; 
for (int i = 0; i < kCIELEN; i++) { 
    ciex[i] = CIE_X[i]; 
} 


cudaStatus = cudaMemcpyToSymbol(dev_CIE_X, &ciex, kCIELEN * sizeof(double)); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMemcpy failed!"); 
    } 

link,它说cudaInvalidValue是由于一个或多个传递给API调用的参数之一是不值的可接受范围内。

但我想我通过两个指针,复制项目的大小是正确的。那么问题是什么?

回答

2

此:

__constant__ double *dev_CIE_X; 

cudaStatus = cudaMalloc((void**)&dev_CIE_X, kCIELEN * sizeof(double)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
} 

是非法的。 __constant__无法动态分配内存,并且无法以此方式直接从主机操作设备符号。你可以这样做:

__constant__ double *dev_CIE_X; 
double *h_dev_CIE_X; 
cudaMalloc((void**)&h_dev_CIE_X, kCIELEN * sizeof(double)); 

cudaMemcpyToSymbol(dev_CIE_X, &h_dev_CIE_X, sizeof(double)); 

// populate CIE_X 

cudaMemcpy(h_dev_CIE_X, &CIE_X[0], kCIELEN * sizeof(double), cudaMemcpyHostToDevice); 

但你要明白,阵列存储在全局存储器中,只有指针值存储在常量内存。

你可能需要的是这样的:

__constant__ double dev_CIE_X[kCIELEN]; 

// populate CIE_X 

cudaMemcpyToSymbol(dev_CIE_X, &CIE_X[0], kCIELEN * sizeof(double)); 

即静态声明常量存储器阵列,然后将主机的数据复制到阵列。

+0

谢谢。我只是混淆了动态分配的指针是否可以用作常量内存变量。那么,如果我有一个自定义的类,例如'Vector3',并且我想使用常量内存来存储'Vector3'类型的某个变量,我可以使用'__constant__ Vector3 a'?它是否是非内置类型的问题?如果这是可行的,我应该考虑将自定义类变量存储在常量变量中时的空间限制问题吗? –