c++ - CUDA Vision Studio 内核问题

标签 c++ c cuda

我有一个项目,我必须在 Visual Studio/CUDA 中使用包含 2 个随机数组 AB< 的 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 **"

对我应该做什么有什么建议吗?

最佳答案

  1. 首先,无论何时您在使用 CUDA 代码时遇到问题,我都建议您使用 proper CUDA error checking 并使用 cuda-memcheck(例如从命令行)运行您的代码。

  2. 这不是你想的那样:

    int *A[dim][dim];
    

    这是创建一个二维指针数组。您需要的是指向二维数组(int)的指针。

  3. 在 C 中,当您定义一个数组时,您不能为数组维度的元素分配任何内容:

    A[dim][dim]= (int *)malloc(dsize); 
    

    数组的大小只能达到 dim- 1。A[dim][dim] 不存在并且超出了数组定义的范围。这似乎与您对在 C 或 C++ 中使用二维数组的一般混淆有关。

  4. 这一行同样被打断(将数值分配给与未分配指针关联的区域),进一步证明您对 C 中的二维数组感到困惑:

    *A[i][j]=rand() %5+1;
    
  5. 您对 d_Ad_Bd_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/

相关文章:

c++ - 在没有线程支持的程序加载的共享库中使用 C++11 多线程

C++可变参数问题

c++ - COM 服务器的奇怪行为

c - 分段故障点

请求变量时的 C++ 调用函数

performance - 在 CUDA profiler nvvp 中, "Shared/Global Memory Replay Overhead"是什么意思?它是如何计算的?

cudaMalloc 在 CUDA 中导致 "unknown errors"

c++ - 如何避免动态分配小对象?

c - 在 C 中传递参数

c++ - CUDA 和 C++ 函数问题 (Visual Studio 2013)