初始化一个 OpenCL 对象
Posted
技术标签:
【中文标题】初始化一个 OpenCL 对象【英文标题】:initialise an OpenCL object 【发布时间】:2013-03-21 17:47:54 【问题描述】:嗨,我想知道我是否可以创建一个像这样的结构的 openCL 对象
struct Product
int n_id;
char n_name;
Item(id, name)n_id = id; n_name = name;
item;
我想将此信息传递给内核,以使该结构可从另一个结构重用。
我想通过内核添加项目
kernel addItem(int name, char name)
Item it(id,name);
Items.add(it);
所以我的问题是如何传递这些信息以及如何使我创建的对象可从另一个内核重用?
干杯
【问题讨论】:
【参考方案1】:OpenCL 内核是用类似 C99 的受限制(例如,结构中没有指针)和扩展(例如 float4 数据类型)语言编写的。它们不是用 C++ 编写的。
您在主机上初始化类似 C 的结构,然后将它们复制过来。类似 C 的结构没有方法。在带有 Visual Studio 的主机上使用 C++ OpenCL 绑定(来自 cl.hpp)我执行以下操作:
#pragma pack(16)
struct Light
cl_float4 pos;
cl_float4 dir;
cl_float4 intensity;
cl_int type;
cl_int pad[3];
;
#pragma pack()
const int nlight = 10
Light lights[nlight];
//...code to initialize array of structs
cl::Buffer lights_mem = cl::Buffer(context, CL_MEM_COPY_HOST_PTR, sizeof(Light)*nlight, lights);
kernel1.setArg(0, lights_mem);
这会将灯光复制到 OpenCL 设备。在内核中,您可以像这样访问灯光结构:
__kernel void trace(__global Light* lights, ...)
float4 pos = lights[0].pos
//find a new position (pos_new)
lights[0].pos = pos_new;
内核完成后,您可以将 cl::Buffer lights_mem 传递给下一个内核。
kernel2.setArg(0, lights_mem);
但是,您可以通过使用只读或只写缓冲区来获得更快的速度,因此它可能有助于将您的内核分为只读和只写内核。
我不知道 pack() pragma 和 padding 是否仍然需要,但我一直在使用它们,因为每次有人说不再需要它们时,我都会遇到一个问题,当我把它们放回去时就会消失。
【讨论】:
值得注意的是,AMD 的(不可移植的)静态 c++ 内核语言可用于在 OpenCL 内核中编写类似 C++ 的结构和类。通常的限制仍然适用(这包括:没有继承或虚函数,结构/类中没有指针等......)。当然,它只适用于 AMD 运行时。最后一段+1,打包绝对是一件头疼的事。实际上,我昨晚能够将它们从渲染器中取出,但我仍然担心它会在某个时候在我的脸上爆炸。 哦,这很有趣。我不知道那件事。我只使用 OpenCL 1.1 和 #define CL_USE_DEPRECATED_OPENCL_1_1_APIS,这样我的代码就可以在 Nvidia 和 AMD 上运行。 我实际上并没有使用静态 c++ 内核语言,我只是提到了它:p(并且 CL_USE_DEPRECATED_OPENCL_1_1_APIS 绝对有用,否则几乎不可能在 1.2 运行时运行 1.1,因为丢失或错误函数签名 - 太烦人了)。我希望 NVIDIA 能够实现 OpenCL 1.2,但它有多难? 我认为 Nvidia 不再对 OpenCL 感兴趣。我很确定他们故意破坏了 Titan 卡上的 OpenCL 驱动程序。实际上,如果您不启用双浮点提升,我认为它们仍然有效(但我不确定)。这只是意味着,对于 OpenCL,Titan 比 GTX690 慢,但成本一样高。 你们是传奇!这些都是我想要的很棒的信息,还有一些很棒的信息疯狂的道具@raxman以上是关于初始化一个 OpenCL 对象的主要内容,如果未能解决你的问题,请参考以下文章