我在将设备中的数据复制回主机时遇到问题。我的数据排列在一个结构中:将数据从设备复制到主机时出现无效参数错误
typedef struct Array2D {
double* arr;
int rows;
int cols;
} Array2D;
arr
是'扁平'阵列。 rows
和cols
描述了尺寸。
下面的代码演示如何,我想回数据复制到主机:
h_output = (Array2D*) malloc(sizeof(Array2D));
cudaMemcpy(h_output, d_output, sizeof(Array2D), cudaMemcpyDeviceToHost);
double* h_arr = (double*) malloc(h_output->cols*h_output->rows*sizeof(double));
cudaMemcpy(h_arr, h_output->arr, h_output->cols*h_output->rows*sizeof(double), cudaMemcpyDeviceToHost);
h_output->arr = h_arr;
然而,在第四行的执行失败,CUDA错误11(无效参数)。我看不出为什么会发生这种情况。阵列的大小是正确的,我可以从主机访问h_output
和h_array
,并且都有“真实”地址。
EDIT 对不起,为更多的信息(=更多的代码)的请求后期应答。
我测试过,指针d_output->arr
是一个设备指针,通过尝试访问主机上设备指针的值。正如预期的那样,我没有被允许这样做,让我认为d_output->arr
实际上是一个有效的设备指针。
该代码的目标是使用四阶Runge-Kutta方法求解Thiele微分方程。
class CalculationSpecification
{
/* FUNCTIONS OMITTED */
public:
__device__ void RK4_n(CalculationSpecification* cs, CalcData data, Array2D* d_output)
{
double* rk4data = (double*)malloc((data.pdata->endYear - data.pdata->startYear + 1)*data.pdata->states*sizeof(double));
/* CALCULATION STUFF HAPPENS HERE */
// We know that rows = 51, cols = 1 and that rk4data contains 51 values as it should.
// This was confirmed by using printf directly in this function.
d_output->arr = rk4data;
d_output->rows = data.pdata->endYear - data.pdata->startYear + 1;
d_output->cols = data.pdata->states;
}
};
class PureEndowment : CalculationSpecification
{
/* FUNCTIONS OMITTED */
public:
__device__ void Compute(Array2D *result, CalcData data)
{
RK4_n(this, data, result);
}
};
__global__ void kernel2(Array2D *d_output)
{
/* Other code that initializes 'cd'. */
PureEndowment pe;
pe.Compute(d_output,cd);
}
void prepareOutputSet(Array2D* h_output, Array2D* d_output, int count)
{
h_output = (Array2D*) malloc(sizeof(Array2D));
cudaMemcpy(h_output, d_output, sizeof(Array2D), cudaMemcpyDeviceToHost); // After this call I can read the correct values of row, col as well as the address of the pointer.
double* h_arr = (double*) malloc(h_output->cols*h_output->rows*sizeof(double));
cudaMemcpy(h_arr, h_output->arr, h_output->cols*h_output->rows*sizeof(double), cudaMemcpyDeviceToHost)
h_output->arr = h_arr;
}
int main()
{
Array2D *h_output, *d_output;
cudaMalloc((void**)&d_output, sizeof(Array2D));
kernel2<<<1,1>>>(d_output);
cudaDeviceSynchronize();
prepareOutputSet(h_output, d_output, 1);
getchar();
return 0;
}
EDIT2
此外,我现在已经测试的设备上运行时的d_output->arr
值是相同的h_output->arr
在prepareOutputSet
第一cudaMemcpy
-call后的值。
错误的最可能的来源是'houtput-> arr'不是一个有效的设备指针。你能扩展一下你的代码来展示你如何分配和拷贝'd_output'的内容给设备吗? – talonmies 2012-02-23 13:36:13
'd_output'及其内容使用'malloc()'在设备上分配。我确信它包含实际的数据,因为我试着打印'd_output-> arr'的内容并获得了预期的输出。 – ssnielsen 2012-02-23 13:55:05
你的意思是'h_output' _及其内容_?因为'd_output'没有出现在你的示例代码中。 – pQB 2012-02-23 15:06:14