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

Struct 将结构数组作为openCL内核参数传递时出现奇怪的值,struct,kernel,opencl,arguments,Struct,Kernel,Opencl,Arguments,当将一个结构数组作为参数传递给内核时,我会得到第一个数组之后的项的奇怪值(数组[1],数组[2],等等)。这似乎是一个对齐问题,也许 以下是结构: typedef struct Sphere { float3 color; float3 position; float3 reflectivity; float radius; int phong; bool isReflective; } Sphere; 以下是主机端初始化代码: cl::Buff

当将一个结构数组作为参数传递给内核时,我会得到第一个数组之后的项的奇怪值(数组[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);

发生的情况是,数组中第二个球体结构的颜色实际上将具有我在主机侧设置颜色的最后一个值(s3或z)、一个未初始化的零值,以及我在主机侧设置位置的第一个值(s0或x)。我注意到float3数据类型实际上仍然有第四个值(s3),没有初始化。我认为这就是未初始化的零值的来源。因此,这似乎是一个对齐问题。我真的不知道我能做些什么来修复它。我希望有人能解释一下这个问题。我已确保我的结构定义在两侧完全相同。

来自OpenCL 1.2规范,第6.11.1节:

请注意,任何给定结构或联合类型的对齐都是必需的 根据ISO C标准,至少是最低值的完美倍数 结构的所有成员对齐的公共倍数 或者说,联盟是有问题的,而且必须是一个二人的力量

此外,
cl\u浮动3
也算作
cl\u浮动4
,参见第6.1.5节

最后,在第6.9.k节中:

程序中内核函数的参数不能用 内置标量类型bool、half、size_t、ptrdiff_t、intptr_t和 uintptr\t或包含声明为 这些内置标量类型之一

为了遵守这些规则,并可能加快访问速度,您可以尝试(OpenCL C端;在主机上使用
cl\u float4
):


根据OpenCL 1.2规范第6.11.1节:

请注意,任何给定结构或联合类型的对齐都是必需的 根据ISO C标准,至少是最低值的完美倍数 结构的所有成员对齐的公共倍数 或者说,联盟是有问题的,而且必须是一个二人的力量

此外,
cl\u浮动3
也算作
cl\u浮动4
,参见第6.1.5节

最后,在第6.9.k节中:

程序中内核函数的参数不能用 内置标量类型bool、half、size_t、ptrdiff_t、intptr_t和 uintptr\t或包含声明为 这些内置标量类型之一

为了遵守这些规则,并可能加快访问速度,您可以尝试(OpenCL C端;在主机上使用
cl\u float4
):


你能出示你的clEnqueueWriteBuffer密码吗?我认为
bool
有一个问题导致填充不对齐。还考虑在使用结构时使用<代码> CLY[DATATYPE ] 类型作为主机代码。我正在使用C++绑定。我虔诚地使用cl_数据类型。你能展示一下你的clEnqueueWriteBuffer代码吗?我认为
bool
有一个问题导致填充不对齐。还考虑在使用结构时使用<代码> CLY[DATATYPE ] 类型作为主机代码。我正在使用C++绑定。我虔诚地使用cl_数据类型。
typedef struct Sphere
{
    float4 color;
    float4 position;
    float4 reflectivity;
    float4 radiusPhongReflective; // each value uses 1 float
} Sphere;