【问题标题】:CUDA separate kernel file errorCUDA分离内核文件错误
【发布时间】:2016-04-18 22:22:18
【问题描述】:

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

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

我知道如何在 OpenCL 中做到这一点,但无法在 CUDA 中进行管理。

ma​​in.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();
}

【问题讨论】:

    标签: c++ cuda


    【解决方案1】:

    在这行代码处:

    SizeIn = pDataIn.size();
    

    您的pDataIn&lt;unsigned char&gt; 的向量,其大小足以处理每像素4 字节的3840x2160 图像。所以SizeIn 应该是 3840x2160x4。

    然后将矢量数据分配给unsigned char 指针:

    PInData = pDataIn.data();
    

    然后你将该指针转换为 uchar4,同时传递 old 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
    $
    

    【讨论】:

      猜你喜欢
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      相关资源
      最近更新 更多