Сбой объявления переменной OpenCL вне области ядра - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь поддерживать глобальную переменную ядра, которая может действовать как статическая переменная. Так что я могу сохранить предыдущее значение в переменной для дальнейших вычислений.
Вот что я попробовал и что я получил как ошибку:

__global int weightsum;
__kernel void calcLWMALoop(int begin, int limit, __global double *price, __global double *firstValue, int weightsum)
          {
            int len = get_global_id(3);
            for(int i=begin;i<limit;i++)
            {                 
               weightsum+=(i-begin+1);
               firstValue[len]+=(i-begin+1)*price[i];
            }
      firstValue[len]/=(double)weightsum;

          }

Ошибка вывода:

OpenCL program create failed: INVALID_HANDLE <kernel>:41:14: error: variable has address space that is not supported in program scope declaration
__global int weightsum;
             ^
<kernel>:41:14: error: global variables must have a constant address space qualifier
5105

Код ошибки 5105 гласит: Error occurred when compiling an OpenCL program

Дайте мне знать, что я могу сделать в этой ситуации. Пожалуйста, предложите мне правильный путь, чтобы можно было эффективно программировать.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Вы можете иметь программную область или статические переменные в __global адресном пространстве, но только в OpenCL 2.0. Вы можете передать -cl-std=CL2.0 в clBuildProgram, чтобы включить это, если ваша реализация OpenCL (драйвер) имеет поддержку OpenCL 2.0.

Связанные цитаты из спецификации:

OpenCL 1.x: https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/global.html

Все переменные области действия программы должны быть объявлены в адресном пространстве __constant.

OpenCL 2.0: https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/global.html

Переменные, определенные в области действия программы, и статические переменные внутри функции также могут быть объявлены в глобальном адресном пространстве. Они могут быть определены с любым допустимым типом данных OpenCL C, кроме тех, которые указаны в таблице 6.3. В частности, такие переменные области действия программы могут иметь любой определенный пользователем тип или указатель на определенный пользователем тип. При наличии разделяемой виртуальной памяти эти указатели или члены-указатели должны работать должным образом, если они являются указателями совместно используемой виртуальной памяти и указанное хранилище, на которое ссылаются, было сопоставлено соответствующим образом. Эти переменные в глобальном адресном пространстве имеют то же время жизни, что и программа, и их значения сохраняются между вызовами любого из ядер в программе. Эти переменные не являются общими для всех устройств. У них есть отличное хранение.

Область действия программы и статические переменные в глобальном адресном пространстве могут быть инициализированы, но только с помощью константных выражений.

Спецификатор const также можно использовать с квалификатором __global для указания объекта буферной памяти только для чтения.

0 голосов
/ 04 мая 2018

Вы не можете иметь глобальные переменные на языке ядра OpenCL C. Вы можете создать буфер хоста (clCreateBuffer) и передать его ядру (clSetKernelArg), и тогда он станет указателем на глобальный в вашем ядре. Вы также можете создавать указатели на глобальные в личной памяти, но это видно только для каждого рабочего элемента.

...