【问题标题】:OpenCl Segmentation Error at clEnqueueNDRangeKernelclEnqueueNDRangeKernel 处的 OpenCl 分段错误
【发布时间】:2016-02-16 10:05:38
【问题描述】:

我一直致力于在 Eclipse 上使用 OpenCL 进行卷积。它在 enqueueNDRangeKernel 之后给出了分段错误。 这是我的主机代码:-

我使用 OpenCV 拍摄了输入图像,然后:-

const int width = image.size().width;
const int height = image.size().height;
std::cout<<"width: \t"<<width<<"\t height: "<<height<<std::endl;
std::size_t in_imagesize = (width*height)*sizeof(float);

std::vector<float> ptr(width*height,0);

const float filter[3] = {1,2,3};
float filter_size = 3*sizeof(float);
const int FilterRadius = 1;

cv::Mat result_image = cv::Mat(cvSize(width,height), CV_32FC1);
std::size_t out_imagesize = sizeof(float)*(width*height);
std::vector<float> read_buffer(width*height,0);

然后是上下文、命令队列、内核程序,然后是:-

cl::Buffer input_dev, filter_kernel, output_dev;

input_dev = cl::Buffer(ctx,CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PT R,in_imagesize,image.data,&err);
if(error!= CL_SUCCESS){
std::cout<<"Input Buffer Failed "<<std::endl;
}

output_dev =cl::Buffer(ctx,CL_MEM_READ_WRITE,out_imagesize,NU LL,&err);
if(error!= CL_SUCCESS){
std::cout<<"Output Buffer Failed "<<std::endl;
}

filter_kernel = cl::Buffer(ctx,CL_MEM_READ_ONLY,filter_size,NULL,& err);
if(error!= CL_SUCCESS){
std::cout<<"Output Buffer Failed "<<std::endl;


std::cout<<"filter_kernel write buffer "<<std::endl;
queue.enqueueWriteBuffer(filter_kernel,CL_TRUE,0,3 *sizeof(float),filter,NULL,NULL);


// Create Kernel

std::cout<<"Now try create kernel objects .."<<std::endl;

cl::Kernel kernel(prg,"ConvH_naive",&err);
if(error!= CL_SUCCESS)
{
std::cout<<"create Kernel_naive failed \n"<<std::endl;
}

然后是内核参数,然后是:-

cl::NDRange globalsize(width,height);
cl::NDRange localsize(1,1);
cl::NDRange offset(0,0);


std::cout<<"Enqueuing the Kernel"<<std::endl;
if(queue.enqueueNDRangeKernel(kernel,offset,global size,localsize,NULL,NULL)!=CL_SUCCESS)
{
std::cout<<"Failed enqueuing the Kernel"<<std::endl;
}
queue.finish();

在这个 Readbuffer 和 imshow 之后。但代码在此语句后停止,给出分段错误。

有人可以帮忙吗??是否有可能是内核代码有问题?我也要加吗?

【问题讨论】:

  • 您可以自己找出问题所在。先把内核的内容注释掉,看看enqueueNDRangeKernel/queue.finish()之后是否还有seg faults。如果不是,那么问题出在您的内核中。然后逐行逐行取消注释(或内核的某些部分,如果你想更快地做到这一点)并重新测试。
  • 请添加一个可以构建和运行的最小工作示例。您遗漏了重要部分,例如如何设置内核参数。

标签: opencl convolution


【解决方案1】:
  1. (1,1) 的局部大小通常是一个非常糟糕的选择
  2. 您在哪个平台上运行?什么设备(例如 CPU、GPU)?
  3. 这可能是因为您没有处理边界条件并访问超出范围的缓冲区,因此出现了段错误。

【讨论】:

  • 澄清一下,虽然 (1,1) 的局部大小不是最理想的,但它不会导致任何错误(假设内核本身没有错误)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-11
  • 2018-03-18
  • 1970-01-01
  • 2021-03-03
  • 2018-11-18
相关资源
最近更新 更多