OpenCL C ++绑定:如何为enqueueWriteBuffer竞争实现回调

时间:2019-04-03 10:15:46

标签: c++ opencl

我刚开始使用OpenCL 1.2和C ++绑定。我想让写入缓冲区异步入队,并在操作完成后获得回调。这是相关代码行的精简版本:

cl::Event enqueuingBufferReady;
auto error = enqueuingBufferReady.setCallback (CL_COMPLETE, [] (cl_event, cl_int, void*) { std::cout << "Enqueueing complete\n"; });
std::cout << "SetCallback return value: " << MyOpenCLHelpers::getErrorString (error) << std::endl;

// source is a std::vector<int>, buffer is a cl::Buffer of a matching size
commandQueue.enqueueWriteBuffer (buffer, CL_FALSE, 0, sizeof (int) * source.size(), source.data(), NULL, &enqueuingBufferReady);

//... execute the kernel - works successfully!

cl_int info;
enqueuingBufferAReady.getInfo (CL_EVENT_COMMAND_EXECUTION_STATUS, &info);
std::cout << "State of enqueuing " << MyOpenCLHelpers::getEventCommandExecutionStatusString (info) << std::endl;

有效的方法:

内核成功执行并产生正确的结果。缓冲区入队应该已经起作用。该程序以打印终止

State of enqueuing CL_COMPLETE

什么不起作用:

setCallback调用返回

SetCallback return value: CL_INVALID_EVENT

从不调用回调。

那么这段代码有什么问题,以及如何将其更改为按预期工作?

1 个答案:

答案 0 :(得分:1)

与此同时,我自己发现了它。我的错是在使写缓冲区入队之前设置回调。正确的顺序是:

cl::Event enqueuingBufferReady;

// source is a std::vector<int>, buffer is a cl::Buffer of a matching size
commandQueue.enqueueWriteBuffer (buffer, CL_FALSE, 0, sizeof (int) * source.size(), source.data(), NULL, &enqueuingBufferReady);

auto error = enqueuingBufferReady.setCallback (CL_COMPLETE, [] (cl_event, cl_int, void*) { std::cout << "Enqueueing complete\n"; });
std::cout << "SetCallback return value: " << MyOpenCLHelpers::getErrorString (error) << std::endl;

仅在调用enqueueWriteBuffer之后,传入的cl::Event才有效,随后的setCallback调用才有效。我对此感到有些困惑,因为我不确定如何确保在设置回调之前不会使缓冲区入队完成,但是我的测试表明这无关紧要,因为即使回调被调用该操作已经完成很长时间了。