C++调用OpenCL内核时如何正确初始化输入输出参数
问题根因
- 第一,OpenCL内核在设备侧运行是异步操作,你调用完KernelFunctor后没有等待任务执行完成,内核实际还没跑完就开始读主机侧内存了。
- 第二,设备侧
output_buffer存储的结果不会自动同步到主机侧的output_vector,需要你主动调用拷贝接口把设备缓冲区数据读回主机内存。 - 第三,macOS的OpenCL 1.2驱动普遍不支持内核侧
printf特性,该功能属于OpenCL 1.2标准的可选实现,大部分Apple硬件的OpenCL驱动都没有做这个功能的适配,看不到printf输出是正常现象。
修复方案
修改你的C++代码逻辑,内核执行后先同步命令队列,再把设备缓冲区数据回读到主机侧vector:
cl::Kernel kernel(program, "test_kernel", &cl_error); if (cl_error != 0) { std::cout << "Error - cl::Kernel - " << getErrorString(cl_error) << std::endl; return 1; } cl::CommandQueue command_queue(context, device); cl::vector<float> input_vector{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f }; cl::vector<float> output_vector{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; // 显式传入上下文避免缓冲区绑定到错误上下文,可选优化 cl::Buffer input_buffer(context, std::begin(input_vector), std::end(input_vector), true); cl::Buffer output_buffer(context, std::begin(output_vector), std::end(output_vector), false); cl::EnqueueArgs enqueue_args(command_queue, cl::NDRange(5)); cl::KernelFunctor<cl::Buffer, cl::Buffer> functor(kernel); functor(enqueue_args, input_buffer, output_buffer); // 新增1:等待命令队列中所有任务执行完成 command_queue.finish(); // 新增2:把设备侧output_buffer的数据回读到主机侧output_vector cl::copy(command_queue, output_buffer, std::begin(output_vector), std::end(output_vector)); for (const auto& value : output_vector) { std::cout << value << ", "; }
修改后运行就能得到0.1, 1.2, 2.3, 3.4, 4.5,的预期输出。
内容的提问来源于stack exchange,提问作者Iron Attorney
相关产品推荐
相关产品推荐

