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);
#endifreturn 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::stringauto 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 NDEBUGauto log=cl_utilits::getBuildInfo<CL_PROGRAM_BUILD_LOG>(program);showBuildLog(log,name);#endifreturn 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_ */

opencl: C++ 接口(cl.hpp)创建kernel相关推荐

  1. 创建一个抽象类动物类以及以下几个接口:进食的接口、睡觉的接口、思考的接口、说话的接口。分别定义猫类、人类、鸟类继承动物类并选择实现上述的接口,并创建实例验证。

    创建一个抽象类动物类以及以下几个接口:进食的接口.睡觉的接口.思考的接口.说话的接口.分别定义猫类.人类.鸟类继承动物类并选择实现上述的接口,并创建实例验证. 上代码 package ThirdDay ...

  2. C语言接口与实现:创建可重用软件的技术

    关注.星标公众号,直达精彩内容 来源:技术让梦想更伟大 作者:李肖遥 大家后,我是肖遥,静默的两天,终于可以在家里安静的坐下来,思考和躺平了. 最近发现一本好书,<C语言接口与实现(创建可重用软 ...

  3. 实现Runnable接口的形式创建线程

    MyRunnable.java package com.dym.juc;/* * 当线程类已经有父类了,就不能用Thread类的方式来创建线程 * 可以使用实现Runnable接口的方式去创建线程 * ...

  4. D3D11设备接口的动态创建方法

    在微软的例子中,提供了一种动态创建ID3D11Device接口指针的方法,发在这里,供大家参考.该方法的优势就是可以方便的判定系统中是否支持D3D11,并且针对可能的情况,通过MessageBox的方 ...

  5. 通达信lv2接口程序怎么创建BOLL通道数据?

    通达信lv2接口程序主要是面向的阅读对象以及接口文档主要包括哪些业务的接口,可以让读者有一个直观的认识.如:通达信lv2接口系统面向外部接入方的数据协议接口,主要包括:用户注册接口.同步用户.授权认证 ...

  6. node.js编写前端接口,服务器创建、数据库连接、路由挂载,增删改查、分页查询接口的编写

    1.文件准备 我们要准备三个文件来演示最基础的服务器创建.数据库连接路由挂载,增删改查.分页查询接口的编写.其中服务器创建单独一个文件为app.js,数据库连接为一个文件为pool.js,最后一个为接 ...

  7. 声明一个接口IPlayer,包含5个接口方法:播放、停止、暂停、上一首和下一首。设计一个Windows应用程序,在该程序中定义一个MP3播放器类和一个AVI播放器类,以实现该接口,最后创建相应类的实例

    从左往右,btnMP3,lblShow,btnAVI using System; using System.Collections.Generic; using System.ComponentMod ...

  8. ajax余额支付宝微信支付(多种情况调用同一个接口、jquery创建新对象设置属性)

    需求:需要用余额.支付宝.微信支付方式支付会员,余额支付显示余额其余支付不显示余额.余额点支付直接成功或失败,支付宝/微信支付弹出相应的二维码.支付接口为同一个,但要处理三种情况. 用到了ajax的c ...

  9. SolidWorks模型导入Matlab接口设置的创建

    参考:https://ww2.mathworks.cn/help/physmod/sm/cad-import.html 第一步: CAD->XML multibody description f ...

最新文章

  1. 微软Cortana全面升级神经网络语音,效果堪比真人发音
  2. mysql peferences_MySQL初次实践
  3. Crontab 使用(转)
  4. java8新特性简述
  5. JSP的9个内置对象-application
  6. Path Operation
  7. 2015第36周日每天进步1%
  8. 关于数组相关乱七八糟
  9. 翻译一定要知道的一些软件和工具
  10. 深入理解Java三种IO模式和Epoll模型
  11. FPGA实现cameralink解码
  12. mysql如何还原数据库
  13. 程序员的第一次相亲,还没开始,就已经结束了
  14. 4款报表工具功能对比,哪款最实用?
  15. 1957:【12NOIP普及组】质因数分解
  16. roce流量抓包 linux,roce性能测试方法
  17. AcWing 4246. 最短路径和(反向建图+链式前向星+堆优化)
  18. IDEA 2017.3.4 破解到2099年方法
  19. 性能测试中的服务器数据监控
  20. SHA-256算法实现

热门文章

  1. 【NOIP2013模拟10.23】君と彼女の恋
  2. 回复审稿意见应该注意什么?
  3. windows下移植别人配置好的python环境
  4. Helm及其它功能性组件
  5. 陌陌前端面试 - 凉面
  6. 《塔木德智慧全书》摘要(之一)
  7. 基于Java——SpringBoot的洗浴会所管理系统
  8. 大学生的期望落差在哪里?——转帖newsmth
  9. define和sbit的区别
  10. 基于Ubuntu16.04(64位)搭建WebRTC服务器(目前搭在局域网)