【发布时间】:2018-12-20 03:07:37
【问题描述】:
如果想要将阵列从主机复制到设备,请执行 cudamalloc 和 cudaMemcpy。但是为了减少麻烦,只需做 cudaMallocManaged 没有前两件事,生活从未如此简单。 代码看起来像这样(或多或少)
__global__ void convert(float kelvin[], float celsius[]) //can pass
arrays in kernel
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i<N)
kelvin[i]=celsius[i]+273.15;
}
int main()
{
float *celsius =(float *)malloc(N*sizeof(float));
float *kelvin =(float *)malloc(N*sizeof(float));
cudaMallocManaged(&celsius, N*sizeof(float));
cudaMallocManaged(&kelvin, N*sizeof(float));
// init celsius here
dim3 blocksPerGrid(1,1,1); //use only one block
dim3 threadsPerBlock(N,1,1); //use N threads in the block
convert<<<blocksPerGrid, threadsPerBlock>>>(kelvin,celsius);
cudaDeviceSynchronize();
//Doing stuff with the output here
return 0;
}
前面的例子对我来说似乎很清楚。 但是,怎么办 cudaMallocManaged 用于 2D 和 3D 数组?我一直在努力
__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N])
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < N && j < N)
C[i][j] = A[i][j] + B[i][j];
}
int main()
{ // I thonk, 2D arrays can be passed as pointer to pointers
float **A = (float **)malloc(N*N*sizeof(float));
float **B = (float **)malloc(N*N*sizeof(float));
float **C = (float **)malloc(N*N*sizeof(float));
cudaMallocManaged(&A, N*N*sizeof(float));
cudaMallocManaged(&B, N*N*sizeof(float));
cudaMallocManaged(&C, N*N*sizeof(float));
A[N][N]={{1,0,0},{0,1,0},{0,0,1}};
B[N][N]={{1,0,0},{0,1,0},{0,0,1}};
dim3 threadsPerBlock(16, 16);
dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);
MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
//outputs and all
}
但是,它显示以下错误
matrix_add.cu(22): error: too many initializer values
matrix_add.cu(25): error: argument of type "float **" is incompatible with parameter of type "float (*)[3]"
非常感谢您的帮助。
【问题讨论】:
-
“二维数组”不能作为指针传递。为什么所有东西都分配了两次?
-
@talonmies ,因为我已经在 CPU 中分配了内存,所以我也必须在 cuda 设备中分配它。这里 cudaMallocManaged 在 GPU 中分配相同的内存。至少我是这么认为的
-
你想错了。 malloc 调用是不必要且不正确的,就像代码中的其他所有内容一样。我建议您重新阅读上一个问题的答案中的所有内容,因为您显然不明白那里告诉您的内容。
标签: cuda