OpenCL:结构发送到设备端的内部函数

时间:2016-02-29 22:25:49

标签: struct opencl

在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)代码将在设备端运行。有没有其他方法可以做到这一点?由于我没有发送对函数的引用,它是否通过值传递?并且不应该比通过引用传递函数参数慢吗?

1 个答案:

答案 0 :(得分:1)

因此问题出现(来自注释)是__private__global地址空间之间的混淆,并且可能编译器/运行时在通知指针混合方面不是很有帮助。

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地址空间中某些内容的指针[换句话说,所有CL线程具有相同的地址],void PrintOwnStruct OwnStruct* g)的参数声明一个在默认OwnStruct地址空间中指向__private的参数[换言之,在此线程的堆栈中]。

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

我很确定某些OpenCL编译器会为此提供错误,但显然不是这个错误。我希望真正的语法错误,例如将%-&6添加到代码中实际上会为您提供一个根本无法运行的内核,因此当您调用clCreateKernelclBuildProgram时,您将收到错误 - 可由clGetProgramBuildInfo显示。但是如果编译器没有检测到不同的地址空间,那么它就是编译器的错误/特征。

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

在较新的CL2.0中,默认地址空间为generic,允许"任何"地址空间。