如何用C++正确获取OpenCL程序中的内核数量?
关于OpenCL获取内核数量的问题
为什么clGetProgramInfo(..., CL_PROGRAM_NUM_KERNELS, ...)返回0?
要通过CL_PROGRAM_NUM_KERNELS获取内核数量,必须满足核心前提:程序已经成功完成编译或链接操作,且编译状态为CL_BUILD_SUCCESS。你可能忽略了以下关键细节:
- 确认已调用
clBuildProgram(针对clCreateProgramWithSource创建的源码程序)或clLinkProgram,且返回值为CL_SUCCESS。 - 即使
clBuildProgram返回成功,也要针对每个关联设备检查编译状态:用clGetProgramBuildInfo获取CL_PROGRAM_BUILD_STATUS,避免多设备场景下部分设备编译失败的情况。 clFinish对程序编译无作用,因为clBuildProgram本身是同步阻塞执行的(除非使用OpenCL 2.0+的CL_BUILD_PROGRAM_ASYNC异步编译选项),等待命令队列无法解决编译未完成的问题。
clCreateKernelsInProgram是否是正确做法?
完全正确。这是OpenCL标准中推荐的批量获取程序内所有内核的方法,甚至比先调用clGetProgramInfo再逐个创建内核的流程更高效。
更规范的用法是分两步执行:先传入N=0获取内核数量,再分配对应大小的数组获取所有内核:
cl_uint numKernels; cl_int err = clCreateKernelsInProgram(OCL_program, 0, nullptr, &numKernels); if (err != CL_SUCCESS) { // 处理错误,比如打印错误码 } // 分配内核数组 cl_kernel* kernels = new cl_kernel[numKernels]; err = clCreateKernelsInProgram(OCL_program, numKernels, kernels, nullptr); if (err != CL_SUCCESS) { // 处理错误 } // 使用内核执行计算... // 清理资源 for (cl_uint i = 0; i < numKernels; ++i) { clReleaseKernel(kernels[i]); } delete[] kernels;
这种方式既避免了“设一个较大的任意N”的不确定性,也能准确获取所有内核。
内容的提问来源于stack exchange,提问作者Paul Aner
相关产品推荐
相关产品推荐

