当将一个结构数组作为参数传递给我的内核时,我得到第一个(数组[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)未初始化。我认为这是非初始化零值的来源。所以它似乎是一个对齐问题。我真的不知道我能做些什么来修复它。我希望也许有人可以解决这个问题。我确保我的结构定义在双方都完全相同。
答案 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;