2016-04-18 2 views
1

Я пытаюсь получить весь код CUDA в отдельный файл test.cu и вызывать его из файла main.cpp с помощью файла test.h. Но когда я пытаюсь получить данные с устройства, я всегда получаю сообщение об ошибке «Необработанное исключение в 0x0F277552 (nvcuda.dll) в ExampleSeparate.exe: 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 является вектором <unsigned char> достаточного размера для обработки 3840x2160 изображения с 4 байта на пиксель, предположительно. Таким образом, 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

Смежные вопросы