【问题标题】:CUDA NPP - Error on printing outputCUDA NPP - 打印输出错误
【发布时间】:2014-03-24 14:44:28
【问题描述】:

在我之前的帖子之后:CUDA NPP - unknown error upon GPU error check

我曾尝试使用 CUDA NPP 库对图像中的所有像素求和,在一些开发人员的帮助下,我终于得到了可以编译的代码。但是,当我尝试通过将存储在 partialSum 中的值复制到 double 变量中(与 CUDA v4.2 的 NPP 指南一致)打印出存储在 partialSum 中的值时,我收到此错误:

Unhandled exception at 0x00fdf7f4 in MedianFilter.exe: 0xC0000005: Access violation reading location 0x40000000.

我一直在尝试摆脱它,但到目前为止我一直没有成功。请帮忙!我在这段小代码上已经有大约两天的时间了。

代码:

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
{
    if (code != cudaSuccess) 
    {
        fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
        if (abort) getchar();
    }
}

// processing image starts here 

// device_pointer initializations
unsigned char *device_input;
unsigned char *device_output;    

size_t d_ipimgSize = input.step * input.rows;
size_t d_opimgSize = output.step * output.rows;

gpuErrchk( cudaMalloc( (void**) &device_input, d_ipimgSize) );
gpuErrchk( cudaMalloc( (void**) &device_output, d_opimgSize) );

gpuErrchk( cudaMemcpy(device_input, input.data, d_ipimgSize, cudaMemcpyHostToDevice) );


// Median filter the input image here
// .......


// allocate data on the host for comparing the sum of all pixels in image with CUDA implementation

// 1st argument - allocate data for pSrc - copy device_output into this pointer
Npp8u *odata; 
gpuErrchk( cudaMalloc( (void**) &odata, sizeof(Npp8u)*output.rows*output.cols ) );
gpuErrchk( cudaMemcpy(odata, device_output, sizeof(Npp8u)*output.rows*output.cols, cudaMemcpyDeviceToDevice) ); 

// 2nd arg - set step 
int ostep = output.step;  

// 3rd arg - set nppiSize
NppiSize imSize; 
imSize.width = output.cols; 
imSize.height = output.rows;

// 4th arg - set npp8u scratch buffer size
Npp8u *scratch; 
int bytes = 0;
nppiReductionGetBufferHostSize_8u_C1R( imSize, &bytes);

gpuErrchk( cudaMalloc((void **)&scratch, bytes) );

// 5th arg - set npp64f partialSum (64 bit double will be the result)
Npp64f *partialSum; 
gpuErrchk( cudaMalloc( (void**) &partialSum, sizeof(Npp64f) ) );

//                 nnp8u, int, nppisize, npp8u, npp64f    
nppiSum_8u_C1R( odata, ostep, imSize, scratch, partialSum );

double *dev_result;
    dev_result = (double*)malloc(sizeof(double)); // EDIT
gpuErrchk( cudaMemcpy(&dev_result, partialSum, sizeof(double), cudaMemcpyDeviceToHost) );
//int tot = output.rows * output.cols;
printf( "\n Total Sum cuda %f \n",  *dev_result) ;   // <---- access violation here

【问题讨论】:

  • 我只是在这里猜测,但我希望这对你有所帮助。从一个非常肤浅的 POV 来看,您正在混合 GPU 内存和 RAM 内存变量,这很奇怪。尝试打印“Hello World”。如果可以继续下一步,如果您的内联代码通过 GPU 管道(或使用多 SIMD),那么您的 %s 、 %d 将指向 GPU 内存而不是 RAM 内存,而 fprintf 将使用 kernell (访问 RAM 内存)。
  • 您从未在主机上为dev_result 分配任何内存,这会导致 cudaMemcpy 破坏堆栈并导致程序崩溃。我已经投票结束这个问题,我认为在发布Stack Overflow 问题之前期待一些调试和分析是合理的。
  • @talonmies 我意识到我之前没有malloc dev_result,所以我确实分配了它。它仍然给我同样的错误。我已经尝试了一切,但它没有打印出结果。显然,我在发布之前尝试调试我的答案;否则,我学习CUDA NPP的整个概念将是无效的。

标签: c++ cuda npp


【解决方案1】:

这里的问题似乎是基本的指针滥用(我说似乎是因为我们的代码不完整,无法编译,所以很难确定)。

这应该可行:

double *dev_result = (double*)malloc(sizeof(double));
gpuErrchk( cudaMemcpy(dev_result, partialSum, sizeof(double), cudaMemcpyDeviceToHost) );
printf( "\n Total Sum cuda %f \n",  *dev_result);

这也应该有效:

double dev_result;
gpuErrchk( cudaMemcpy(&dev_result, partialSum, sizeof(double), cudaMemcpyDeviceToHost) );
printf( "\n Total Sum cuda %f \n",  dev_result);

这假设不完整代码中的所有其他内容都是正确的。我将其作为练习留给读者,以发现这三个变体之间的差异。

【讨论】:

  • 感谢您的反对。当cudaMemcpy 进程没有向它写入任何值时,我应该通过取消引用dev_result 来访问垃圾值。我应该为此受到批评;傻我。 :|
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多