Pointers 如何在CUDA中写入内存指针

Pointers 如何在CUDA中写入内存指针,pointers,cuda,gpu,Pointers,Cuda,Gpu,我声明了两个GPU内存指针,并分配了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, curr

我声明了两个GPU内存指针,并分配了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);

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

关键概念是多维数组在内存中的存储顺序——这一点描述得很好。一个有用的抽象是定义一个简单的类,它封装了一个指向存储在线性内存中的多维数组的指针,并提供了一个操作符,该操作符提供了类似于通常的
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;
}
模板
结构阵列2d
{
T*p;
规模(lda);;
__设备主机__
array2d(tp*\tp,size\tplda):p(\tp),lda(\lda){};
__设备主机__
运算符()(大小为i,大小为j){
返回p[j+i*lda];
}
__设备主机__
常量T&运算符()(大小i,大小j)常量{
返回p[j+i*lda];
}
};
__全局无效角色(array2d gpuOut、array2d gpuIn){
int idx=threadIdx.x;
int-idy=threadIdx.y;
char live='0';
char dead=';
charf=gpuIn(idx,idy);
如果(f==live){
gpuOut(idx,idy)=死亡;
}
否则{
gpuOut(idx,idy)=实时;
} 
}
int main()
{        
const int rows=5,cols=6;
常量大小数组字节=大小(字符)*大小(行*列);
//声明GPU内存指针
char*gpuIn;
char*gpuOut;
char currIn[rows][cols]、currOut[rows][cols];
//分配GPU内存
cudamaloc(&gpuIn,数组字节);
cudamaloc(&gpuOut,数组字节);
//将阵列传输到GPU
cudaMemcpy(gpuIn、currIn、数组字节、cudaMemcpyHostToDevice);
//启动内核
角色(array2d(gpuOut,cols),array2d(gpuIn,cols));
//将结果数组复制回CPU
cudaMemcpy(currOut、gpuOut、数组字节、cudaMemcpyDeviceToHost);
cudaFree(gpuIn);
cudaFree(gpuOut);
返回0;
}

重要的一点是,在线性存储器中存储的二维C或C++数组可以被称为< COL> COR+行数COLs < /代码>。上面代码中的类只是表达这一点的一种方便方式。

关键概念是内存中多维数组的存储顺序——这一点描述得很好。一个有用的抽象是定义一个简单的类,它封装了一个指向存储在线性内存中的多维数组的指针,并提供了一个操作符,该操作符提供了类似于通常的
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;
}
模板
结构阵列2d
{
T*p;
规模(lda);;
__设备主机__
array2d(tp*\tp,size\tplda):p(\tp),lda(\lda){};
__设备主机__
运算符()(大小为i,大小为j){
返回p[j+i*lda];
}
__设备主机__
常量T&运算符()(大小i,大小j)常量{
返回p[j+i*lda];
}
};
__全局无效角色(array2d gpuOut、array2d gpuIn){
int idx=threadIdx.x;
int-idy=threadIdx.y;
char live='0';
char dead=';
charf=gpuIn(idx,idy);
如果(f==live){
gpuOut(idx,idy)=死亡;
}
否则{
gpuOut(idx,idy)=实时;
} 
}
int main()
{        
const int rows=5,cols=6;
常量大小数组字节=大小(字符)*大小(行*列);
//声明GPU内存指针
char*gpuIn;
char*gpuOut;
char currIn[rows][cols]、currOut[rows][cols];
//分配GPU内存
cudamaloc(&gpuIn,数组字节);
cudamaloc(&gpuOut,数组字节);
//将阵列传输到GPU
cudaMemcpy(gpuIn、currIn、数组字节、cudaMemcpyHostToDevice);
//启动内核
角色(array2d(gpuOut,cols),array2d(gpuIn,cols));
//将结果数组复制回CPU
cudaMemcpy(currOut、gpuOut、数组字节、cudaMemcpyDeviceToHost);
cudaFree(gpuIn);
cudaFree(gpuOut);
返回0;
}

重要的一点是,在线性存储器中存储的二维C或C++数组可以被称为< COL> COR+行数COLs < /代码>。上面代码中的类只是一种方便的表达方式。

一些错误:具体是什么类型的错误?确切的错误消息是什么?如果向CUDA API调用添加正确的错误检查,会发生什么情况?错误1。“表达式必须具有指向对象类型的指针”,位于char f=gpuIn[idx][idy]的第行,gpuOut[idx][idy]=死亡;和gpuOut[idx][idy]=live;内核内部。错误2。类型为“char*”的参数与我在主角色(gpuOut,gpuIn)中启动内核的行上类型为“char”的参数不兼容;好吧,因为内核中的
gpuIn
是指向
char
的指针,所以不能像
gpuIn[idx][idy]
那样对其进行双重解引用;这在普通的C或C++代码中是行不通的,所以在CUDA中不起作用并不奇怪。你应该提供一份报告。你可以编辑你的问题,你不需要把这些东西塞进注释中。我试图通过内核中的指针“gpuIn”和“gpuOut”来获取2D数组中的位置。我该怎么做?这实际上是“某些错误”的重复:具体是什么类型的错误?确切的错误消息是什么?如果向CUDA API调用添加正确的错误检查,会发生什么情况?错误1。“表达式必须具有指向对象类型的指针”,位于char f=gpuIn[idx][idy]的第行,gpuOut[idx][idy]=死亡;和gpuOut[idx][idy]=live;内核内部。错误2。类型为“char*”的参数与我在主角色(gpuOut,gpuIn)中启动内核的行上类型为“char”的参数不兼容;好吧,因为内核中的
gpuIn
是指向
char
的指针,所以不能像
gpuIn[idx][idy]
那样对其进行双重解引用;这在普通的C或C++代码中是行不通的,所以在CUDA中不起作用并不奇怪。你应该提供一份报告。你可以编辑你的问题,你不需要