OpenCL c++: CL_INVALID_KERNEL和make_kernel不是cl的成员
OpenCL C++: CL_INVALID_KERNEL and make_kernel not a member of cl
我在这里读了很多,但这是我的第一篇。
我正在尝试为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()
{ ... }
我想你一定知道为什么。因为非静态函数是全局的,并且其他同名文件中的函数之间可能存在冲突。
- 检查输入是否不是整数或数字
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 为什么使用SFINAE而不是函数重载
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 为什么std::valarray不是算术的
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- MSVC是否支持C++11样式的属性而不是__declspec
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 为什么make_tie不是一件事
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 为什么std::isnan 不是 constexpr?
- GlobalAlloc而不是其他分配方法
- 当比特(而不是字节)的顺序至关重要时的持久性
- 为什么复制而不是移动数据元素?
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 如何计算数组中元素的位数?(不是数组的长度),并计算其数字的总和