我在使用这行代码时遇到了一些问题:
__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)
答案 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中的指针类型总是带有地址空间限定符private
,local
,global
或constant
(请参阅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"来命名数组,由于它与动态内存分配的关联,它可能会使人感到困惑(并且动态内存分配不是示例代码中发生的事情) !)。