OpenCL:无法将整数传递给常量内存

OpenCL:无法将整数传递给常量内存,opencl,Opencl,我写了一个这样的内核 kernel void computeLayerOutput_Rolled(global Layer* restrict layers, constant int* restrict netSpec, __constant const int layer1) 但是在创建内核时发生了一个cl::Error,错误信息是 :29:123: error: invalid address space for argument to __kernel function kernel

我写了一个这样的内核

kernel void computeLayerOutput_Rolled(global Layer* restrict layers, constant int* restrict netSpec, __constant const int layer1)
但是在创建内核时发生了一个
cl::Error
,错误信息是

:29:123: error: invalid address space for argument to __kernel function
kernel void computeLayerOutput_Rolled(global Layer* restrict layers, constant int* restrict netSpec, __constant const int layer1)
                                                                                                                          ^
:29:123: error: parameter may not be qualified with an address space

terminate called after throwing an instance of 'cl::Error'
  what():  clCreateKernel
当我删除
layer1
\u常量
限定符时,一切正常,但我不想将其放入私有内存,因为它可能会在每个工作项中占用一个寄存器。只传递一个元素的数组似乎也不是一个非常优雅的解决方案


我只是想知道还有什么别的办法可以解决这个问题吗?

我刚才也遇到过同样的“问题”。我习惯了CUDAC/C++处理常量内存的方式,并试图找到一种解决方案,在OpenCL中获得同样的便利。长话短说,我没找到。如果你想要恒定的内存,你可以做两件事:

  • 按照建议传入指向常量地址空间的指针,或
  • 使用#定义并重新编译
  • 这些解决方案中没有一个是非常漂亮的,但它们做了它们应该做的事情


    但是,如果传递整数的唯一问题是担心寄存器使用率过高,则可以继续提供每个值的整数。如果指针的大小为32位,则单个整数值将占用与指向常量内存的指针一样多的寄存器。

    我刚才遇到过同样的“问题”。我习惯了CUDAC/C++处理常量内存的方式,并试图找到一种解决方案,在OpenCL中获得同样的便利。长话短说,我没找到。如果你想要恒定的内存,你可以做两件事:

  • 按照建议传入指向常量地址空间的指针,或
  • 使用#定义并重新编译
  • 这些解决方案中没有一个是非常漂亮的,但它们做了它们应该做的事情

    但是,如果传递整数的唯一问题是担心寄存器使用率过高,则可以继续提供每个值的整数。如果指针的大小为32位,则单个整数值将占用与指向常量内存的指针一样多的寄存器。

    规范说明(标签):

    (1) 中函数参数的通用地址空间名称 程序或函数的局部变量是私有的。所有论点 到
    \u内核
    函数应位于
    \u私有
    地址空间中

    (2)
    \uu内核
    声明为类型指针的函数参数只能指向以下地址空间之一:
    \uu全局
    \uu局部
    \u常数

    换句话说,在内核参数中,只有指针可以限定为
    \uu常量
    layer1
    不是指针,因此它不能是
    \uu常量

    我不想把它放到私有内存中,因为它可能会在每个工作项中占用一个寄存器

    layer1
    可能已经在使用寄存器,因为它已经在私有内存中:正如引号(1)所示,内核函数的所有参数都在
    \u private
    地址空间中,该地址空间可能映射到寄存器

    为了澄清,在编写
    常量int*restrict netSpec
    时,不要混淆:

    • 指针的地址空间(参数
      netSpec
      位于
      \u private
      地址空间)
    • 指针对象的地址空间(netSpec指向的是
      \u常量中的地址空间)
    规范上说(我的标签):

    (1) 中函数参数的通用地址空间名称 程序或函数的局部变量是私有的。所有论点 到
    \u内核
    函数应位于
    \u私有
    地址空间中

    (2)
    \uu内核
    声明为类型指针的函数参数只能指向以下地址空间之一:
    \uu全局
    \uu局部
    \u常数

    换句话说,在内核参数中,只有指针可以限定为
    \uu常量
    layer1
    不是指针,因此它不能是
    \uu常量

    我不想把它放到私有内存中,因为它可能会在每个工作项中占用一个寄存器

    layer1
    可能已经在使用寄存器,因为它已经在私有内存中:正如引号(1)所示,内核函数的所有参数都在
    \u private
    地址空间中,该地址空间可能映射到寄存器

    为了澄清,在编写
    常量int*restrict netSpec
    时,不要混淆:

    • 指针的地址空间(参数
      netSpec
      位于
      \u private
      地址空间)
    • 指针对象的地址空间(netSpec指向的是
      \u常量中的地址空间)

    您的意思是恒定内存值的地址也需要额外的寄存器吗?我从来没有想过。。。非常感谢,MichaelDo你是说恒定内存值的地址也需要额外的寄存器?我从来没有想过。。。非常感谢,MichaelIn练习的论点可能不会占用寄存器。“私有”数据是否映射到寄存器实际上是编译器问题和实现定义的问题。一些实现可能将内核参数映射到常量内存中。考虑到它们是统一的,在它们被写入之前无法区分它们之间的差异,此时它们被提升到寄存器。如果参数是常量,则无论如何都不会写入它。@Lee--我认为编译器可以这样做,但不是必须这样做。“因为我没有添加任何优化标志,所以我对此一无所知。”杨蓓——也许我对恒定内存的组织不太熟悉。我认为它就像一个非常大的寄存器文件,不需要指针之前。。。看来我是wrong@ch94--理论上是正确的。实际上,他们可能会这样做,也可能不会。如果实现的设计使内核参数进入常量