Ошибка CL_INVALID_WORK_GROUP_SIZE

#opencl

#opencl

Вопрос:

У меня есть этот код, для которого я уже опубликовал что-то некоторое время назад.

Сегодня я запустил свое ядро со структурой typedef в небольшой тестовой программе, но clEnqueueNDRangeKernel выдает недопустимую ошибку размера рабочей группы. Согласно веб-сайту khronos, это может иметь 3 причины.

  1. Глобальный размер работы не может быть разделен на локальный размер работы. В моем коде оно делимо.
  2. Размер локальной работы больше, чем может обработать графический процессор. Мой локальный рабочий размер равен 128, что намного меньше заявленного максимума 1024.
  3. Что-то связанное с локальным рабочим размером NULL . Мой локальный рабочий размер не равен NULL 128.

Я несколько часов искал в Интернете, и большинство решений, которые я нашел, связаны с запросом clGetKernelWorkGroupInfo максимального локального рабочего размера. Когда я это делаю, он также сообщает о 1024. У меня действительно нет вариантов, кто-нибудь может помочь? 🙂

Главная: http://pastebin.com/S6R6t3iF ядро: http://pastebin.com/Mrhr8B4v

Ответ №1:

Из вашей ссылки на pastebin я вижу:

 #define MAX_OP_X 4
#define MAX_OP_Y 4
#define MAX_OP MAX_OP_X * MAX_OP_Y      //aantal observer points
#define MAX_SEGMENTEN 128 //aantal segmenten
...
size_t globalSize = MAX_OP;
size_t localSize = MAX_SEGMENTEN;
...
errMsg = clEnqueueNDRangeKernel (commandQueue, kernel, 1, NULL, amp;globalSize, amp;localSize, 0, NULL, NULL);
  

Это означает, что вы пытаетесь поставить в очередь свое ядро с глобальным размером 16 и локальным размером 128. Это почти наверняка не то, что вы хотите. Помните, что глобальный размер — это общее количество рабочих элементов, которые вы хотите запустить, а локальный размер — это размер каждой рабочей группы. Например, если у вас глобальный размер 1024×1024 и локальный размер 16×16, у вас будет 4096 рабочих групп по 256 рабочих элементов в каждой. Это может быть или не быть допустимым, в зависимости от вашего вычислительного устройства.

Что касается передачи нулевого локального размера: в спецификации CL говорится, что если вы это сделаете, реализация CL может выбрать все, что захочет, в качестве размера локальной рабочей группы. В идеале, он попытается сделать что-то умное от вашего имени, но у вас нет никаких гарантий.

Комментарии:

1. это, безусловно, то, что я хочу 🙂 Почему вы думаете, что это не то, что я хочу? Этот код является для меня некоторой практикой, если я освоюсь с ним, это будет довольно большая программа. Итак, я сделал это с учетом будущих расширений.

2. Что бы вы ни хотели, вы должны обеспечить global_size >= local_size

3. Хорошо, позвольте мне привести вам 1D пример. Допустим, у вас есть 10 000 вещей, которые вы хотите обработать с помощью ядра CL. Это ваш глобальный размер: 10 000. Возможно, вы хотите обработать их в группах по 100 вещей. Это ваш местный размер: 100. Поскольку 10 000/100 == 100, эта конкретная договоренность даст вам 100 рабочих групп. Выше у вас есть глобальный размер 16 и локальный размер 128. Это не имеет смысла для OpenCL — 16 / 128. Возможно, вы хотели, чтобы ваш глобальный размер составлял 16 * 128, а локальный — 128? Это дало бы 16 рабочих групп по 128 пунктов в каждой.

4. аааа, значит, ваш глобальный размер работы — это общее количество вычислений, которые вы хотите выполнить, а локальный размер работы — это то, насколько большим вы хотите сделать блок? Хм, теперь это имеет гораздо больше смысла 🙂