2016-04-18 56 views
1

我試圖讓所有的CUDA代碼到單獨的test.cu文件,並使用test.h文件從我的main.cpp文件中調用它。但是,當我嘗試從設備獲取數據時,我總是在ExampleSeparate.exe的0x0F277552(nvcuda.dll)中出現錯誤「未處理的異常:0xC0000005:訪問衝突寫入位置0x04A8D000」。CUDA單獨的內核文件錯誤

你能告訴我代碼有什麼問題嗎?而我做錯了將內核代碼和代碼的主要部分分離到不同的文件中?什麼是最好的方式來做到這一點?

我知道如何在OpenCL中做到這一點,但無法在CUDA中進行管理。

的main.cpp

printf("My CUDA example.\n"); 

    int iWidth, iHeight, iBpp, cycles_max = 100; 

    vector<unsigned char> pDataIn; 
    vector<unsigned char> pDataOut; 

    unsigned int SizeIn, SizeOut; 
    unsigned char *devDatOut, *devDatIn, *PInData, *POutData, *DatIn, *DatOut; 

    int error1 = LoadBmpFile(L"3840x2160.bmp", iWidth, iHeight, iBpp, pDataIn); 

    if (error1 != 0 || pDataIn.size() == 0 || iBpp != 32) 
    { 
     printf("error load input file!\n"); 
    } 


    pDataOut.resize(pDataIn.size()/4); 
    //Для CUDA 
    SizeIn = pDataIn.size(); 
    SizeOut = pDataOut.size(); 
    PInData = pDataIn.data(); 
    POutData = pDataOut.data(); 

    //Для CPU 
    DatIn = pDataIn.data(); 
    DatOut = pDataOut.data(); 

    my_cuda((uchar4*)PInData, POutData, SizeIn, SizeOut); 

    return 0; 

test.h

void my_cuda(uchar4* PInData, unsigned char *POutData, unsigned int SizeIn, unsigned int SizeOut); 

test.cu

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) 
{ 

    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

void my_cuda(uchar4* PInData, unsigned char *POutData, unsigned int SizeIn, unsigned int SizeOut){ 
uchar4 *devDatIn; 
unsigned char *devDatOut; 

    printf("Allocate memory on device\n"); 
gpuErrchk(cudaMalloc((void**)&devDatIn, SizeIn * sizeof(uchar4))); 
gpuErrchk(cudaMalloc((void**)&devDatOut, SizeOut * sizeof(unsigned char))); 

    printf("Copy data on device\n"); 
gpuErrchk(cudaMemcpy(devDatIn, PInData, SizeIn * sizeof(uchar4), cudaMemcpyHostToDevice)); 
gpuErrchk(cudaMemcpy(devDatOut, POutData, SizeOut * sizeof(unsigned char), cudaMemcpyHostToDevice)); 

dim3 blocks(8100, 1, 1); 
dim3 threads(1024, 1, 1); 

addMatrix<<<blocks, threads>>>(devDatIn, devDatOut); 

gpuErrchk(cudaMemcpy(POutData, devDatOut, SizeOut * sizeof(unsigned char), cudaMemcpyDeviceToHost)); 
cudaFree(devDatOut); 
cudaFree(devDatIn); 


    _getch(); 
} 

回答

3

在這行代碼:

SizeIn = pDataIn.size(); 

pDataIn具有足夠的尺寸來處理與每像素4個字節,想必3840X2160圖像的<unsigned char>的載體。所以SizeIn應該是3840x2160x4。

然後您將其分配矢量數據到unsigned char指針:

PInData = pDataIn.data(); 

然後你投這個指針到uchar4,而經過SizeIn以字節爲單位

my_cuda((uchar4*)PInData, POutData, SizeIn, SizeOut); 

在您的my_cuda函數中,爲4倍的設備存儲分配大小:

gpuErrchk(cudaMalloc((void**)&devDatIn, SizeIn * sizeof(uchar4))); 

然後嘗試4倍過多的數據複製從主機到設備:

gpuErrchk(cudaMemcpy(devDatIn, PInData, SizeIn * sizeof(uchar4), cudaMemcpyHostToDevice)); 

該行將賽格故障的主機上,幾乎可以肯定。

SizeIn = pDataIn.size()/4; 

這裏的整個例子根據您顯示的代碼,展示了賽格故障和修復:

$ cat t1135.cu 
#include <stdio.h> 
#include <vector> 

using namespace std; 
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) 
{ 

    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

void my_cuda(uchar4* PInData, unsigned char *POutData, unsigned int SizeIn, unsigned int SizeOut){ 
uchar4 *devDatIn; 
unsigned char *devDatOut; 

    printf("Allocate memory on device\n"); 
gpuErrchk(cudaMalloc((void**)&devDatIn, SizeIn * sizeof(uchar4))); 
gpuErrchk(cudaMalloc((void**)&devDatOut, SizeOut * sizeof(unsigned char))); 

    printf("Copy data on device\n"); 
gpuErrchk(cudaMemcpy(devDatIn, PInData, SizeIn * sizeof(uchar4), cudaMemcpyHostToDevice)); 
gpuErrchk(cudaMemcpy(devDatOut, POutData, SizeOut * sizeof(unsigned char), cudaMemcpyHostToDevice)); 

dim3 blocks(8100, 1, 1); 
dim3 threads(1024, 1, 1); 

//addMatrix<<<blocks, threads>>>(devDatIn, devDatOut); 

gpuErrchk(cudaMemcpy(POutData, devDatOut, SizeOut * sizeof(unsigned char), cudaMemcpyDeviceToHost)); 
cudaFree(devDatOut); 
cudaFree(devDatIn); 


} 

int main(){ 

printf("My CUDA example.\n"); 


    vector<unsigned char> pDataIn(3840*2160*4); 
    vector<unsigned char> pDataOut; 

    unsigned int SizeIn, SizeOut; 
    unsigned char *PInData, *POutData; 



    pDataOut.resize(pDataIn.size()/4); 
    //... CUDA 
#ifdef FIX 
    SizeIn = pDataIn.size()/4; 
#else 
    SizeIn = pDataIn.size(); 
#endif 
    SizeOut = pDataOut.size(); 
    PInData = pDataIn.data(); 
    POutData = pDataOut.data(); 

    my_cuda((uchar4*)PInData, POutData, SizeIn, SizeOut); 

    return 0; 

} 
$ nvcc -o t1135 t1135.cu 
$ ./t1135 
My CUDA example. 
Allocate memory on device 
Copy data on device 
Segmentation fault (core dumped) 
$ nvcc -DFIX -o t1135 t1135.cu 
$ ./t1135 
My CUDA example. 
Allocate memory on device 
Copy data on device 
$ 
+0

謝謝你很多

爲解決方案可能是簡單! – Generwp