繁体   English   中英

二维多维数组传递给内核,CUDA

[英]2D multidimensional array passing to kernel, CUDA

我一直在努力寻找一种实现方法,该实现方法允许我将预定义的2D数组传递给内核。

int values[2][3];

我需要将所有数据保留在正确的列和行中。 现在我知道CUDA接受线性形式的2D数组,但是如何传递已经建立的数组?

正如@ jarod42指出的那样,对于“自动”,“可变长度” C样式数组,如您所显示:

int values[2][3];

这样的数组的存储格式与:

int values[2*3];

这意味着我们可以将该数组视为线性单下标数组(即使不是):

  1. 为了从主机传输到设备:

     #define W 3 #define H 2 int values[H][W]; int *d_values; cudaMalloc(&d_values, H*W*sizeof(int)); cudaMemcpy(d_values, values, H*W*sizeof(int), cudaMemcpyHostToDevice); 
  2. 并且出于访问设备代码的目的,请使用“模拟” 2D访问:

     __global__ void kernel(int *values, int width, ...){ int col = threadIdx.x+blockDim.x*blockIdx.x; int row = threadIdx.y+blockDim.y*blockIdx.y; int my_value = values[row*width+col]; ... } int main(){ ... kernel<<<...>>>(d_values, W, ...); ... } 

但是根据您的问题的措辞:

现在我知道CUDA接受线性形式的2D数组,但是如何传递已经建立的数组?

看来您可能已经意识到上述方法,我通常将其称为“展平” 2D数组以线性方式处理它(也许具有“模拟” 2D访问权限)。

通常,要处理一个在编译时不知道的宽度的2D数组,同时仍然允许在设备代码中进行双下标访问,这很麻烦 ,我不建议这样做,特别是对于CUDA初学者而言。 但这实际上不是您提出的情况:

内核的预定义2D数组。

int values[2][3];
              ^
             the "width"

我的意思是在编译时就知道数组的“宽度”(即第二个,即最后一个下标的范围)。 在那种情况下,我们可以利用编译器生成必要的数组索引,以使传输和使用过程仅比“扁平化”情况稍微复杂一些,同时仍允许在内核中进行双下标访问:

$ cat t1023.cu
#include <stdio.h>

#define W 3
#define H 2
#define BSIZE 8

typedef int arrtype[W];

__global__ void kernel(arrtype *values, int width, int height){

  int col=threadIdx.x+blockDim.x*blockIdx.x;
  int row=threadIdx.y+blockDim.y*blockIdx.y;

  if ((row < height)&&(col < width)){

    int my_val = values[row][col]; //doubly-subscripted access
    printf("row: %d, col: %d, value: %d\n", row, col, my_val);
    }
}

int main(){

  int values[H][W];
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      values[i][j] = i+j;
  arrtype *d_values;
  cudaMalloc(&d_values, H*W*sizeof(int));
  cudaMemcpy(d_values, values, H*W*sizeof(int), cudaMemcpyHostToDevice);
  dim3 block(BSIZE,BSIZE);
  dim3 grid((W+block.x-1)/block.x, (H+block.y-1)/block.y);
  kernel<<<grid,block>>>(d_values, W, H);
  cudaDeviceSynchronize();
  return 0;
}
$ nvcc -o t1023 t1023.cu
$ ./t1023
row: 0, col: 0, value: 0
row: 0, col: 1, value: 1
row: 0, col: 2, value: 2
row: 1, col: 0, value: 1
row: 1, col: 1, value: 2
row: 1, col: 2, value: 3
$

有关完整工作的3D(即三重下标)示例,请参见此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM