Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 如何使用嵌套for循环将两个二维(倾斜)数组相加?_Loops_Cuda_Multidimensional Array - Fatal编程技术网

Loops 如何使用嵌套for循环将两个二维(倾斜)数组相加?

Loops 如何使用嵌套for循环将两个二维(倾斜)数组相加?,loops,cuda,multidimensional-array,Loops,Cuda,Multidimensional Array,我是cuda的新手。我想把两个2d数组加在第三个数组中。 我使用以下代码: cudaMallocPitch((void**)&device_a, &pitch, 2*sizeof(int),2); cudaMallocPitch((void**)&device_b, &pitch, 2*sizeof(int),2); cudaMallocPitch((void**)&device_c, &pitch, 2*sizeof(int),2); 现在我的

我是cuda的新手。我想把两个2d数组加在第三个数组中。 我使用以下代码:

cudaMallocPitch((void**)&device_a, &pitch, 2*sizeof(int),2);
cudaMallocPitch((void**)&device_b, &pitch, 2*sizeof(int),2);
cudaMallocPitch((void**)&device_c, &pitch, 2*sizeof(int),2);
现在我的问题是,我不想把这些数组用作平坦的二维数组 在我的内核代码中,我希望di使用两个for循环&将结果放入第三个数组中,如

__global__ void add(int *dev_a ,int *dev_b,int* dec_c)
{
    for i=0;i<2;i++)
    { 
      for j=0;j<2;j++)
      {
        dev_c[i][j]=dev_a[i][j]+dev_b[i][j];
      }
    }
}
\uuuuu全局\uuuuuu无效添加(int*dev\u a,int*dev\u b,int*dec)
{

对于i=0;i简单的回答是,您不能。函数的作用与它的名字完全一样,它分配倾斜线性内存,其中的倾斜是GPU内存控制器和纹理硬件的最佳选择

如果希望在内核中使用指针数组,内核代码必须如下所示:

__global___ void add(int *dev_a[] ,int *dev_b[], int* dec_c[])
{
    for i=0;i<2;i++) { 
      for j=0;j<2;j++) {
        dev_c[i][j]=dev_a[i][j]+dev_b[i][j];
      }
    }
}
int ** h_a = (int **)malloc(2 * sizeof(int *));
cudaMalloc((void**)&h_a[0], 2*sizeof(int));
cudaMalloc((void**)&h_a[1], 2*sizeof(int));

int **d_a;
cudaMalloc((void ***)&d_a, 2 * sizeof(int *));
cudaMemcpy(d_a, h_a, 2*sizeof(int *), cudaMemcpyHostToDevice);
这会将分配的设备指针数组保留在d_a中,然后将其传递给内核

出于代码复杂性和性能方面的原因,您确实不想这样做,在CUDA代码中使用指针数组比使用线性内存的替代方法更难、更慢


为了说明在CUDA中使用指针数组是多么愚蠢,下面是一个完整的示例问题,它结合了上述两种思想:

#include <cstdio>
__global__ void add(int * dev_a[], int * dev_b[], int * dev_c[])
{
    for(int i=0;i<2;i++)
    { 
        for(int j=0;j<2;j++)
        {
            dev_c[i][j]=dev_a[i][j]+dev_b[i][j];
        }
    }
}

inline void GPUassert(cudaError_t code, char * file, int line, bool Abort=true)
{
    if (code != 0) {
        fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code),file,line);
        if (Abort) exit(code);
    }       
}

#define GPUerrchk(ans) { GPUassert((ans), __FILE__, __LINE__); }

