Привязки OpenCL C ++: как реализовать обратный вызов для конкурса enqueueWriteBuffer - PullRequest
1 голос
/ 03 апреля 2019

Я только начинаю с OpenCL 1.2 и C ++ Bindings. Я хочу поставить в буфер записи асинхронный и получить обратный вызов после завершения операции. Вот урезанная версия соответствующих строк кода:

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 Ответ

1 голос
/ 03 апреля 2019

Тем временем я узнал это сам. Моя ошибка состояла в том, чтобы установить обратный вызов перед постановкой в ​​очередь в буфер записи. Правильный порядок:

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 работает. Я был немного смущен этим, потому что я не был уверен, как было гарантировано, что постановка в буфер не завершится до того, как будет установлен обратный вызов, однако мой тест показал, что это не имеет значения, так как обратный вызов даже вызывается, если он устанавливается долго после того, как операция уже завершена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...