【问题标题】:How can I write the memory pointer in CUDA [duplicate]如何在 CUDA 中写入内存指针 [重复]
【发布时间】:2017-04-27 21:35:50
【问题描述】:

我声明了两个 GPU 内存指针,并在 main 中分配了 GPU 内存、传输数据和启动内核:

// declare GPU memory pointers
char * gpuIn;
char * gpuOut;

// allocate GPU memory
cudaMalloc(&gpuIn, ARRAY_BYTES);
cudaMalloc(&gpuOut, ARRAY_BYTES);

// transfer the array to the GPU
cudaMemcpy(gpuIn, currIn, ARRAY_BYTES, cudaMemcpyHostToDevice);

// launch the kernel
role<<<dim3(1),dim3(40,20)>>>(gpuOut, gpuIn);

// copy back the result array to the CPU
cudaMemcpy(currOut, gpuOut, ARRAY_BYTES, cudaMemcpyDeviceToHost);

cudaFree(gpuIn);
cudaFree(gpuOut);

这是我在内核中的代码:

__global__ void role(char * gpuOut, char * gpuIn){
    int idx = threadIdx.x;
    int idy = threadIdx.y;

    char live = '0';
    char dead = '.';

    char f = gpuIn[idx][idy];

    if(f==live){ 
       gpuOut[idx][idy]=dead;
    }
    else{
       gpuOut[idx][idy]=live;
    } 
}

但是这里有一些错误,我认为这里是指针上的一些错误。任何机构都可以提供帮助?

【问题讨论】:

  • “一些错误”:具体是什么错误?确切的错误信息是什么?如果向 CUDA API 调用添加正确的错误检查会发生什么?
  • 错误 1. char f = gpuIn[idx][idy]; 行上的“表达式必须具有指向对象类型的指针”; , gpuOut[idx][idy]=dead;和 gpuOut[idx][idy]=live;内核内部。错误2.“char *”类型的参数与“char”类型的参数不兼容”在我以主要角色启动内核的那一行>> (gpuOut, gpuIn);
  • 好吧,因为你内核中的gpuIn 是一个指向char 的指针,所以你不能像gpuIn[idx][idy] 那样对它进行双重取消引用;这在普通的 C 或 C++ 代码中不起作用,因此它在 CUDA 中不起作用也就不足为奇了。您应该提供minimal reproducible example。你可以编辑你的问题,你不需要把这些东西塞进 cmets。
  • 我试图通过内核中的指针“gpuIn”和“gpuOut”来获取二维数组中的位置。我该怎么做?
  • 这真的是stackoverflow.com/a/18930734/681865的复制品

标签: pointers cuda gpu


【解决方案1】:

关键概念是多维数组在内存中的存储顺序——这在here 中有很好的描述。一个有用的抽象是定义一个简单的类,它封装指向存储在线性内存中的多维数组的指针,并提供一个运算符,该运算符提供类似于通常的a[i][j] 样式访问。您的代码可以修改如下:

template<typename T>
struct array2d
{
    T* p;
    size_t lda;

    __device__ __host__
    array2d(T* _p, size_t _lda) : p(_p), lda(_lda) {};

    __device__ __host__
    T& operator()(size_t i, size_t j) {
        return p[j + i * lda]; 
    }
    __device__ __host__
    const T& operator()(size_t i, size_t j) const {
        return p[j + i * lda]; 
    }
};

__global__ void role(array2d<char> gpuOut, array2d<char> gpuIn){
    int idx = threadIdx.x;
    int idy = threadIdx.y;

    char live = '0';
    char dead = '.';

    char f = gpuIn(idx,idy);

    if(f==live){ 
       gpuOut(idx,idy)=dead;
    }
    else{
       gpuOut(idx,idy)=live;
    } 
}

int main()
{        
    const int rows = 5, cols = 6;
    const size_t ARRAY_BYTES = sizeof(char) * size_t(rows * cols);

    // declare GPU memory pointers
    char * gpuIn;
    char * gpuOut;

    char currIn[rows][cols], currOut[rows][cols];

    // allocate GPU memory
    cudaMalloc(&gpuIn, ARRAY_BYTES);
    cudaMalloc(&gpuOut, ARRAY_BYTES);

    // transfer the array to the GPU
    cudaMemcpy(gpuIn, currIn, ARRAY_BYTES, cudaMemcpyHostToDevice);

    // launch the kernel
    role<<<dim3(1),dim3(rows,cols)>>>(array2d<char>(gpuOut, cols), array2d<char>(gpuIn, cols));

    // copy back the result array to the CPU
    cudaMemcpy(currOut, gpuOut, ARRAY_BYTES, cudaMemcpyDeviceToHost);

    cudaFree(gpuIn);
    cudaFree(gpuOut);

    return 0;
}

这里的重点是存储在线性内存中的二维 C 或 C++ 数组可以寻址为col + row * number of cols。上面代码中的类只是一种方便的表达方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    相关资源
    最近更新 更多