__local struct array opencl

时间:2014-12-05 09:50:43

标签: arrays struct opencl

我在使用这行代码时遇到了一些问题:

__local cl_var new_vars[10];

这些都有效:

__local cl_var test;
__local int test[10];
__local cl_var * test

供参考,cl_var是:

typedef struct cl_var{
   int var;
   struct cl_var* next;
} cl_var;

尝试编译时出现seg错误。我正在使用JOCL包,不确定这是否有所作为。

为什么我不能在本地声明一系列结构?

(我尝试将结构定义更改为在各个地方包含local)

2 个答案:

答案 0 :(得分:0)

原因是记忆对齐。根据这个article及其中的评论,你必须小心对齐。在本页的评论部分中对David Garcia的解释非常清楚对齐:一些编译器可能会选择在16字节上填充结构大小。

post in Khronos forum中有重要的附加信息:

  

OpenCL中的基本数据类型(整数和浮点数据类型)具有已定义的大小和对齐要求(请参阅OpenCL 1.1规范的第6.1.5节)。确保主机和主机之间的对齐匹配在设备上使用这些数据类型的OpenCL内核,使用cl_来声明将由主机和设备共享的结构(参见1.1规范中表6.1之后的表)。

所以你应该使用cl_float代替float,如果我理解spec page on basic OpenCL types

,也可以明确指定对齐方式
  

对于3分量矢量数据类型,数据类型的大小为4 * sizeof(分量)。这意味着3分量矢量数据类型将与4 * sizeof(分量)边界对齐。

因此,显式对齐可能会解决您的问题。

除此之外,这个答案的第二部分:

  

请注意,这仅适用于整数&浮点数据类型。对齐规则不适用于指针。这就是为什么指针不能嵌入OpenCL中的结构中的一个原因。

OpenCL规范在这个主题上非常明确:"你不能将包含指针的结构传递给OpenCL" (引自here,并确认there,我太懒了,无法抓住规格页... :))。显然,这不是这种情况,但是你的结构不会成为内核参数的有效类型。

答案 1 :(得分:0)

我无法在编译时(或甚至是运行时)重现错误。我对JOCL不熟悉,所以无法帮助我。 我正在使用Windows,NVIDIA和JIT编译OpenCL内核。

您是否也通过访问new_vars在内核中使用已分配的内存,或者您是否只声明__local cl_var new_vars[10];并发生错误?

你的意思是什么"我试过改变结构定义以在各个地方包含本地"?您是否已将local地址空间限定符添加到" next"指针? 如果是这样,那么我的以下解释可能不是解决方案。

从我看到的,错误的潜在原因是缺少地址空间限定符(无法验证,因为我无法重现错误)。您的问题是OpenCL中的指针类型总是带有地址空间限定符privatelocalglobalconstant(请参阅here)。如果你遗漏它,OpenCL默认选择private:"如果没有指定地址空间限定符,则声明为指针的变量被认为指向__private地址空间" (见Notes)。

这就是你的结构发生了什么。在结构体中,您声明了一个指向结构本身的指针,但是您没有指定任何地址空间限定符,因此默认设置为private。

书写

typedef struct cl_var{
   int var;
   struct cl_var* next;
} cl_var;

相当于写作

typedef struct cl_var{
   int var;
   private struct cl_var* next;
} cl_var;

当通过写__local cl_var new_vars[10];在本地内存中静态分配10个cl_var对象时,地址空间限定符不匹配,因为对象驻留在本地内存中,但期望指向一个对象(" next&# 34;)在私人记忆中。因此,当在对象中使用指针时,程序应该崩溃,但仅在运行时,而不是编译时(除非你的编译器非常敏感 - 在这种情况下实际上这是一件好事)。

写作

typedef struct cl_var{
   int var;
   local struct cl_var* next;
} cl_var;

你应该能够分配内存。

旁注:尝试避免使用" new"来命名数组,由于它与动态内存分配的关联,它可能会使人感到困惑(并且动态内存分配不是示例代码中发生的事情) !)。