所以我试图将锯齿状阵列从主机复制到设备。首先,这是我目前对cudaMalloc和cudaMemcpy的理解:
cudaMalloc获取指向内存块的指针。
cudaMemcpy获取指向要复制到的内存块的指针。
如果我错了请纠正我。
现在这是我的代码不起作用(编译正常但没有输出):
__global__ void kernel(int** arr)
{
for (int i=0; i<3; i++)
printf("%d\n", arr[i][0]);
}
int main()
{
int arr[][3] = {{1},{2},{3}}; // 3 arrays, 1 element each
int **d_arr;
cudaMalloc((void**)(&d_arr), sizeof(int*)*3); // allocate for 3 int pointers
for (int i=0; i<3; i++)
{
cudaMalloc( (void**) &(d_arr[i]), sizeof(int) * 1 ); // allocate for 1 int in each int pointer
cudaMemcpy(d_arr[i], arr[i], sizeof(int) * 1, cudaMemcpyHostToDevice); // copy data
}
kernel<<<1,1>>>(d_arr);
cudaDeviceSynchronize();
cudaDeviceReset();
}
那我在这里做错了什么? 干杯
答案 0 :(得分:1)
我发现了原因,这是因为cudaMalloc和cudaMemcpy期望指针存在于主机上而不是设备上。
在我的for循环中,我试图在主机上运行的代码中填充设备上存在的指针!
正确的方法是创建一个中间变量,主机上指向设备内存的指针,用整数填充它,然后将该指针复制到锯齿状数组(指针上的指针)!
这是正确的版本:
__global__ void kernel(int** arr)
{
for (int i=0; i<3; i++)
printf("%d\n", arr[i][0]);
}
int main()
{
int arr[][3] = {{1},{2},{3}}; // 3 arrays, 1 element each
int **d_arr;
cudaMalloc((void***)(&d_arr), sizeof(int*)*3); // allocate for 3 int pointers
for (int i=0; i<3; i++)
{
int* temp;
cudaMalloc( (void**) &(temp), sizeof(int) * 1 ); // allocate for 1 int in each int pointer
cudaMemcpy(temp, arr[i], sizeof(int) * 1, cudaMemcpyHostToDevice); // copy data
cudaMemcpy(d_arr+i, &temp, sizeof(int*), cudaMemcpyHostToDevice);
}
kernel<<<1,1>>>(d_arr);
cudaDeviceSynchronize();
cudaDeviceReset();
}
答案 1 :(得分:0)
您的内核调用printf()
,其中 曾经是(直到CC2.0)主机功能。一切都还可以。 ;)
cudaMemcpy((void*)d_arr, (void*)arr, sizeof(int*)*3, cudaMemcpyHostToDevice);
将主机上的阵列内存地址复制到设备上。这是没有意义的。由于您现在有指向设备上主机内存的指针。
您不能在CUDA中以特定方式分配2d阵列。请参阅http://www.stevenmarkford.com/allocating-2d-arrays-in-cuda/。