CUDA单独的内核文件错误

时间:2016-04-18 22:22:19

标签: c++ cuda

我正在尝试将所有CUDA代码放到单独的test.cu文件中,并使用test.h文件从main.cpp文件中调用它。但是当我尝试从设备获取数据时,我总是在ExampleSeparate.exe中遇到错误“0x0F277552(nvcuda.dll)的未处理异常:0xC0000005:访问冲突写入位置0x04A8D000。”

请告诉我代码有什么问题?我将内核代码和代码的主要部分分成不同的文件我做错了什么?最好的方法是什么?

我知道如何在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();
}

1 个答案:

答案 0 :(得分:3)

在这行代码中:

SizeIn = pDataIn.size();

你的pDataIn是一个足够大的<unsigned char>向量,可以处理每像素4个字节的3840x2160图像。所以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;

这是一个基于您展示的代码的完整工作示例,演示了seg错误和修复:

$ 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
$