OpenCL 结构对齐错误

OpenCL struct alignment errors

我在 OpenCL 中对齐主机和设备之间的结构时遇到了问题。我在主机和设备上定义了许多自定义结构,除了一个之外,它们似乎都运行良好。

我正在发送一个数组中的两个结构。第一个结构 (sObject[0]) 中的所有值都在设备中被正确读取,但第二个 (sObject[1]) 正在以一种看似损坏的方式读取,其中所有值都混淆了,有些值丢失了。

据我所知,这可能是数据对齐的问题,其中主机和设备可能具有不同的类型分配或填充,但我已验证数据类型在主机和设备上具有相同的大小device 和我尝试使用 #pragma pack(8)__attribute__ ((aligned (128)))__attribute__ ((packed)) 等对齐方式,尽管我不确定它们是否与编译器 (VS2017) 一起正常工作。

这是主机和设备上的结构代码:

主持人:

typedef struct _cl_tag_sObject {
    cl_double3 m_vCenter;
    cl_double3 m_vBounds1;
    cl_double3 m_vBounds2;
    cl_double m_dRadius;
    cl_bool m_type;
} sObject;

设备:

typedef struct _cl_tag_sObject {
    double3 m_vCenter;
    double3 m_vBounds1;
    double3 m_vBounds2;
    double m_dRadius;
    bool m_type;
} sObject;

以下是主机上的分配值和从设备读取的值:

主持人:

m_vCenter = (0,-100.5,0)
m_vBounds1 = (2,2,2)
m_vBounds2 = (3,3,3)
m_dRadius = 100
m_type = 0

设备:

m_vCenter = (0,0,2)
m_vBounds1 = (2,0,3)
m_vBounds2 = (3,0,100)
m_dRadius = 1
m_type = 0

似乎省略了值 -100.5(2,2,2)(3,3,3) 中的中间值取代了填充,尽管我是 OpenCL 的新手并且不确定至于这个过程实际上是如何工作的。

是什么导致了这个问题,如何解决?

谢谢。

WRT 结构打包:__attribute__ ((packed)) 导致 GCC 和 LLVM 上的结构元素之间 零填充 。我不知道您的设备的实现是否使用它们。我几乎没有使用 VS 的经验,但我认为 #pragma pack(1) 是您在主机端获得零填充所需要的。

除了打包之外,您需要注意 cl_<type>3 类型在 CL/cl_platform.h header 中被类型定义为 cl_<type>4 类型。所以在 host 方面,它们本质上是相同的。

因此,即使打包,您的结构也有 cl_double4 和 4 个元素,并且在主机内存中应该如下所示(转换为双精度数组):

0 100.5 0 0 | 2 2 2 0 | 3 3 3 0 | 100

怀疑 您设备的编译器忽略了主机约定并为 double3 使用真正的 3 元素向量。您可以简单地通过将 device-side 结构更改为使用 double4:

来验证
    double4 m_vCenter;
    double4 m_vBounds1;
    double4 m_vBounds2;

不幸的是,结构在 OpenCL 中是一个灰色区域。可能最好避免结构内部的 3 元素向量..