gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 05:54:07 25 4
gpt4 key购买 nike

我一直在努力寻找一个允许我将预定义的二维数组传递给内核的实现。

int values[2][3];

我需要将所有数据保存在正确的列和行中。现在我知道 CUDA 接受线性形式的二维数组,但我如何传递一个已经构建的数组?

最佳答案

正如@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, ...);
    ...
    }

但根据您问题中的措辞:

Now I know that CUDA accepts 2D arrays in a linear form but how do I pass an already built array?

看来您可能知道上述方法,我通常将其称为“扁平化”二维数组以线性方式处理它(可能使用“模拟”二维访问)。

一般来说,处理编译时未知宽度的二维数组,同时仍然允许在设备代码中进行双下标访问,是rather involved。 ,我不会推荐它,特别是对于 CUDA 初学者。但实际上您提出的情况并非如此:

a predefined 2D array to a kernel.

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(即三重下标)示例,请参阅 here

关于c++ - 二维多维数组传递给内核,CUDA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34591161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com