opencl: C++ 接口(cl.hpp)创建kernel
来源:互联网 发布:北师珠网络教学 编辑:程序博客网 时间:2024/06/05 08:51
OpenCL不仅提供了标准C接口,同时提供C++的接口(cl.hpp),其实就是基于C接口的进一步封装。有了这个C++接口,对于C++项目来说,就大大提高了使用的便利性,本人涉及的这个项目对OpenCL的调用全部都是基于OpenCL的C++接口来完成的。
本文讲述如何用OpenCL 1.2的C++接口来从cl原文件创建kernel。
在cl.hpp中对cl_kernel
被封装成了cl::Kernel
对象,当然cl_program
也被封装成了cl::Program
对象。创建Kernel基本上主要涉及的就是这两个对象。
要创建cl::Kernel
,先要创建cl::Program
,下面的代码片段从一个std::string
字符串源码中创建cl::Program
/* 通过source提供的源码创建 cl::Program */cl::Program facecl_context::createProgram(std::string source,const char* name) { try { // 执行clCreateProgramWithSource创建对象 // m_context为cl::Context上下文件对象 cl::Program program(m_context, source); try{ program.build(); //代码编译 执行clBuildProgram#ifndef NDEBUG // 获取编译日志 auto log=cl_utilits::getBuildInfo<CL_PROGRAM_BUILD_LOG>(program); // 显示编译日志 showBuildLog(log,name);#endif return program; }#ifdef CL_VERSION_2_0 //当OpenCL版本为2.0以上时,编译错误抛出cl::BuildError异常// 当然要让Opencl出错时抛出异常而不是返回错误码,需要在的代码中增加__CL_ENABLE_EXCEPTIONS宏定义 catch(cl::BuildError &e){ auto log=e.getBuildLog(); showBuildLog(log,name); // 将cl::BuildError封装成自定义异常face_cl_build_exception抛出 throw face_cl_build_exception(e,log); }#else //当OpenCL版本为1.1,1.2时,编译错误抛出cl::Error异常 catch(cl::Error& e){ auto log=cl_utilits::getBuildInfo<CL_PROGRAM_BUILD_LOG>(program); showBuildLog(log,name); // 将cl::Error封装成自定义异常face_cl_build_exception抛出 throw face_cl_build_exception(e,log); }#endif } catch (cl::Error& e) { // 将cl::Error 封装成自定义异常face_cl_exception抛出 throw face_cl_exception(e); }}
有了cl::Program
对象,创建cl::Kernel
就更简单了
/* 通过file提供的源码创建 cl::Kernel,并将cl::Kernel命名为name加入m_kernels映射表中 */cl::Kernel facecl_context::createKernel(const char* name, const char *file) { auto scaling = load_string(file); // 从文本文件file读取所有内存到转成std::string auto program = createProgram(scaling,name); // 创建cl::Program对象 cl::Kernel kernel(program, name); this->m_kernels.emplace(name, kernel); // m_kernels类型为std::unordered_map<std::string,cl::Kernel> return kernel;}
facecl_context
类完整的源码如下
/* * platforms.h * * Created on: 2016年2月21日 * Author: guyadong */#ifndef FACEDETECT_FACECL_CONTEXT_H_#define FACEDETECT_FACECL_CONTEXT_H_#include "mycl.h"#include <iostream>#include <unordered_map>#include "cl_utilits.h"#include "assert_macros.h"using namespace std;typedef enum { image_scaling}facecl_kernel;#define KERNEL_NAME(n) #n#define KERNEL_FILE_NAME(n) #n".cl"class facecl_context { cl::Context m_context; cl::ImageFormat m_gray_format; std::unordered_map<std::string,cl::Kernel> m_kernels; cl::CommandQueue m_command_queue; /* 初始化上下文(context),优先获取GPU设备 */ cl::Context _initContext(){ try { return cl::Context(CL_DEVICE_TYPE_GPU); } catch (cl::Error &e) { if (CL_DEVICE_NOT_FOUND != e.err()) throw e; try { return cl::Context(CL_DEVICE_TYPE_CPU); } catch (cl::Error &e1) { if (CL_DEVICE_NOT_FOUND != e1.err()) throw e1; return cl::Context(CL_DEVICE_TYPE_DEFAULT); } }}public: void showSupportedImageFormats(cl_mem_flags flags, cl_mem_object_type type = CL_MEM_OBJECT_IMAGE2D, std::ostream& stream = cout) { return cl_utilits::showSupportedImageFormats(m_context, flags, type, cout); } const cl::Context& getContext()const{ return m_context; } const cl::ImageFormat& getGrayFormat()const{ return m_gray_format; } const cl::Kernel& getKernel(const char* name)const{ auto itor=m_kernels.find(std::string(name)); if(itor==m_kernels.end()) throw face_cl_exception(ERROR_STR("can't found kernel:").append(name)); return itor->second; } cl::CommandQueue &getCommandQueue(){ return m_command_queue; } cl::Program createProgram(std::string src,const char* name=nullptr) { try { cl::Program program(m_context, source); try{ program.build(); #ifndef NDEBUG auto log=cl_utilits::getBuildInfo<CL_PROGRAM_BUILD_LOG>(program); showBuildLog(log,name); #endif return program; } #ifdef CL_VERSION_2_0 //当OpenCL版本为2.0以上时,编译错误抛出cl::BuildError异常 catch(cl::BuildError &e){ auto log=e.getBuildLog(); showBuildLog(log,name); throw face_cl_build_exception(e,log); } #else //当OpenCL版本为1.1,1.2时,编译错误抛出cl::Error异常 catch(cl::Error& e){ auto log=cl_utilits::getBuildInfo<CL_PROGRAM_BUILD_LOG>(program); showBuildLog(log,name); throw face_cl_build_exception(e,log); } #endif } catch (cl::Error& e) { throw face_cl_exception(e); } } cl::Kernel createKernel(const char* name, const char* file){ auto scaling = load_string(file); auto program = createProgram(scaling,name); cl::Kernel kernel(program, name); this->m_kernels.emplace(name, kernel); return kernel; } void showBuildLog(build_log_type& build_log, const char* name = nullptr, std::ostream& stream=cout) { if (name) stream<<"--------------" << "source name:" << name<<"------------------" << endl; cl_utilits::showBuildLog(build_log, stream); } facecl_context(){ try{ m_context = _initContext(); auto devices = m_context.getInfo<CL_CONTEXT_DEVICES>(); m_command_queue=cl::CommandQueue(m_context); cl_utilits::showDevices(devices); m_gray_format = cl_utilits::getFittedImageFormatForGray(m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR); cout << "select format:" << cl_utilits::imageFormatToString(m_gray_format) << endl; auto k=createKernel(KERNEL_NAME(image_scaling),KERNEL_FILE_NAME(image_scaling)); }catch(exception&e){ cout<<e.what()<<endl; throw e; } } virtual ~facecl_context()=default;};extern facecl_context global_facecl_context;#endif /* FACEDETECT_FACECL_CONTEXT_H_ */
0 0
- opencl: C++ 接口(cl.hpp)创建kernel
- opencl:c++接口(cl.hpp)利用cl::LocalSpaceArg设置__local 参数
- opencl:C++ 利用cl::make_kernel简化kernel执行代码
- opencl:慎用-cl-opt-disable选项编译kernel(可能会导致一些无法解释的问题)
- opencl:cl::make_kernel的进化
- OpenCL读取内核cl文件
- opencl kernel 参数限制
- OpenCL调用kernel
- OpenCV-CL: OpenCL加速计算机视觉技术
- OpenCL Kernel 结构不支持二级指针?
- opencl::kernel中获取local memory size
- OpenCL Bug: Unrecognized Token during Kernel Compilation
- OpenCL中kernel的循环调用
- HPP
- hpp
- hpp
- .hpp
- HPP
- 函数模板和类模板
- 002_Http之介绍
- Eclipse中同时打开多个Console
- PHP中如何判断一个字符串是否是合法的日期模式
- C#套接字使用
- opencl: C++ 接口(cl.hpp)创建kernel
- Java基础知识(一)
- centos的nginx安装
- Contest Hunter - IHHH
- poj-3112 Pie
- 【漫画解读】HDFS存储原理
- 安卓布局:android:gravity 与 andorid:layout_gravity的区别
- python matplotlib绘图时图例显示问题
- 编写函数取得上一月的最后一天