Как вы работаете с невозможностью передать список cl_mem в вызов ядра?

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

Вот несколько вещей, которые я пробовал:

  1. Просто есть много аргументов ядра. Конечно, звучит халтурно, но работает для малых N. Именно этим мы и занимались.
  2. Сделайте 1) с каким-то циклом макросов, который расширяет аргументы ядра до максимального размера (что, я думаю, зависит от устройства). Я действительно не хочу этого делать... это звучит плохо.
  3. Создайте какой-то список структур, содержащих указатели, и заполните его перед вызовом ядра. Я попробовал это, и я думаю, что это нарушает спецификацию. Согласно тому, что я видел на форумах nVidia, сохранение адреса указателя устройства после одного вызова ядра является незаконным. Если кто-нибудь может указать, где в спецификации это сказано, я хотел бы знать, потому что я не могу его найти. Тем не менее, это определенно ломает аппаратное обеспечение ATI, поскольку оно перемещает объекты.
  4. Откажитесь, сохраните объекты переменного размера в большом массиве и напишите умный алгоритм для использования пустого пространства, чтобы весь массив приходилось реже перекомпоновывать. Это будет работать, но это неэлегантный и сложный дизайн. Кроме того, это требует много страшной арифметики указателя...

У кого-нибудь есть другие идеи? Как насчет опыта, пытающегося сделать это; есть ли наименее хакерский способ? Почему?


person Benjamin Horstman    schedule 27.07.2011    source источник


Ответы (2)


К 3: спецификация OpenCL 1.1, страница 193, говорит: «Аргументы функций ядра в программе не могут быть объявлены как указатель на указатель (указатели)».

Структура, содержащая указатель на указатель (указатель на объект буфера), возможно, не противоречит строгому чтению этого предложения, но соответствует духу: никакие указатели на объекты буфера не могут передаваться в качестве аргументов из хост-кода в ядро, даже если они скрыты внутри определяемая пользователем структура.

Я бы выбрал вариант 5: не использовать структуры данных переменного размера. Если у вас есть способ сделать их постоянными, сделайте это. Это сделает вашу жизнь намного проще. Чтобы быть точным, нет никакой «структуры переменного размера». Каждое определение структуры создает структуры постоянного размера, поэтому, если размер изменился, то изменилась сама структура и, следовательно, требуется другой объект памяти. Каждый указатель, передаваемый в функцию ядра, должен иметь один тип.

person sharpneli    schedule 28.07.2011

В дополнение к шарнелису вариант ответа 5:

Если объекты имеют одинаковый размер, вы можете использовать объединения для максимально возможного размера объекта. Но убедитесь, что вы используете явное выравнивание. Передайте второй буфер, идентифицирующий объединение, используемое в каждом объекте в вашем буфере объединения объектов переменного размера в статическом размере.

Я вернулся к этому при использовании кода opencl lib, который допускал только один массив переменных произвольного типа. Я просто использовал cl_float2 для передачи двух чисел с плавающей запятой. Поскольку типы cl_floatN реализованы как союзы, то, что работает для встроенных типов, будет работать и для вас.

person Armin    schedule 26.09.2014