#opencl
#opencl
Вопрос:
У меня есть этот код, для которого я уже опубликовал что-то некоторое время назад.
Сегодня я запустил свое ядро со структурой typedef в небольшой тестовой программе, но clEnqueueNDRangeKernel
выдает недопустимую ошибку размера рабочей группы. Согласно веб-сайту khronos, это может иметь 3 причины.
- Глобальный размер работы не может быть разделен на локальный размер работы. В моем коде оно делимо.
- Размер локальной работы больше, чем может обработать графический процессор. Мой локальный рабочий размер равен 128, что намного меньше заявленного максимума 1024.
- Что-то связанное с локальным рабочим размером
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. аааа, значит, ваш глобальный размер работы — это общее количество вычислений, которые вы хотите выполнить, а локальный размер работы — это то, насколько большим вы хотите сделать блок? Хм, теперь это имеет гораздо больше смысла 🙂