Поведение кода OpenCL отличается для карт AMD и NVIDIA.

У меня есть константа в верхней части моего кода...

__constant uint uintmaxx =  (uint)(  (((ulong)1)<<32) - 1 );

Он отлично компилируется на компиляторах AMD и NVIDIA OpenCL... затем выполняется.

(правильно) на картах ATI возвращает... 4294967295 или (все 32 бита = 1)

(неверно) на картах NVIDIA возвращает... 2147483648 или (только 32-й бит = 1)

Я также попробовал -1 + 1‹‹32, и это сработало на ATI, но не на NVIDIA.

Что дает? Я просто что-то упустил?

Пока я говорю о различиях компиляторов OpenCL, кто-нибудь знает хороший ресурс, в котором перечислены различия компиляторов между AMD и NVIDIA?


person extracrispy    schedule 07.11.2013    source источник


Ответы (2)


OpenCL уже предоставляет это вам. Вы можете использовать предопределенный UINT_MAX в коде ядра, и реализация гарантирует, что он содержит правильное значение.

Однако в используемом вами методе также нет ничего плохого. Спецификация гарантирует, что uint является 32-битным, а ulong 64-битным, int является дополнением до двух, и все, что не указано явно, работает именно так, как написано в спецификации C99.

Даже просто это должно работать и давать правильный результат: uint uintmaxx = -1;

Похоже, у NVidia просто сломан компилятор, если нет, то я очень надеюсь, что меня поправят в этом вопросе. Действительно странная часть заключается в том, как, черт возьми, 32-й бит равен 1? Сдвиг влево на 32 перемещает исходный бит на 33-е место. Так что же ставит немного на 32-е место? Единственное, что мне пришло в голову, это то, что они вообще не соблюдают порядок операторов и преобразуют формулу в (ulong)1 ‹‹ (32-1) или что-то в этом роде.

Вы, вероятно, должны подать отчет об ошибке. Но, если честно, учитывая, что они ненавидят OpenCL так же сильно, как Microsoft ненавидит OpenGL, если не больше, я бы не стал ожидать быстрого времени отклика.

person sharpneli    schedule 07.11.2013
comment
Спасибо. Я должен был просто использовать определение или -1. Я не думал об этом, и в итоге он укусил меня. - person extracrispy; 07.11.2013

Я полностью согласен с ответом @sharpneli. Но просто попробуйте это:

__constant uint uintmaxx = -1;

И, как сказал Sharpneli, используйте макрос UINT_MAX, это более безопасный способ.

person DarkZeros    schedule 07.11.2013