int main(void)
{
    const int aa[2][2]={{1,2},{3,4}};
    const int bb[2][2]={{5,6},{7,8}};
    int cc[2][2];

    int ** h_a = (int **)malloc(2 * sizeof(int *));
    for(int i=0; i<2;i++){
        GPUerrchk(cudaMalloc((void**)&h_a[i], 2*sizeof(int)));
        GPUerrchk(cudaMemcpy(h_a[i], &aa[i][0], 2*sizeof(int), cudaMemcpyHostToDevice));
    }

    int **d_a;
    GPUerrchk(cudaMalloc((void ***)&d_a, 2 * sizeof(int *)));
    GPUerrchk(cudaMemcpy(d_a, h_a, 2*sizeof(int *), cudaMemcpyHostToDevice));

    int ** h_b = (int **)malloc(2 * sizeof(int *));
    for(int i=0; i<2;i++){
        GPUerrchk(cudaMalloc((void**)&h_b[i], 2*sizeof(int)));
        GPUerrchk(cudaMemcpy(h_b[i], &bb[i][0], 2*sizeof(int), cudaMemcpyHostToDevice));
    }

    int ** d_b;
    GPUerrchk(cudaMalloc((void ***)&d_b, 2 * sizeof(int *)));
    GPUerrchk(cudaMemcpy(d_b, h_b, 2*sizeof(int *), cudaMemcpyHostToDevice));

    int ** h_c = (int **)malloc(2 * sizeof(int *));
    for(int i=0; i<2;i++){
        GPUerrchk(cudaMalloc((void**)&h_c[i], 2*sizeof(int)));
    }

    int ** d_c;
    GPUerrchk(cudaMalloc((void ***)&d_c, 2 * sizeof(int *)));
    GPUerrchk(cudaMemcpy(d_c, h_c, 2*sizeof(int *), cudaMemcpyHostToDevice));

    add<<<1,1>>>(d_a,d_b,d_c);
    GPUerrchk(cudaPeekAtLastError());

    for(int i=0; i<2;i++){
        GPUerrchk(cudaMemcpy(&cc[i][0], h_c[i], 2*sizeof(int), cudaMemcpyDeviceToHost));
    }

    for(int i=0;i<2;i++) {
        for(int j=0;j<2;j++) {
            printf("(%d,%d):%d\n",i,j,cc[i][j]);
        }
    }

    return cudaThreadExit();
}
#包括
__全局无效添加(int*开发a[],int*开发b[],int*开发c[]
{

for(int i=0;i您不需要在设备内部使用for循环。请尝试以下代码

#include <stdio.h>
#include <cuda.h>
#include <stdlib.h>
#include <time.h>

#define N 800
__global__ void  matrixAdd(float* A, float* B, float* C){

int i = threadIdx.x;
int j = blockIdx.x;
C[N*j+i] = A[N*j+i] + B[N*j+i];
}

int main (void) {
clock_t start = clock();
float a[N][N], b[N][N], c[N][N];
float *dev_a, *dev_b, *dev_c;

cudaMalloc((void **)&dev_a, N * N * sizeof(float));
cudaMalloc((void **)&dev_b, N * N * sizeof(float));
cudaMalloc((void **)&dev_c, N * N * sizeof(float));

for (int i = 0; i < N; i++){
    for (int j = 0; j < N; j++){    
        a[i][j] = rand() % 10;
        b[i][j] = rand() % 10;
    }
}

cudaMemcpy(dev_a, a, N * N * sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, b, N * N * sizeof(float), cudaMemcpyHostToDevice);

matrixAdd <<<N,N>>> (dev_a, dev_b, dev_c);
cudaMemcpy(c, dev_c, N * N * sizeof(float), cudaMemcpyDeviceToHost);

for (int i = 0; i < N; i++){
    for (int j = 0; j < N; j++){
    printf("[%d, %d ]= %f + %f = %f\n",i,j, a[i][j], b[i][j], c[i][j]);
    }
}
printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);

cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);

return 0; 
}
#包括
#包括
#包括
#包括
#定义N 800
__全局无效矩阵ADD(浮点*A、浮点*B、浮点*C){
int i=threadIdx.x;
int j=blockIdx.x;
C[N*j+i]=A[N*j+i]+B[N*j+i];
}
内部主(空){
时钟启动=时钟();
浮动a[N][N]、b[N][N]、c[N][N];
浮动*dev_a、*dev_b、*dev_c;
cudamaloc((无效**)和dev_a,N*N*sizeof(浮动));
cudamaloc((void**)和dev_b,N*N*sizeof(float));
cudamaloc((void**)和dev_c,N*N*sizeof(float));
对于(int i=0;i
请将代码格式缩进4个空格。是的,你是对的。现在假设我这样做应该是我的内核调用谢谢。是的,你是对的。现在假设我这样做,我的内核调用应该是什么?有一件事我会说我使用cudamaloc((void***)和d_a,2*sizeof(int*));但它显示了错误;对h_a来说,还有一件事,那就是为什么要使用cuda malloc?请解释这项工作仅适用于编译时已知维度的静态分配数组。对于任何类型的动态分配(例如
cudaMalloc
等)如问题中所述,这将不起作用。顺便说一句,在将数组传递给内核之前,您仍在将其展平,这不是问题用户想要的。