Opencl编程的标准开发流程

  • 前言
  • OpenCL执行流程
  • 模板

前言

在前面的内容中介绍 了opencl编程环境的搭建方式环境搭建,本篇文章以为例讲述opencl编程的标准开发流程


编程环境:VS2015 + Intel® UHD Graphics 620

OpenCL执行流程

1.创建OpenCL程序第一步是要确定其执行的平台,clGetPlatFormIDs:

cl_int clGetPlatFormIDs(cl_uint num_entries, cl_platform _id * platforms,cl_uint *num_platforms)

2.在确定平台之后确定执行计算的设备,使用函数clGetDeviceIDs:

cl_int clGetDeviceIDs(cl_platform_id platform,cl_device_type  device_type, cl_uint  num_entries, cl_device_id *devices, cl_uint *num_devices);

3.确定设备后创建上下文,上下文为关联的设备、命令队列、程序对象、内核对象提供了一个容器,其所关联的设备必须来自同一平台。使用函数clCreateContext:

cl_context clCreateContext(const cl_context_properties * properties, cl_uint num_devices, const cl_device_id * devices, (void)(*pfn_notify) (const char * errinfo, const void *private_info ,size_t cb, void *user_data), void *user _data, cl_int * errcode_ret);

4.创建命令队列。在上下文中对对象的操作需要依赖命令队列,主机将命令提交到命令队列中,命令队列将命令发送给设备。命令队列和设备满足一对一的关系。函数clCreateCommandQueue:

cl_command_queue clCreateCommandQueue(cl_context context, cl_device_id device, cl_command_queue_properties properties,cl_int *errcode_ret)

5.创建内存对象,函数clCreateBuffer:

cl_mem clCreateBuffer(cl_context context,cl_mem_flags flags,size_t size,void *host_ptr,cl_int *errcode_ret)

6.创建程序对象,可以通过传入OpenCL C 源代码文本,也可以利用程序二进制来创建,本人更习惯使用第一种方法,clCreateProgramWithSource:

cl_program clCreateProgramWithSource (cl_context context,cl_uint count,const char **strings,const size_t *lengths,cl_int *errcode_ret)

7.编译程序对象。clBuildProgram 会为指定的所有设备构建程序对象,等价于在C程序上调用编译器与链接器。

cl_int clBuildProgram (  cl_program program,cl_uint num_devices,const cl_device_id *device_list,const char *options,void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),void *user_data)

8.创建内核对象。内核对象可以是一个通过命令队列发送到设备上执行的函数,创建函数clCreateKernel:

cl_mem clCreateBuffer(cl_context context,cl_mem_flags flags,size_t size,void *host_ptr,cl_int *errcode_ret)

9.设置内核参数。内核函数的参数需要通过clSetKernelArg来传递。

cl_int clSetKernelArg(cl_kernel kernel, cl_uint arg_index,size_t arg_size, const void *arg_value)

10.执行内核。在所有的准备工作已经做好之后,便可以让设备来执行内核函数,clEnqueueNDRangeKernel:

cl_int clEnqueueNDRangeKernel(cl_command_queue command_queue,cl_kernel kernel, cl_uint work_dim,const size_t *global_work_offset,const size_t *global_work_size,const size_t *local_work_size,cl_uint num_events_in_wait_list,const cl_event *event_wait_list, cl_event *event)

11.OpenCL设备执行完计算后,将数据拷贝回主机端并销毁分配的资源。

以上就是整个的开发流程。


模板

根据此过程,自己编写了一套通用模板

