如何判断获取的cl_program对象所属类型?
如何判断不透明
cl_program对象包含的内容类型? OpenCL标准提供了查询程序属性的规范方式来识别cl_program的内容,核心是通过clGetProgramInfo()函数,结合不同的查询参数提取关键信息。
核心查询参数与解析逻辑
1. 识别基础内容类型
通过以下cl_program_info枚举值,可直接判断程序是否包含源码、IL或二进制:
CL_PROGRAM_SOURCE:若查询返回非空字符串(长度大于1,排除空串情况),说明程序包含文本源码(由clCreateProgramWithSource()创建)。部分实现会在编译后保留源码,需注意兼容性。CL_PROGRAM_IL:若返回非空数据,说明程序包含SPIR等中间表示(由clCreateProgramWithIL()创建)。CL_PROGRAM_BINARIES:结合CL_PROGRAM_BINARY_SIZES查询,若返回非空二进制数组,说明程序包含针对设备的二进制对象。
2. 细分二进制对象类型
针对CL_PROGRAM_BINARIES中的每个设备二进制,用CL_PROGRAM_BINARY_TYPES查询具体类型,对应cl_program_binary_type枚举值:
CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT:未链接的已编译二进制CL_PROGRAM_BINARY_TYPE_EXECUTABLE:可执行二进制CL_PROGRAM_BINARY_TYPE_LIBRARY:库二进制CL_PROGRAM_BINARY_TYPE_IL:二进制形式存储的SPIR ILCL_PROGRAM_BINARY_TYPE_BUILT_IN_KERNEL:内置内核存根
3. 识别内置内核
查询CL_PROGRAM_BUILT_IN_KERNELS,若返回非空内核名称列表,说明程序由clCreateProgramWithBuiltinKernels()创建,包含内置内核。
组合内容的判断流程
由于cl_program可同时包含多种内容(如源码+已编译二进制),需依次查询多个属性:
- 先检查
CL_PROGRAM_SOURCE判断是否含源码; - 检查
CL_PROGRAM_IL判断是否含中间表示; - 通过
CL_PROGRAM_BINARIES和CL_PROGRAM_BINARY_TYPES逐个识别二进制类型; - 检查
CL_PROGRAM_BUILT_IN_KERNELS判断是否含内置内核。
示例代码片段
// 假设已获取合法的cl_program和cl_device_id对象 cl_int err; size_t source_size; char* source = NULL; // 查询是否包含源码 err = clGetProgramInfo(program, CL_PROGRAM_SOURCE, 0, NULL, &source_size); if (err == CL_SUCCESS && source_size > 1) { source = malloc(source_size); clGetProgramInfo(program, CL_PROGRAM_SOURCE, source_size, source, NULL); printf("程序包含源码\n"); free(source); } // 查询各设备的二进制类型 size_t num_devices; clGetProgramInfo(program, CL_PROGRAM_NUM_DEVICES, sizeof(num_devices), &num_devices, NULL); cl_program_binary_type* binary_types = malloc(num_devices * sizeof(cl_program_binary_type)); clGetProgramInfo(program, CL_PROGRAM_BINARY_TYPES, num_devices * sizeof(cl_program_binary_type), binary_types, NULL); for (size_t i = 0; i < num_devices; i++) { switch (binary_types[i]) { case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT: printf("设备%d包含已编译二进制\n", i); break; case CL_PROGRAM_BINARY_TYPE_EXECUTABLE: printf("设备%d包含可执行二进制\n", i); break; case CL_PROGRAM_BINARY_TYPE_LIBRARY: printf("设备%d包含库二进制\n", i); break; case CL_PROGRAM_BINARY_TYPE_IL: printf("设备%d包含二进制形式的IL\n", i); break; case CL_PROGRAM_BINARY_TYPE_BUILT_IN_KERNEL: printf("设备%d包含内置内核\n", i); break; default: printf("设备%d包含未知类型二进制\n", i); } } free(binary_types);
注意事项
- 不同OpenCL实现对属性的保留行为有差异:部分实现会在编译后丢弃源码,部分则会保留;
- 组合内容场景下,需同时查询多个属性才能完整识别所有内容类型;
- 查询
CL_PROGRAM_BINARIES前,需先用CL_PROGRAM_BINARY_SIZES获取每个二进制的大小,避免内存分配不足。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

