OpenCL:结构内结构发送到设备端的内部功能

OpenCL: Struct within struct sending to internal function on device side

有一个关于 OpenCL 中的结构处理的问题,但我没有在此处找到。我收集了我在一个结构中使用的所有数据,该结构本身由多个结构组成。我想执行以下操作:

typedef struct tag_OwnStruct
  {
    float a;
    float b;
    float c;
    int d;
    float e;
    int f;
  }OwnStruct;

typedef struct tag_DataStruct
  {
     OwnStruct g;
     //+ Alot of other structs... not written for simplicity

  }DataStruct;

void PrintOwnStruct(OwnStruct* g)
{
  printf("Current lane id : %f\n",g->a);
}

__kernel void Test(__global DataStruct *data)
{
  PrintOwnStruct(&data->g);

}

所以我想根据从主机端发送到设备的给定数据,将引用发送到其中的结构。这在某种程度上不起作用,我不知道为什么。我在纯 C 代码中尝试了同样的事情并且它有效..

如果我将 PrintOwnStruct 更改为:

void PrintOwnStruct(OwnStruct g)
    {
      printf("Current lane id : %f\n",g.a);
    }

并将函数调用为:PrintOwnStruct(data->g) 代码将在设备端 运行。还有其他方法吗?因为我没有发送对函数的引用,它是按值传递的吗?这难道不应该比通过引用传递函数参数慢吗?

所以问题(来自评论)是 __private__global 地址 space 之间的混淆,可能 compiler/runtime 不是很有帮助在告知指针的组合。

void PrintOwnStruct(OwnStruct* g)
{
  printf("Current lane id : %f\n",g->a);
}

__kernel void Test(__global DataStruct *data)
{
  PrintOwnStruct(&data->g);
}

__global DataStruct *data 是指向 __global 地址 space 中某物的指针 [换句话说,所有 CL 线程具有相同的地址],void [=15= 的参数] OwnStruct* g) 在默认 __private 地址 space 中声明一个指向 OwnStruct 的参数 [换句话说,在该线程的堆栈上]。

正确的做法是通过声明函数 PrintOwnStruct(__global OwnStruct* g) 为指向 __global 的两个指针维护地址 space。

我很确定某些 OpenCL 编译器会为此给出错误,但显然不是这个。我希望真正的语法错误,例如在代码中添加 %-&6 实际上会给你一个根本没有 运行 的内核,所以当你调用 clCreateKernelclBuildProgram,你会得到一个错误 - 可以通过 clGetProgramBuildInfo 显示。但是,如果编译器没有检测到不同的地址 space,那么它就是编译器的 bug/feature。

[事实上,如果你的编译器是基于 Clang 的,你可能想看看这个错误: https://llvm.org/bugs/show_bug.cgi?id=19957 - 谷歌搜索半小时给出了某种结果! :)]

在较新的 CL2.0 中,默认地址-space 是 generic,这允许使用 "any" 地址 space。