#include<stdio.h>
#include<stdlib.h>
#include<CL/cl.h>
#include<string.h>
#include <iostream>
#pragma warning( disable : 4996 )s
#define MAX_SOURCE_SIZE (0x100000)int main(void) {cl_int err = 0;//查询第一个平台cl_platform_id platform;err = clGetPlatformIDs(1, &platform, NULL);if (err < 0) {perror("Couldn't find any platforms");exit(1);}//查询平台上的设备 cl_device_id device;err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);if (err < 0) {perror("Couldn't find any DEVICE");exit(1);}//创建上下文cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);if (NULL == context){perror("Couldn't create context");exit(1);}//创建命令队列cl_command_queue CommandQueue = clCreateCommandQueue(context,device, 0, NULL);if (NULL == CommandQueue){perror("Couldn't create command queue");exit(1);}//创建输入输出内存对象// 创建输入内存对象int len;const char* input;//输入字符串cl_mem memInutBuffer = clCreateBuffer(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,  // 输入内存为只读,并可以从宿主机内存复制到设备内存(len + 1) * sizeof(char),         // 输入内存空间大小(void *)input,NULL);// 创建输出内存对象cl_mem memOutputBuffer = clCreateBuffer(context,CL_MEM_WRITE_ONLY,                 // 输出内存只能写(len + 1) * sizeof(char),    // 输出内存空间大小NULL,NULL);if ((NULL == memInutBuffer) || (NULL == memOutputBuffer)){perror("Error creating memory objects");exit(1);}//读取CL程序源码,将cl文件中的代码转为字符串FILE* fp = fopen("*.cl", "rb");if (fp == NULL) {perror("Couldn't find the program file");exit(1);}fseek(fp, 0, SEEK_END);size_t filesize = ftell(fp);fseek(fp, 0, SEEK_SET);rewind(fp);char *program_buffer=(char*)malloc(filesize+1);program_buffer[filesize] = '\0';fread(program_buffer, sizeof(char), filesize, fp);fclose(fp);//创建CL程序cl_program program= clCreateProgramWithSource(context, 1,&program_buffer,&filesize, &err);if (err < 0) {perror("Couldn't create the program");exit(1);}//编译CL程序const char options[] = "-cl-finite-math-only -cl-no-signed-zeros";err = clBuildProgram(program, 1, &device, options, NULL, NULL);if (err < 0) {/* Find size of log and print to std output */char *program_log;size_t log_size;clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,0, NULL, &log_size);program_log = (char*)malloc(log_size + 1);program_log[log_size] = '\0';clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,log_size + 1, program_log, NULL);printf("%s\n", program_log);free(program_log);exit(1);}//创建CL内核cl_kernel kernel = clCreateKernel(program, "kernelname", &err);if (err < 0) {perror("Couldn't create the kernel");exit(1);}//设置内核参数,根据实际的Kernel修改err = clSetKernelArg(kernel, 0,sizeof(memInutBuffer),(void *)memInutBuffer);err = clSetKernelArg(kernel, 1, sizeof(memInutBuffer), (void *)memOutputBuffer);//计算,参数值按照 实际 修改size_t global_work_size[] = {100};size_t local_work_size[] = { 1 };err = clEnqueueNDRangeKernel(CommandQueue, kernel, 1, NULL,global_work_size, local_work_size,0, NULL, NULL);//读取结果err = clEnqueueReadBuffer(CommandQueue, memOutputBuffer, CL_TRUE, 0, len * sizeof(char), memOutputBuffer,0, NULL, NULL);//输出数据//释放资源err = clReleaseKernel(kernel);err = clReleaseProgram(program);err = clReleaseMemObject(memInutBuffer);err = clReleaseMemObject(memOutputBuffer);err = clReleaseCommandQueue(CommandQueue);err = clReleaseContext(context);}

以上均为原创内容 如需转载,请注明出处 如有问题,还请指正。

