C++ CUDA中的二维阵列

C++ CUDA中的二维阵列,c++,parallel-processing,cuda,C++,Parallel Processing,Cuda,我正在练习这个简单的代码,它采用一个二维数组,并用CUDA对它们进行汇总。最后,C的结果不是我所接受的。另外,我想知道我是否可以使用向量而不是c样式的数组 #include <iostream> using namespace std; #define N 2 __global__ void MatAdd(double** a, double** b, double** c) { int i = threadIdx.x;

我正在练习这个简单的代码,它采用一个二维数组,并用CUDA对它们进行汇总。最后,C的结果不是我所接受的。另外,我想知道我是否可以使用向量而不是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; 
    
   
}
在这种情况下,不能使用双**类型。或者,您应该使用一个扁平数组,该数组包含双*-型变量中给定矩阵的所有值

问题的核心位于下面一行和下面的类似行中:

cudaMemcpya_d,a,d_尺寸,cudaMemcpyHostToDevice; 这里假设a和a_d是兼容类型,但它们不是。双**型变量是指内存中一个或多个指针的指针,通常是指引用多个不同双类型数组的指针数组,而双**型变量或静态2D C数组指内存中的连续位置


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

在函数原型上更改为*double,还可以将此cudaMemcpya_d,a,d_size,cudamemcpyhostto设备更改为cudaMemcpyvoid**&a_d,a,d_size,cudamemcpyhostodice;给我一个错误:表达式必须有指向对象类型的指针,其中a和b也是求和的,有没有办法访问i,j而不是使用展平矩阵?这个例子在某种程度上类似于NVIDIA网站,没有使用展平矩阵。你不需要在cudaMemcpy中使用演员阵容,也不需要使用a_d的地址。请注意,静态多维C数组在内存中总是平坦的。还要注意的是,GPU主要用于处理内存中的连续数据,因此多维数组会定期展平。我强烈建议你读这本书。你可以在第22页找到矩阵乘法的例子。可能有兴趣。如果愿意,没有理由不能使用双**和/或双下标数组。然而,扁平化建议是很好的传统智慧。您以前/现在删除的问题已经有了一种可能的正确方法,即双订阅访问。有更新版本的编程指南可用。我不知道为什么有人会引用CUDA 3.2的版本,这个版本已经超过10年了。最新文档可以在docs.nvidia.com上找到。这是否回答了您的问题?您遇到的不是CUDA问题,而是对不同类型多维数组如何工作的误解。请看这里的StackOverflow。还有一个教育性的例子。