I have next structure in my host program:
typedef struct s_figure
{
cl_float reflection;
cl_int color;
enum e_figure type;
cl_float3 vector1;
cl_float3 vector2;
cl_float param1;
cl_float param2;
} t_figure;
I have next structure in my kernel:
typedef struct s_figure
{
float reflection;
int color;
enum e_figure type;
float3 vector1;
float3 vector2;
float param1;
float param2;
} t_figure;
Also you can see enum for both of it:
enum e_figure
{
BadFigure = -1,
InfinitePlane = 0,
Sphere = 1,
InfiniteCylinder = 2,
InfiniteCone = 3
};
While passing data to the OpenCL kernel in this way (where figures is an correct parsed structures array):
buf_figures = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(t_figure) * figures_count, figures, &err);
clEnqueueWriteBuffer(view->cl->queue, buf_figures, CL_TRUE, 0,sizeof(t_figure) * figures_count, figures, 0, NULL, NULL);
I have a problems with data distortion, for example color after transferring data to OpenCL kernel can be changed to very different (0xFFFFFF->0x007FC2). Also raytrace algorithms works in another way every program execution. How can I fix it? I think gcc compiler make structures in different way than openclc but how to sync it?
You need to specify __attribute__ ((packed))
for a struct declaration for both host and device. Otherwise different compilers (host compiler and device compiler) may create different memory layout for a struct.
EDIT: Given that sizeof(t_figure)
is 52 on both host and device, then the
root cause is probably not related to the struct.
Since you create a buffer with CL_MEM_USE_HOST_PTR, there are some caveats you need to consider:
figures
pointer that you specify with CL_MEM_USE_HOST_PTR
must point to a valid memory while a buffer is alive, because it
is actually used as an underlying memory storage for cl_mem object.
Buffer created with CL_MEM_USE_HOST_PTR
already uses a memory
(or a copy of it) pointed by figures
, so a subsequent write
with clEnqueueWriteBuffer
is redundant here. More importantly,
I'm not even sure how clEnqueueWriteBuffer
behaves in this
case, because this operation is essentially a memcpy(figures,figures, size)
.