【问题标题】:two-dimensional arrays in CUDACUDA 中的二维数组
【发布时间】:2021-04-03 19:44:16
【问题描述】:

我正在练习这个简单的代码,它接受一个二维数组并将它们与 CUDA 相加。最后,C的结果不是我接受的。另外,我想知道是否可以使用 vector 代替 c 样式的数组。

#include <iostream>
using namespace std; 
#define N 2   
__global__ void MatAdd(double** a, double** b,
                       double** c)
{
    int i = threadIdx.x;
    int j = threadIdx.y;
    c[i][j] = a[i][j] + b[i][j];
}

int main()
{

    
    double a[2][2]= {{1.0,2.0},{3.0,4.0}};
    double b[2][2]= {{1.0,2.0},{3.0,4.0}};
    double c[2][2]; // it will be the result! 
    double**  a_d; 
    double**  b_d;
    double**  c_d; 
    int d_size = N * N * sizeof(double);
    int numBlocks = 1;
        dim3 threadsPerBlock(N, N);
        
        cudaMalloc(&a_d, d_size);
        
        cudaMalloc(&b_d, d_size);
        
        cudaMalloc(&c_d, d_size);
        
        cudaMemcpy(a_d, a, d_size, cudaMemcpyHostToDevice);
    
        cudaMemcpy(b_d, b, d_size, cudaMemcpyHostToDevice);
        
        cudaMemcpy(c_d, c, d_size, cudaMemcpyHostToDevice);
        
        MatAdd<<<numBlocks, threadsPerBlock>>>(a_d, b_d, c_d);
        
        //cudaDeviceSynchronize();
        cudaMemcpy(c, c_d, d_size, cudaMemcpyDeviceToHost);
     
     for (int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            
            cout<<c[i][j]<<endl;    
        }
     
    }
    return 0; 
    
   
}

【问题讨论】:

标签: c++ parallel-processing cuda


【解决方案1】:

在这种情况下,您不能使用double** 类型。或者,您应该使用扁平数组,其中包含 double*-type 变量中给定矩阵的所有值。

问题的核心位于以下行(以及类似的下一行):

cudaMemcpy(a_d, a, d_size, cudaMemcpyHostToDevice);

在这里您假设aa_d 是兼容的类型,但它们不是。 double**-typed 变量是一个指针,它引用内存中的一个或多个指针(通常是一个指针数组,引用许多不同的 double-typed 数组),而 double*-typed 变量或静态 2D C 数组引用内存中的连续位置。

请注意,您可以使用matrix[N*i+j] 访问矩阵的给定(i,j) 单元格,其中N 是列数,假设矩阵是double* 类型的扁平矩阵并使用行优先排序

【讨论】:

  • 在函数原型上更改为 *double 并将此 cudaMemcpy(a_d, a, d_size, cudaMemcpyHostToDevice) 更改为 cudaMemcpy((void**)&amp;a_d, a, d_size, cudaMemcpyHostToDevice); 给我的错误是:expression must have pointer-to-object type 其中 a 和 b 相加
  • 另外,有没有办法访问i ,j 而不是使用扁平矩阵?这个例子有点类似于没有使用扁平矩阵的 NVIDIA 网站
  • 你不需要cudaMemcpy 的演员表,也不需要a_d 的地址。请注意,静态多维 C 数组总是在内存中展平。另请注意,GPU 主要设计用于处理内存中的连续数据,因此多维数组经常被展平。我强烈建议您阅读CUDA programming guide。您尤其可以在第 22 页找到矩阵乘法的示例。
  • This 可能感兴趣。如果您愿意,没有理由不能使用double** 和/或双下标数组。然而,扁平化建议是很好的传统智慧。您以前/现在删除的问题已经有一种可能的正确方法,用于双下标访问。
  • 有许多更新版本的编程指南可用。我不确定为什么有人会引用 CUDA 3.2 中超过 10 年的版本。随时可以在 docs.nvidia.com 上找到最新的文档
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 2019-08-08
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 2011-03-25
相关资源
最近更新 更多