C++ 制作内核的不同方法

C++ 制作内核的不同方法,c++,opencl,C++,Opencl,在这个 有两种方法可以运行内核,注释中还提到了另一种方法: 1. cl::KernelFunctor simple_add(cl::Kernel(program,"simple_add"),queue,cl::NullRange,cl::NDRange(10),cl::NullRange); simple_add(buffer_A,buffer_B,buffer_C); cl::Kernel kernel_add=cl::Kernel(program,"simple_add"); kernel

在这个

有两种方法可以运行内核,注释中还提到了另一种方法:

1.

cl::KernelFunctor simple_add(cl::Kernel(program,"simple_add"),queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(buffer_A,buffer_B,buffer_C);
cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
kernel_add.setArg(0,buffer_A);
kernel_add.setArg(1,buffer_B);
kernel_add.setArg(2,buffer_C);
queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();
cl::make_kernel simple_add(cl::Kernel(program,"simple_add"));
cl::EnqueueArgs eargs(queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(eargs, buffer_A,buffer_B,buffer_C).wait();
然而,我发现,那个KernelFunctor

所以我尝试了另一种方法:

2.

cl::KernelFunctor simple_add(cl::Kernel(program,"simple_add"),queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(buffer_A,buffer_B,buffer_C);
cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
kernel_add.setArg(0,buffer_A);
kernel_add.setArg(1,buffer_B);
kernel_add.setArg(2,buffer_C);
queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();
cl::make_kernel simple_add(cl::Kernel(program,"simple_add"));
cl::EnqueueArgs eargs(queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(eargs, buffer_A,buffer_B,buffer_C).wait();
它成功地编译和运行

但是,评论中有第三个选项:

3.

cl::KernelFunctor simple_add(cl::Kernel(program,"simple_add"),queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(buffer_A,buffer_B,buffer_C);
cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
kernel_add.setArg(0,buffer_A);
kernel_add.setArg(1,buffer_B);
kernel_add.setArg(2,buffer_C);
queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();
cl::make_kernel simple_add(cl::Kernel(program,"simple_add"));
cl::EnqueueArgs eargs(queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(eargs, buffer_A,buffer_B,buffer_C).wait();
它不编译,我认为make_内核需要模板参数。 我是OpenCl新手,没有设法修复代码

我的问题是:

一,。我应该如何修改3。要编译的代码

二,。哪条路更好?为什么?2.对比3.?

您可以查看有关
cl::make_内核
API的详细说明(在第3.6.1节中),其中包括使用示例

在您的例子中,您可以编写如下内容来创建内核函子:

auto simple_add = cl::make_kernel<cl::Buffer&, cl::Buffer&, cl::Buffer&>(program, "simple_add");
自动简单添加=cl::生成内核(程序,“简单添加”);
你的第二个问题主要是基于观点,因此很难回答。有人可能会说,内核函子方法更简单,因为它允许您像调用函数一样“调用”内核,并以熟悉的方式传递参数。另一种方法(您问题中的选项2)更明确地说明了设置参数和将内核排队,但更接近于表示如何使用OpenCLCAPI编写相同的代码。您使用哪种方法完全取决于个人喜好。

请注意make_内核,像KernelFunctor这样的功能最终可能会比setArg有所改变。如果您的目标是在使用functor时延长代码库的使用时间,那么将setArg功能包装到您自己的functor类中可能会很有用。