两个clCreateKernel函数
clCreateKernel函数会生成编译生成最终的二进制汇编。
clCreateKernel 和 clCreateKernelsInProgram 都是 OpenCL 中用于创建内核对象的函数,但它们在功能和使用场景上存在明显区别,下面为你详细介绍:
功能用途¶
clCreateKernel:此函数用于从clProgram对象里创建单个内核对象。当你确切知道要使用的内核函数名时,就可以使用这个函数。clCreateKernelsInProgram:该函数用于从clProgram对象中创建所有内核对象。当你想一次性获取程序里的所有内核,而不是逐个指定内核函数名时,就适合使用这个函数。
函数原型¶
C++
// clCreateKernel
cl_kernel clCreateKernel(cl_program program, const char *kernel_name, cl_int *errcode_ret);
// clCreateKernelsInProgram
cl_int clCreateKernelsInProgram(cl_program program, cl_uint num_kernels, cl_kernel *kernels, cl_uint *num_kernels_ret);
参数解释¶
clCreateKernelprogram:代表包含内核函数的clProgram对象。kernel_name:是一个字符串,代表要创建的内核函数名。errcode_ret:用于返回错误码。clCreateKernelsInProgramprogram:代表包含内核函数的clProgram对象。num_kernels:表示调用者预期创建的内核数量。如果传入0,kernels可以设为NULL,函数会返回程序里的内核总数。kernels:是一个指向cl_kernel数组的指针,用于存储创建的内核对象。num_kernels_ret:用于返回实际创建的内核数量。
示例代码¶
C++
#include <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>
// OpenCL kernel source code
const char *kernelSource = "__kernel void add(__global const int *a, __global const int *b, __global int *c) { \n"
" int gid = get_global_id(0); \n"
" c[gid] = a[gid] + b[gid]; \n"
"} \n"
"__kernel void subtract(__global const int *a, __global const int *b, __global int *c) { \n"
" int gid = get_global_id(0); \n"
" c[gid] = a[gid] - b[gid]; \n"
"} \n";
int main() {
// Create an OpenCL context
cl_platform_id platform;
cl_device_id device;
cl_context context;
clGetPlatformIDs(1, &platform, NULL);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
// Create an OpenCL program
cl_program program = clCreateProgramWithSource(context, 1, (const char **)&kernelSource, NULL, NULL);
clBuildProgram(program, 1, &device, NULL, NULL, NULL);
// 使用 clCreateKernel 创建单个内核
cl_kernel add_kernel = clCreateKernel(program, "add", NULL);
// 使用 clCreateKernelsInProgram 创建所有内核
cl_uint num_kernels;
clCreateKernelsInProgram(program, 0, NULL, &num_kernels);
cl_kernel *all_kernels = (cl_kernel *)malloc(num_kernels * sizeof(cl_kernel));
clCreateKernelsInProgram(program, num_kernels, all_kernels, NULL);
// Clean up
clReleaseKernel(add_kernel);
for (cl_uint i = 0; i < num_kernels; i++) {
clReleaseKernel(all_kernels[i]);
}
free(all_kernels);
clReleaseProgram(program);
clReleaseContext(context);
return 0;
}
总结¶
- 若你清楚要使用的内核函数名,且只需要创建一个内核对象,就使用
clCreateKernel。 - 若你想一次性获取程序里的所有内核对象,就使用
clCreateKernelsInProgram。