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