【问题标题】:OpenCL variable declaration failed outside kernel scopeOpenCL 变量声明在内核范围之外失败
【发布时间】:2018-10-14 13:10:51
【问题描述】:

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

__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

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

【问题讨论】:

    标签: c function kernel opencl


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

    【讨论】:

    • 我可以在哪里以及如何将-cl-std=CL2.0 传递给clBuildProgram?我在 MQL5 中使用 Opencl。
    • 根据我在此处看到的 (mql5.com/en/docs/opencl/clprogramcreate),无法使用 MQL5 传递额外的编译选项,但我不是 MQL5 专家,因此您可能会找到解决方法。
    【解决方案2】:

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

    【讨论】:

    • 这是否意味着我不能在内核之外拥有一个全局变量?我可以这样声明吗:khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/global.html 但是这个对我没有帮助。
    • 正如他所说,“在 OpenCL C 内核语言中不能有全局变量。”它是正确的。 __global 地址限定符用于指针。使用缓冲区来保存所有工作项都需要访问的值。此外,get_global_id(3) 似乎无效;你只能访问 0 到 2。
    猜你喜欢
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 2020-02-03
    • 2016-09-18
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多