我刚开始使用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
从不调用回调。
那么这段代码有什么问题,以及如何将其更改为按预期工作?
答案 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
调用才有效。我对此感到有些困惑,因为我不确定如何确保在设置回调之前不会使缓冲区入队完成,但是我的测试表明这无关紧要,因为即使回调被调用该操作已经完成很长时间了。