我正在尝试将一个double数组复制到设备上的一块常量内存中。但是得到cudaInvalidValue错误。
这是我的代码。
#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调用的一个或多个参数不在可接受的值范围内。
但我想我传了两个指针,复制项目的大小是正确的。那么问题是什么?
答案 0 :(得分: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));
即。静态地将数组声明为常量内存,然后将主机数据复制到该数组。