2017-04-26 153 views
0

內存指針我聲明瞭兩個GPU內存指針,以及分配的GPU內存,傳輸數據,並在主啓動內核:我怎麼能寫在CUDA

// 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; 
    } 
} 

但是,這裏有一些錯誤,我認爲這裏有一些錯誤的指針。任何機構都可以提供幫助?

+1

「有些錯誤」:具體是什麼樣的錯誤?什麼是確切的錯誤信息?如果您向CUDA API調用添加適當的錯誤檢查,會發生什麼情況? – njuffa

+0

錯誤1.「表達式必須具有指針對象類型」,符合char f = gpuIn [idx] [idy]; ,gpuOut [idx] [idy] =死亡;和gpuOut [idx] [idy] = live;在內核裏面。錯誤2.「類型」char *「的參數與我在主角色中啓動內核的行上的」char「類型參數不兼容<<< dim3(1),dim3(40,20)>>> (gpuOut,gpuIn); –

+3

那麼,因爲你的內核中的'gpuIn'是一個指向'char'的指針,所以你不能像'gpuIn [idx] [idy]'那樣對它進行雙重引用。這在普通的C或C++代碼中不起作用,所以在CUDA中不起作用也就不足爲奇了。你應該提供[mcve]。你可以編輯你的問題,你不需要把這些東西塞進評論中。 –

回答

2

關鍵概念是內存中多維數組的存儲順序 - 這很好地描述了here。一個有用的抽象是定義一個簡單的類,它封裝了一個存儲在線性內存中的多維數組的指針,並提供了一個類似於通常的樣式訪問的操作符。您的代碼可以修改這樣的事:

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加以解決。上面代碼中的類僅僅是表達這一點的便利方式。