2014-12-05 140 views
0

我遇到这行代码的一些问题:__local结构阵列的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包,不知道这是否有所作为。

为什么我不能有一个本地声明的结构数组的任何理由?

(我试图改变结构定义,包括在不同的地方本地)

+1

我不认为你可以包含一个指向自己的指针。由于它尚未定义。此外,它正在生成无限递归问题。 – DarkZeros 2014-12-05 10:23:26

+0

@DarkZeros我最初确实有这个问题,但包括struct关键字固定,我猜它是一个不同的命名空间。此外,它在任何地方都可以,除非将它用作本地数组。 – 2014-12-05 10:48:06

+0

'我在编译时遇到seg错误。'你的意思是你在编译时**得到一个段错误**? – 2014-12-05 10:48:48

回答

0

的原因是内存对齐。根据article和其中的评论,您必须小心对齐。 David Garcia在这个页面的注释部分中的解释非常明确:一些编译器可以选择填充16个字节的结构大小。

有一个在此post in Khronos forum重要的附加信息:在OpenCL的

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

所以,你应该用cl_float代替float,也许还可以指定明确的定位,如果我理解spec page on basic OpenCL types

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

所以也许明确的对齐将解决您的问题。

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

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

OpenCL的规范是在这个问题上明确表示:“你不能将包含指针到OpenCL的一个结构”(从here报价,并且也证实there,我懒得抢规范网页.. 。:))。显然这里并不是这种情况,但是你的结构将不会成为内核参数的有效类型。

+0

我不把它传递给内核参数,这些都是在函数中声明的,也是 - 它导致问题的唯一时间是在本地数组内使用时,以任何其他描述它的方式使用。 – 2014-12-05 10:49:13

+0

是的,这就是为什么结构体中的指针并不真正相关,但我认为很好的提及。但是你有没有试图声明一个16字节的结构对齐? – Bentoy13 2014-12-05 13:15:10

+0

我没有,我会考虑现在这样做,但为什么只会影响本地数组,没有任何其他类型的数组,或本地指针,或本地正常? – 2014-12-05 19:46:10

0

我无法在编译时(甚至是运行时)重现错误。我不熟悉JOCL,因此无法在这方面提供帮助。 我正在使用Windows,NVIDIA和JIT编译OpenCL内核。

您是否还在内核中使用分配的内存?new_vars或者您是否只声明__local cl_var new_vars[10];并且发生错误?

另外你是什么意思与“我试图改变结构定义包括本地在不同的地方”?您是否已将local地址空间限定符添加到“下一个”指针? 如果是这样,那么我的以下解释可能不是解决方案。

从我所看到的,错误的潜在原因是缺少地址空间限定符(无法验证,因为我无法重现错误)。您的问题是OpenCL中的指针类型始终带有地址空间限定符private,local,globalconstant(请参阅here)。如果将它保留,OpenCL默认选择private:“如果未指定地址空间限定符,则声明为指针的变量被视为指向__私有地址空间”(请参阅​​Notes)。

这就是你的结构发生了什么。在struct中声明了一个指向结构本身的指针,但是你没有指定任何地址空间限定符,所以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对象,地址空间限定符不匹配,因为对象驻留在本地内存,但期望在私有内存中指向一个对象(“下一个”)。因此,在对象中使用指针时,程序应该会崩溃,但只能在运行时而不是编译时(除非编译器非常敏感 - 在这种情况下实际上是一件好事)。

通过编写

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

你应该能够分配内存。注意:尽量避免使用“新”来命名你的数组,因为它与动态内存分配的联系(并且动态内存分配不在你的示例代码中发生的事情),它可能会让人困惑。