将 C 结构传递给 OpenCL 内核
Passing C structures to OpenCL kernel
我的主机程序中有下一个结构:
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;
我的内核中有下一个结构:
typedef struct s_figure
{
float reflection;
int color;
enum e_figure type;
float3 vector1;
float3 vector2;
float param1;
float param2;
} t_figure;
您还可以看到两者的枚举:
enum e_figure
{
BadFigure = -1,
InfinitePlane = 0,
Sphere = 1,
InfiniteCylinder = 2,
InfiniteCone = 3
};
以这种方式将数据传递给 OpenCL 内核时(其中数字是正确解析的结构数组):
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);
我遇到数据失真问题,例如,将数据传输到 OpenCL 内核后颜色可能会变得非常不同 (0xFFFFFF->0x007FC2)。此外,光线追踪算法在每次程序执行时以另一种方式工作。我该如何解决?我认为 gcc 编译器以不同于 openclc 的方式构建结构,但如何同步它?
您需要为主机和设备的结构声明指定 __attribute__ ((packed))
。否则,不同的编译器(主机编译器和设备编译器)可能会为结构创建不同的内存布局。
编辑:假设 sizeof(t_figure)
在主机和设备上都是 52,那么
根本原因可能与结构无关。
由于您使用 CL_MEM_USE_HOST_PTR 创建了一个缓冲区,所以有一些
您需要考虑的注意事项:
figures
您用 CL_MEM_USE_HOST_PTR
指定的指针
当缓冲区处于活动状态时必须指向有效内存,因为它
实际上用作cl_mem对象的底层内存存储。
用 CL_MEM_USE_HOST_PTR
创建的缓冲区已经占用了内存
(或其副本)由 figures
指向,因此后续写入
with clEnqueueWriteBuffer
在这里是多余的。更重要的是,
我什至不确定 clEnqueueWriteBuffer
在这方面的表现如何
case,因为这个操作本质上是一个memcpy(figures,figures, size)
.
我的主机程序中有下一个结构:
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;
我的内核中有下一个结构:
typedef struct s_figure
{
float reflection;
int color;
enum e_figure type;
float3 vector1;
float3 vector2;
float param1;
float param2;
} t_figure;
您还可以看到两者的枚举:
enum e_figure
{
BadFigure = -1,
InfinitePlane = 0,
Sphere = 1,
InfiniteCylinder = 2,
InfiniteCone = 3
};
以这种方式将数据传递给 OpenCL 内核时(其中数字是正确解析的结构数组):
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);
我遇到数据失真问题,例如,将数据传输到 OpenCL 内核后颜色可能会变得非常不同 (0xFFFFFF->0x007FC2)。此外,光线追踪算法在每次程序执行时以另一种方式工作。我该如何解决?我认为 gcc 编译器以不同于 openclc 的方式构建结构,但如何同步它?
您需要为主机和设备的结构声明指定 __attribute__ ((packed))
。否则,不同的编译器(主机编译器和设备编译器)可能会为结构创建不同的内存布局。
编辑:假设 sizeof(t_figure)
在主机和设备上都是 52,那么
根本原因可能与结构无关。
由于您使用 CL_MEM_USE_HOST_PTR 创建了一个缓冲区,所以有一些 您需要考虑的注意事项:
figures
您用CL_MEM_USE_HOST_PTR
指定的指针 当缓冲区处于活动状态时必须指向有效内存,因为它 实际上用作cl_mem对象的底层内存存储。用
CL_MEM_USE_HOST_PTR
创建的缓冲区已经占用了内存 (或其副本)由figures
指向,因此后续写入 withclEnqueueWriteBuffer
在这里是多余的。更重要的是, 我什至不确定clEnqueueWriteBuffer
在这方面的表现如何 case,因为这个操作本质上是一个memcpy(figures,figures, size)
.