CUDA分离内核文件错误
Posted
技术标签:
【中文标题】CUDA分离内核文件错误【英文标题】:CUDA separate kernel file error 【发布时间】:2016-04-18 22:22:18 【问题描述】:我正在尝试将所有 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】:在这行代码处:
SizeIn = pDataIn.size();
您的pDataIn
是<unsigned char>
的向量,其大小足以处理每像素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
$
【讨论】:
以上是关于CUDA分离内核文件错误的主要内容,如果未能解决你的问题,请参考以下文章
我可以将“静态”CUDA 内核启动与 PTX 代码结合起来并获得一个工作二进制文件吗?
分析一个CUDA矩阵加法代码,使用nvprof:代码API配置文件,内核没有
分析一个CUDA矩阵加法代码,使用nvprof:代码API配置文件,内核没有