我有一个项目,我必须在 Visual Studio/CUDA 中使用包含 2 个随机数组 A
和 B< 的 GPU 线程和 block 创建程序
用于在将结果存储到第三个数组 C
之前计算基于此等式的值:
C(1,j)=max(A(:,j)+max(B(:,j))
(注意:“:"运算符表示所有行)
这是我的内核函数
__global__ void mykernel(int **a, int **b,int **c,const int width)
{
int col= threadIdx.x;
int tempa=0;
int tempb=0;
for(int k=0;k<width;k++){
int maxA=a[k][col];
if (maxA>tempa){
tempa=maxA;
}
int maxB=b[k][col];
if (maxB>tempb){
tempb=maxB;
}
}
c[0][col] =tempa+tempb;
}
还有我的主要
int main()
{
const int dim= 5;
const int rows=5;
const int columns=5;
size_t dsize = rows*columns*sizeof(int);
//Αντίγραφα πινάκων δεδομένων της CPU
int *A[dim][dim];
int *B[dim][dim];
int *C[1][dim];
//Αντίγραφα πινάκων δεδομένων της GPU
int *d_A[dim][dim],*d_B[dim][dim],*d_C[1][dim];
//Εξασφάλιση μνήμης για τα αντίγραφα δεδομένων της CPU
A[dim][dim]= (int *)malloc(dsize);
B[dim][dim] = (int *)malloc(dsize);
C[1][dim]= (int *)malloc(dsize);
//Γέμισμα των πινάκων με τυχαίες τιμές μεταξυ
for (int i=0;i<rows;i++)
for (int j=0;j<columns;j++){
*A[i][j]=rand() %5+1;
*B[i][j]=rand() %5+1;
}
//Εξασφάλιση μνήμης για τα αντίγραφα δεδομένων της GPU και αντιγραφή δεδομένων CPU προς GPU
cudaMalloc((void **)&d_A, dsize);
cudaMemcpy(d_A, A, dsize, cudaMemcpyHostToDevice);
cudaMalloc((void **)&d_B, dsize);
cudaMemcpy(d_B, B, dsize, cudaMemcpyHostToDevice);
cudaMalloc((void **)&d_C, dsize);
//Κλήση Kernel συνάρτησης στην GPU με χρήση 5 Threads σε 1 Block
mykernel<<<1,5>>>(d_A,d_B,d_C,dim);
//Αντιγραφή αποτελέσματος στην μνήμη της CPU
cudaMemcpy(C, d_C, dsize, cudaMemcpyDeviceToHost);
//Εκκαθάριση Μνήμης για CPU και GPU
free(A);
free(B);
free(C);
cudaFree(d_A); cudaFree(d_B); cudaFree(d_C);
while(1){};
return 0;
}
我想我的算法是正确的,但在这一行中我得到了以下错误:
行
mykernel<<<1,5>>>(d_A,d_B,d_C,dim);
错误
argument of type "int *(*)[5]" is incompatible with parameter of type "int **"
对我应该做什么有什么建议吗?
最佳答案
首先,无论何时您在使用 CUDA 代码时遇到问题,我都建议您使用 proper CUDA error checking 并使用
cuda-memcheck
(例如从命令行)运行您的代码。这不是你想的那样:
int *A[dim][dim];
这是创建一个二维指针数组。您需要的是指向二维数组(
int
)的指针。在 C 中,当您定义一个数组时,您不能为数组维度的元素分配任何内容:
A[dim][dim]= (int *)malloc(dsize);
数组的大小只能达到
dim
- 1。A[dim][dim]
不存在并且超出了数组定义的范围。这似乎与您对在 C 或 C++ 中使用二维数组的一般混淆有关。这一行同样被打断(将数值分配给与未分配指针关联的区域),进一步证明您对 C 中的二维数组感到困惑:
*A[i][j]=rand() %5+1;
您对
d_A
、d_B
和d_C
的处理同样有问题。
很明显,您想要在 CUDA 内核中使用二维数组,因此这里正确的方法可能是从一组 canonical examples 中选择一个方法。由于您在编译时似乎知道数组维度,我们将 leverage that 。这是一个显示模组的完整示例:
$ cat t1344.cu
#include <iostream>
const int dim = 5;
typedef int my_arr[dim];
__global__ void mykernel(my_arr *a, my_arr *b, my_arr *c,const int width)
{
int col= threadIdx.x;
int tempa=0;
int tempb=0;
for(int k=0;k<width;k++){
int maxA=a[k][col];
if (maxA>tempa){
tempa=maxA;
}
int maxB=b[k][col];
if (maxB>tempb){
tempb=maxB;
}
}
c[0][col] =tempa+tempb;
}
int main()
{
const int rows=dim;
const int columns=dim;
size_t dsize = rows*columns*sizeof(int);
//Αντίγραφα πινάκων δεδομένων της CPU;
my_arr *A, *B, *C;
//Αντίγραφα πινάκων δεδομένων της GPU
my_arr *d_A,*d_B,*d_C;
//Εξασφάλιση μνήμης για τα αντίγραφα δεδομένων της CPU
A = (my_arr *)malloc(dsize);
B = (my_arr *)malloc(dsize);
C = (my_arr *)malloc(dsize);
//Γέμισμα των πινάκων με τυχαίες τιμές μεταξυ
for (int i=0;i<rows;i++)
for (int j=0;j<columns;j++){
A[i][j]=rand() %5+1;
B[i][j]=rand() %5+1;
}
//Εξασφάλιση μνήμης για τα αντίγραφα δεδομένων της GPU και αντιγραφή δεδομένων CPU προς GPU
cudaMalloc((void **)&d_A, dsize);
cudaMemcpy(d_A, A, dsize, cudaMemcpyHostToDevice);
cudaMalloc((void **)&d_B, dsize);
cudaMemcpy(d_B, B, dsize, cudaMemcpyHostToDevice);
cudaMalloc((void **)&d_C, dsize);
//Κλήση Kernel συνάρτησης στην GPU με χρήση 5 Threads σε 1 Block
mykernel<<<1,5>>>(d_A,d_B,d_C,dim);
//Αντιγραφή αποτελέσματος στην μνήμη της CPU
cudaMemcpy(C, d_C, dsize, cudaMemcpyDeviceToHost);
for (int i = 0; i < dim; i++) std::cout << C[0][i] << std::endl;
//Εκκαθάριση Μνήμης για CPU και GPU
free(A);
free(B);
free(C);
cudaFree(d_A); cudaFree(d_B); cudaFree(d_C);
return 0;
}
$ nvcc -arch=sm_35 -o t1344 t1344.cu
$ cuda-memcheck ./t1344
========= CUDA-MEMCHECK
9
8
8
9
8
========= ERROR SUMMARY: 0 errors
$
我还没有完全验证结果,但它们对我来说似乎是合理的。
关于c++ - CUDA Vision Studio 内核问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47626429/