OpenCL c++: CL_INVALID_KERNEL和make_kernel不是cl的成员

OpenCL C++: CL_INVALID_KERNEL and make_kernel not a member of cl

本文关键字:不是 kernel cl 成员 make KERNEL c++ CL INVALID OpenCL      更新时间:2023-10-16

我在这里读了很多,但这是我的第一篇。

我正在尝试为Altera的FPGA运行c++ OpenCL代码,目前仅兼容OpenCL 1.0。到目前为止,准备环境、查询平台和使用其他OpenCL函数工作得很好。但是当我尝试创建内核并添加参数时,我遇到了问题。我尝试了两种方法,但都有各自的错误:

方法:

    auto simple_add = cl::make_kernel<cl::Buffer&, cl::Buffer&, cl::Buffer&>    (opencl_Program, ocl_func_name.c_str());
    cl::EnqueueArgs eargs(queue, cl::NullRange, cl::NDRange(n), cl::NullRange);
    simple_add(eargs, buffer_A, buffer_B, buffer_C).wait();

这会产生以下编译错误:

错误:' make_kernel '不是' cl '的成员

auto simple_add = cl::make_kernel(opencl_Program, ocl_func_name.c_str());

方法二:

cl::Kernel simple_add = cl::Kernel(opencl_Program, ocl_func_name.c_str(), p_err);
if (p_err != NULL)
    display_OpenCL_ErrorCode(*p_err);
err = simple_add.setArg(0, sizeof(cl::Buffer), (void*)&buffer_A);
display_OpenCL_ErrorCode(err);
err = simple_add.setArg(1, sizeof(cl::Buffer), (void*)&buffer_B);
display_OpenCL_ErrorCode(err);
err = simple_add.setArg(2, sizeof(cl::Buffer), (void*)&buffer_C);
display_OpenCL_ErrorCode(err);

这会在每个"setArg"行产生以下运行时输出代码(创建内核不会产生错误):

-48(即CL_INVALID_KERNEL).

我的推理:

  • 我没能找到任何地方任何OpenCL 1.0 c++文档。它似乎只在1.2版本开始可用,所以我可能没有办法在c++中为FPGA编写任何代码,但我首先要确保(听起来仍然不太可能)。
  • 方法一的代码来自我在使用OpenCL 2.0和c++ 11时创建的先前文件,并且工作良好。它已经在OpenCL 1.2中记录了,所以它应该可以工作吗?
  • 尽管内核创建在第二种方法中似乎是完美无瑕的,但我怀疑它没有像预期的那样工作,因为它不允许为链接的函数设置任何参数。但我很难调试,因为没有错误…

感谢任何帮助和支持!

(我不想重载第一篇文章,但如果需要,我可以发布更多的代码)。

EDIT1:我看了看cl.hpp文件,发现下面这行:* OpenCL 1.0 (rev 48)和OpenCL 1.1 (rev 33)的简短c++绑定因此,这证实了存在OpenCL 1.0 c++包装器的事实。我还发现,里面没有make_kernel函数。如果我找到解决方案,我会仔细查看文件,并将更正后的代码发布。

几天前我也遇到了这个bug,我刚刚解决了。我在这里分享解决方案。这是代码:

inline void CreateOCLKernels()
{
    filterDepth_ocl_kernel = clCreateKernel(program, "filterDepthKernel", &clError);
    checkErr(clError, "clCreateKernel");
    convertDisparityToDepth_ocl_kernel = clCreateKernel(program, "convertDisparityToDepthKernel", &clError);
    checkErr(clError, "clCreateKernel");
    ComputeNormalAndWeight_ocl_kernel = clCreateKernel(program, "ComputeNormalAndWeightKernel", &clError);
    checkErr(clError, "clCreateKernel");
    convertDepthAffineToFloat_ocl_kernel = clCreateKernel(program, "convertDepthAffineToFloatKernel", &clError);
    checkErr(clError, "clCreateKernel");
}
ITMViewBuilder_OpenCL::ITMViewBuilder_OpenCL(const ITMRGBDCalib *calib):ITMViewBuilder(calib) { CreateOCLKernels(); }

可以看到,它是由构造函数调用的内联函数。我一直从函数"CreateOCLKernels()"接收"无效内核名称",直到我添加"静态"到该函数。

static inline void CreateOCLKernels()
{ ... }

我想你一定知道为什么。因为非静态函数是全局的,并且其他同名文件中的函数之间可能存在冲突。

由于我没有将其设置为"静态",因此会调用其他文件中的其他函数而不是正确的本地函数。