У меня есть программа, использующая OpenCL 2.0, потому что я хочу использовать преимущества на стороне устройства. У меня есть тестовая программа, которая выполняет следующие задачи на стороне хоста:
- Выделяет 16 килобайт памяти с плавающей запятой на устройстве и обнуляет ее.
- Создает нижеприведенную программу OpenCL и создает ядро
masterKernel()
- Устанавливает первый аргумент
masterKernel()
(heap
) для выделенной памяти на шаге 1 - Ставит запрос
masterKernel()
через clEnqueueNDRangeKernel()
с work_dim
, равным 1, и глобальным рабочим размером 1. (Таким образом, он запускается только один раз, с get_global_id(0)
, всегда равным нулю) - Считывает память обратно в хост и отображает ее.
Вот код OpenCL:
//This function was stripped down to nothing for testing purposes.
kernel void childKernel(global float* heap)
{
}
//Enqueues the child kernel.
kernel void masterKernel(global float* heap)
{
ndrange_t ndRange = ndrange_1D(16); //Arbitrary, could be any number.
if(get_global_id(0) == 0)
{
enqueue_kernel(get_default_queue(), 0, ndRange,
^{ childKernel(heap); });
}
}
Программа успешно собирается. Однако, когда я пытаюсь запустить masterKernel()
, вызов enqueue_kernel()
вызывает сбой на стороне хоста на clEnqueueNDRangeKernel()
, с кодом ошибки CL_OUT_OF_RESOURCES
. Документация OpenCL гласит, что enqueue_kernel()
должен возвращать CL_SUCCESS
или CL_ENQUEUE_FAILURE
в зависимости от того, успешно ли блок ставится в очередь или нет. Это не говорит о том, что clEnqueueNDRangeKernel()
само должно потерпеть неудачу. Вот некоторые другие вещи, которые я пробовал:
- Комментирование вызова
enqueue_kernel()
приводит к успешному завершению программы. - Добавление строки, которая устанавливает
heap[0]
для любого числа заставляет программу на стороне хоста отражать это изменение. Поэтому я знаю, что это не проблема с тем, как я передаю аргументы в - Изменение оператора
if
так, чтобы он читал что-то невозможное, например, if(get_global_id(0) == 6000)
still вызывает ошибку. Это говорит мне о том, что ошибка вызвана не enqueue_kernel()
выполнением (я проверил get_global_size(0) == 1
), а просто тем, что она вообще существует в программе. - Изменение оператора
if
на if(0)
делает , чтобы ошибка не произошла. - Делая это так,
childKernel()
на самом деле что-то не делает ошибку go.
Я не совсем уверен, что попробовать дальше. Я знаю, что мое устройство поддерживает OpenCL 2.0. Моим устройством является видеокарта AMD Radeon R9 380. У меня нет доступа к любому другому оборудованию с поддержкой OpenCL 2.0 для его тестирования.