OpenCL:维护单独版本的内核

OpenCL:维护单独版本的内核,opencl,Opencl,报告说: 如果您需要单独版本的内核,有一种方法可以保留源代码 代码库相同,是使用预处理器创建特定于CPU的或 特定于GPU的内核优化版本。你可以跑 clBuildProgram在同一个程序对象上运行两次,一次用于CPU 指示CPU版本的某些标志(编译器输入),第二次 用于GPU和相应的编译器标志。然后,当您创建两个 内核使用clCreateKernel时,运行时有两个不同的版本 对于每个内核 假设我使用clBuildProgram两次,并带有CPU和GPU的标志。这将编译两个版本的程序,一个为C

报告说:

如果您需要单独版本的内核,有一种方法可以保留源代码 代码库相同,是使用预处理器创建特定于CPU的或 特定于GPU的内核优化版本。你可以跑 clBuildProgram在同一个程序对象上运行两次,一次用于CPU 指示CPU版本的某些标志(编译器输入),第二次 用于GPU和相应的编译器标志。然后,当您创建两个 内核使用clCreateKernel时,运行时有两个不同的版本 对于每个内核


假设我使用
clBuildProgram
两次,并带有CPU和GPU的标志。这将编译两个版本的程序,一个为CPU优化,另一个为GPU优化。但是,既然
clCreateKernel()
中没有特定于CPU/GPU的选项,我现在如何创建两个内核?

为CPU和GPU设备构建内核并获取不同内核的调用序列可能如下所示:

cl_program program = clCreateProgramWithSource(...)

clBuildProgram(program, numCpuDevices, cpuDeviceList, cpuOptions, NULL, NULL);
cl_kernel cpuKernel = clCreateKernel(program, ...);

clBuildProgram(program, numGpuDevices, gpuDeviceList, gpuOptions, NULL, NULL);
cl_kernel gpuKernel = clCreateKernel(program, ...);

(注意:我现在无法测试这个问题。如果出现问题,我将删除此答案)

您将只创建具有相同名称的内核。要区分不同的设备,可以在内核中使用
#ifdef
查询,即:

kernel void foo(global float *bar)
{
#ifdef HAVE_CPU
    bar[0] = 23.0;
#elif HAVE_GPU
    bar[0] = 42.0;
#endif
}
您可以通过以下方式获得此标志:

program.build({device}, "-DHAVE_CPU")

-DHAVE\u GPU
。备注:
-D..
不是打字错误。

clCreateKernel
创建程序的入口点,并且该程序已针对特定设备(CPU或GPU)编译。因此,如果程序已经以一种或另一种方式编译,那么在创建内核级别就没有什么可以做的了

通过传递不同的编译程序对象,
clCreateKernel
将为不同的设备创建不同的内核对象

控制GPU/CPU模式的关键在于
clBuildProgram
步骤,其中必须指定设备。 此外,还可以使用外部定义进一步细化编译,以禁用/启用专门为CPU/GPU设计的代码片段