Opencl编程的标准开发流程相关推荐

  1. Win32程序标准开发流程 .

    一.WinMain入口点 我们在学习标准C++的时候,都知道每个应用程序运行时都会先进入入口点函数main,而当从main函数跳出时程序就结束了.在Windows编程里面,也是一样的,只是我们的入口点 ...

  2. 启英泰伦产品方案开发流程

    概述¶ 语音识别作为最自然的交互方式,越来越多的被用户所接受,但是语音方案与传统的逻辑开发不同,需要多方配合才能打造好的产品.本文档主要介绍启英泰伦的语音识别方案的方案设计和项目开发,适用于新接触语音 ...

  3. vue实现饿了么外卖系统(完整开发流程)

    目标 1.掌握vue.js项目在实战中的用 2.学会使用vue.js 3.组件化.模块化的开发方式 涉及知识内容 1.vue-cli 2.axiox ajax通信.vue-resource(更新后不支 ...

  4. Java-GUI编程实战之管理系统 Day1【项目开发流程、软件三层架构、项目需求、项目结构分析】

    视频.课件.源码[链接:https://pan.baidu.com/s/13ffqGDzH-DZib6-MFViW3Q 提取码:zjxs] Java-GUI编程实战之管理系统 Day1[项目开发流程. ...

  5. arduino 机器视觉编程_万物皆可仿真的MATLAB/Simulink神奇在哪?解析如何将其应用于一整套机器人设计开发流程...

    MATLAB/Simulink:万物皆可仿真 MATLAB是由美国MathWorks公司出品的一款商业数学软件.它是一个多功能的科学计算平台,将算法开发.数据分析.矩阵计算等诸多强大功能集成在一个易于 ...

  6. plc程序 linux,plc编程开发流程

    plc编程开发流程 apc总线是一种集人工智能.计算机网络和智能自动化于一体的计算机系统,主要是按照不同的特性和功能为开发人员设计与rto相同的协议.apc总线以当前现代高科技的中心网络为核心,同时以 ...

  7. 大数据产品开发流程规范_华为内部资料流出!揭秘华为数据湖:3大特点、6个标准、入湖流程...

    点蓝色字关注"云技术" 导读:数据湖:实现企业数据的"逻辑汇聚". 作者:华为公司数据管理部来源:大数据DT(ID:hzdashuju)01 华为数据湖的3个特 ...

  8. 为什么云开发最终将成为编程新标准?

    云开发是一个已经存在了很多年的概念,但在过去未能真正成为主流. 然而,由于云和软件即服务的宏观趋势的结合,以及技术的进步,如容器技术 Docker 和 Kubernetes,云开发现在有机会最终成为基 ...

  9. OpenCL编程详细解析与实例

    OpenCL编程详细解析与实例 C语言与OpenCL的编程示例比较 参考链接: https://www.zhihu.com/people/wujianming_110117/posts 先以图像旋转的 ...

最新文章

  1. Phpcms V9手机门户设置教程:怎么用PC V9做手机网站
  2. 【CTF】实验吧 困在栅栏里的凯撒
  3. Matlab符号计算结果过长无法在屏幕中显示的问题
  4. 全球及中国垃圾发电行业运营管理及十四五投资价值评估报告2021-2027年
  5. 2021.02.03 Visual QA论文阅读
  6. 生产者消费者的实际使用
  7. Linux进程调度器-基础
  8. 洛谷P2050 美食节
  9. 在linux上使用labelImg制作LMDB数据集——备忘TX2上运行
  10. 微软MDT 安装与配置(二)
  11. 商淘软件已成为ThinkPHP商城系统之标杆产品
  12. java 缓存文件_java实现酷狗音乐临时缓存文件转换为MP3文件的方法
  13. DVWA下载、安装、使用(漏洞测试环境搭建)教程
  14. 互联网晚报 | 12月10日 星期五 | B站月均活跃UP主达270万人;宝马电动车总销量破百万;苹果市值逼近3万亿美元...
  15. 什么是 知足者常乐?
  16. ALLEGRO Scaled value has been rounded off.错误 CADENCE PCB
  17. pg数据库numeric对应oracle,Oracle类型number与PG类型numeric对比和转换策略
  18. 【文字】文字消散效果
  19. 关于时隙、RB、RE、PRB等概念的笔记
  20. 面试老大难的数据库缓存一致性问题

热门文章

  1. 集合 Transformer(Set Transformer)
  2. mybatisの配置文件
  3. c语言编译器tcc 源码,TCC研究(1): Tiny C Compiler最小的C语言编译器,自己编译自己...
  4. 小米手机MIUI系统稳定版蓝牙无法使用AAC格式编码
  5. linux文件名,Linux教程 概述Linux正规文件名
  6. MySQL必知必会01:一个完整的存储过程
  7. JAVA练习208-井字游戏
  8. Kafka的Streams
  9. Java网络编程(网络基础(IP端口号网络通信协议)、TCP编程、UDP编程和URL编程原理以及常用方法的实例)
  10. 笔记本电脑无法进入u盘启动界面怎么办?