OpenCL变量声明在内核范围之外失败

时间:2018-05-04 06:11:41

标签: c function kernel opencl

我正在尝试维护一个可以像静态变量一样运行的内核智能全局变量。这样我就可以将前一个值存储在变量中以进行进一步的计算 这是我尝试过的以及我得到的错误:

__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 :(得分:1)

您可以在__global地址空间中拥有程序范围或静态变量,但仅限于OpenCL 2.0。如果您的OpenCL实现(驱动程序)支持OpenCL 2.0,则可以将-cl-std=CL2.0传递给clBuildProgram以启用此功能。

规范中的相关引用:

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限定符一起使用,以指定只读缓冲区内存对象。

答案 1 :(得分:0)

您不能在OpenCL C内核语言中使用全局变量。 您可以创建一个主机缓冲区(clCreateBuffer)并将其传递给内核(clSetKernelArg),然后它成为内核中指向global的指针。 您还可以在私有内存中创建指向全局的指针,但这仅对每个工作项可见。