Постановка в очередь на стороне устройства вызывает CL_OUT_OF_RESOURCES - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть программа, использующая OpenCL 2.0, потому что я хочу использовать преимущества на стороне устройства. У меня есть тестовая программа, которая выполняет следующие задачи на стороне хоста:

  1. Выделяет 16 килобайт памяти с плавающей запятой на устройстве и обнуляет ее.
  2. Создает нижеприведенную программу OpenCL и создает ядро ​​masterKernel()
  3. Устанавливает первый аргумент masterKernel() (heap) для выделенной памяти на шаге 1
  4. Ставит запрос masterKernel() через clEnqueueNDRangeKernel() с work_dim, равным 1, и глобальным рабочим размером 1. (Таким образом, он запускается только один раз, с get_global_id(0), всегда равным нулю)
  5. Считывает память обратно в хост и отображает ее.

Вот код 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 для его тестирования.

1 Ответ

0 голосов
/ 21 апреля 2020

В итоге я понял это. Эта проблема возникла из-за того, что я не создал очередь на стороне устройства (с флагами CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT).

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