首页 > 解决方案 > 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

让我知道在这种情况下我能做些什么。请建议我一个正确的方法,以便有效地编程。

标签: cfunctionkernelopencl

解决方案


您可以在地址空间中拥有程序范围或静态变量__global,但仅限于 OpenCL 2.0。如果您的 OpenCL 实现(驱动程序)支持 OpenCL 2.0,您可以通过-cl-std=CL2.0to启用此功能。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 限定符一起使用,以指定只读缓冲存储器对象。


推荐阅读