我一直在寻找一种方法,将填充的阵列数组从主机传输到CUDA中的 device 。
我有什么:
我有一个函数来启动数组及其值:
double** weights; // globally defined in host
int init_weigths(){
weights = (double**) malloc(sizeof(double*) * SIZE);
for (int i = 0; i < SIZE; i++) {
weights[i] = (double*) malloc(sizeof(double) * getSize(i));
for (int j = 0; j < getSize(i); j++){
weights[i][j] = get_value(i,j);
}
}
}
我的(不工作)解决方案:
我设计了一个收集互联网上其他答案信息的解决方案,但没有人工作。我认为这是因为我的数组数组已经填满了信息,以及所包含数组的可变长度。
我所拥有的解决方案,即在所有cudaMemcpy
次来电,以及第二次和更进一步的cudaMalloc
来电中抛出“无效参数”错误;由cudaGetLastError()
检查。
解决方案就是这个:
double** d_weights;
int init_cuda_weight(){
cudaMalloc((void **) &d_weights, sizeof(double*) * SIZE);
double** temp_d_ptrs = (double**) malloc(sizeof(double*) * SIZE);
// temp array of device pointers
for (int i = 0; i < SIZE; i++){
cudaMalloc((void**) &temp_d_ptrs[getSize(i)],
sizeof(double) * getSize(i));
// ERROR CHECK WITH cudaGetLastError(); doesn't throw any errors ar first.
cudaMemcpy(temp_d_ptrs[getSize(i)], weights[getSize(i)], sizeof(double) * getSize(i), cudaMemcpyHostToDevice);
// ERROR CHECK WITH cudaGetLastError(); throw "invalid argument" error for now and beyond.
}
cudaMemcpy(d_weights, temp_d_ptrs, sizeof(double*) * SIZE,
cudaMemcpyHostToDevice);
}
作为附加信息,我已经简化了一些代码。包含在数组数组中的数组具有不同的长度(即SIZE2不是常数),这就是为什么我没有变平为一维数组。
此实施有什么问题?任何实现副本的想法?
EDIT2 : 我写的原始代码没问题。我编辑了代码以包含我所遇到的错误,并在下面包含了正确的答案(代码)。
答案 0 :(得分:1)
错误在于我使用数组总大小getSize(i)
作为分配和副本的索引。这是一个天真的错误,隐藏在真实代码的复杂性和冗长之中。
正确的解决方案是:
double** d_weights;
int init_cuda_weight(){
cudaMalloc((void **) &d_weights, sizeof(double*) * SIZE);
double** temp_d_ptrs = (double**) malloc(sizeof(double*) * SIZE);
// temp array of device pointers
for (int i = 0; i < SIZE; i++){
cudaMalloc((void**) &temp_d_ptrs[i],
sizeof(double) * getSize(i));
// ERROR CHECK WITH cudaGetLastError()
cudaMemcpy(temp_d_ptrs[i], weights[i], sizeof(double) * getSize(i), cudaMemcpyHostToDevice);
// ERROR CHECK WITH cudaGetLastError()
}
cudaMemcpy(d_weights, temp_d_ptrs, sizeof(double*) * SIZE,
cudaMemcpyHostToDevice);
}