将结构数组作为openCL内核参数传递时的奇怪值

时间:2012-04-16 07:46:14

标签: struct kernel opencl arguments

当将一个结构数组作为参数传递给我的内核时,我得到第一个(数组[1],数组[2]等)之后的项的奇怪值。这似乎是一个对齐问题?

这是结构:

typedef struct Sphere
{
    float3 color;
    float3 position;
    float3 reflectivity;
    float radius;
    int phong;
    bool isReflective;
} Sphere;

这是主机端初始化代码:

cl::Buffer cl_spheres = cl::Buffer(context, CL_MEM_READ_ONLY, sizeof(Sphere) * MAX_SPHERES, NULL, &err);
err = queue.enqueueWriteBuffer(cl_spheres, CL_TRUE, 0, sizeof(Sphere) * MAX_SPHERES, spheres, NULL, &event);
err = kernel.setArg(3, cl_spheres);

实际上,数组中第二个Sphere结构的颜色实际上具有我在主机端设置颜色的最后一个值(s3或z),一个未初始化的零值,以及第一个值我在主机端设置的位置(s0或x)。我注意到float3数据类型实际上仍然有第四个值(s3)未初始化。我认为这是非初始化零值的来源。所以它似乎是一个对齐问题。我真的不知道我能做些什么来修复它。我希望也许有人可以解决这个问题。我确保我的结构定义在双方都完全相同。

1 个答案:

答案 0 :(得分:1)

从OpenCL 1.2规范,第6.11.1节:

  

请注意,任何给定的struct或union类型的对齐都是必需的   通过ISO C标准至少是最低的完美倍数   结构的所有成员的对齐的公共倍数   或者有问题的联盟,也必须是两个人的力量。

同样cl_float3计为cl_float4,请参阅第6.1.5节。

最后,在6.9.k节中:

  

程序中的内核函数的参数不能用   内置标量类型bool,half,size_t,ptrdiff_t,intptr_t和   uintptr_t或包含声明为的字段的结构和/或联合   其中一种内置标量类型。

要遵守这些规则,并且可能更快地访问,您可以尝试(OpenCL C端;在主机上使用cl_float4):

typedef struct Sphere
{
    float4 color;
    float4 position;
    float4 reflectivity;
    float4 radiusPhongReflective; // each value uses 1 float
} Sphere;