以下用C语言编写的内核更改了数组的单元格:
__global__ void test(int *mt[matrix_size])
{
mt[0][0]=12;
}
以下代码将内核结果复制到主机,但未将数组正确发送到主机:
int *matrix[matrix_size],*d_matrix[matrix_size];
for(int i=0;i<matrix_size;i++)
matrix[i] = (int *)malloc(n*n*sizeof(int));
for(int i=0;i<matrix_size;i++)
cudaMalloc((void**)&d_matrix[i],sizeof(int));
test<<<1,1>>>(d_matrix);
cudaMemcpy(*matrix,*d_matrix,n*n*sizeof(int),cudaMemcpyDeviceToHost);
printf("\n\n %d \n\n",matrix[0][0]); //the result is zero instead of 12
如何解决该问题?
答案 0 :(得分:0)
您在这里犯了很多错误。
根本原因是d_matrix
位于主机内存中,不能直接传递给内核。如果检查运行时错误,您将首先看到第一个cudaMemcpy
调用由于方向参数错误而失败,然后在修复该错误时,内核将失败并显示无效的地址错误。
要解决此问题,您需要在GPU上分配d_matrix
的副本,并将d_matrix
复制到该副本。这是因为要传递给内核的数组会衰减为指针,而不是按值传递。
类似这样的东西:
#include <cstdio>
const int n = 9;
const int matrix_size = 16;
__global__
void test(int *mt[matrix_size])
{
mt[threadIdx.x][0] = 12 + threadIdx.x;
}
int main()
{
int *matrix[matrix_size],*d_matrix[matrix_size];
for(int i=0;i<matrix_size;i++) {
matrix[i] = (int *)malloc(n * n * sizeof(int));
cudaMalloc((void**)&d_matrix[i], n * n * sizeof(int));
}
int **dd_matrix;
cudaMalloc(&dd_matrix, matrix_size * sizeof(int*));
cudaMemcpy(dd_matrix, d_matrix, matrix_size * sizeof(int *), cudaMemcpyHostToDevice);
test<<<1,matrix_size>>>(dd_matrix);
for(int i=0;i<matrix_size;i++) {
cudaMemcpy(matrix[i], d_matrix[i], n*n*sizeof(int), cudaMemcpyDeviceToHost);
printf("%d = %d \n", i, matrix[i][0]);
}
return 0;
}
运行时给出以下信息:
$ nvcc -g -G -arch=sm_52 -o bozocu bozocu.cu
$ ./bozocu
0 = 12
1 = 13
2 = 14
3 = 15
4 = 16
5 = 17
6 = 18
7 = 19
8 = 20
9 = 21
10 = 22
11 = 23
12 = 24
13 = 25
14 = 26
15 = 27
我相信更符合您的期望。