GPGPU OpenCL编程步骤与简单实例

转自:  http://www.cnblogs.com/xudong-bupt/p/3582780.html 

1.OpenCL概念

  OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU、GPU或其他类型的处理器组成。OpenCL由一门用于编写kernels (在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定义并控制平台的API组成。

  OpenCL提供了两种层面的并行机制:任务并行与数据并行。

2.OpenCL与CUDA的区别

  不同点:OpenCL是通用的异构平台编程语言,为了兼顾不同设备,使用繁琐。

      CUDA是nvidia公司发明的专门在其GPGPU上的编程的框架,使用简单,好入门。

  相同点:都是基于任务并行与数据并行。

3.OpenCL的编程步骤

  (1)Discover and initialize the platforms

    调用两次clGetPlatformIDs函数,第一次获取可用的平台数量,第二次获取一个可用的平台。

  (2)Discover and initialize the devices

    调用两次clGetDeviceIDs函数,第一次获取可用的设备数量,第二次获取一个可用的设备。

  (3)Create  a context(调用clCreateContext函数)

    上下文context可能会管理多个设备device。

  (4)Create a command queue(调用clCreateCommandQueue函数)

    一个设备device对应一个command queue。

    上下文conetxt将命令发送到设备对应的command queue,设备就可以执行命令队列里的命令。

  (5)Create device buffers(调用clCreateBuffer函数)

    Buffer中保存的是数据对象,就是设备执行程序需要的数据保存在其中。

    Buffer由上下文conetxt创建,这样上下文管理的多个设备就会共享Buffer中的数据。

  (6)Write host data to device buffers(调用clEnqueueWriteBuffer函数)

  (7)Create and compile the program

    创建程序对象,程序对象就代表你的程序源文件或者二进制代码数据。

  (8)Create the kernel(调用clCreateKernel函数)

    根据你的程序对象,生成kernel对象,表示设备程序的入口。

  (9)Set the kernel arguments(调用clSetKernelArg函数)

  (10)Configure the work-item structure(设置worksize)

    配置work-item的组织形式(维数,group组成等)

  (11)Enqueue the kernel for execution(调用clEnqueueNDRangeKernel函数)

    将kernel对象,以及 work-item参数放入命令队列中进行执行。

  (12)Read  the output buffer back to the host(调用clEnqueueReadBuffer函数)

  (13)Release OpenCL resources(至此结束整个运行过程)

4.说明

  OpenCL中的核函数必须单列一个文件。

  OpenCL的编程一般步骤就是上面的13步,太长了,以至于要想做个向量加法都是那么困难。

  不过上面的步骤前3步一般是固定的,可以单独写在一个.h/.cpp文件中,其他的一般也不会有什么大的变化。

5.程序实例,向量运算

5.1通用前3个步骤,生成一个文件

  tool.h

 1 #ifndef TOOLH
 2 #define TOOLH
 3
 4 #include <CL/cl.h>
 5 #include <string.h>
 6 #include <stdio.h>
 7 #include <stdlib.h>
 8 #include <iostream>
 9 #include <string>
10 #include <fstream>
11 using namespace std;
12
13 /** convert the kernel file into a string */
14 int convertToString(const char *filename, std::string& s);
15
16 /**Getting platforms and choose an available one.*/
17 int getPlatform(cl_platform_id &platform);
18
19 /**Step 2:Query the platform and choose the first GPU device if has one.*/
20 cl_device_id *getCl_device_id(cl_platform_id &platform);
21
22 #endif

View Code

  tool.cpp

 1 #include <CL/cl.h>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include <iostream>
 6 #include <string>
 7 #include <fstream>
 8 #include "tool.h"
 9 using namespace std;
10
11 /** convert the kernel file into a string */
12 int convertToString(const char *filename, std::string& s)
13 {
14     size_t size;
15     char*  str;
16     std::fstream f(filename, (std::fstream::in | std::fstream::binary));
17
18     if(f.is_open())
19     {
20         size_t fileSize;
21         f.seekg(0, std::fstream::end);
22         size = fileSize = (size_t)f.tellg();
23         f.seekg(0, std::fstream::beg);
24         str = new char[size+1];
25         if(!str)
26         {
27             f.close();
28             return 0;
29         }
30
31         f.read(str, fileSize);
32         f.close();
33         str[size] = '\0';
34         s = str;
35         delete[] str;
36         return 0;
37     }
38     cout<<"Error: failed to open file\n:"<<filename<<endl;
39     return -1;
40 }
41
42 /**Getting platforms and choose an available one.*/
43 int getPlatform(cl_platform_id &platform)
44 {
45     platform = NULL;//the chosen platform
46
47     cl_uint numPlatforms;//the NO. of platforms
48     cl_int    status = clGetPlatformIDs(0, NULL, &numPlatforms);
49     if (status != CL_SUCCESS)
50     {
51         cout<<"Error: Getting platforms!"<<endl;
52         return -1;
53     }
54
55     /**For clarity, choose the first available platform. */
56     if(numPlatforms > 0)
57     {
58         cl_platform_id* platforms =
59             (cl_platform_id* )malloc(numPlatforms* sizeof(cl_platform_id));
60         status = clGetPlatformIDs(numPlatforms, platforms, NULL);
61         platform = platforms[0];
62         free(platforms);
63     }
64     else
65         return -1;
66 }
67
68 /**Step 2:Query the platform and choose the first GPU device if has one.*/
69 cl_device_id *getCl_device_id(cl_platform_id &platform)
70 {
71     cl_uint numDevices = 0;
72     cl_device_id *devices=NULL;
73     cl_int    status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
74     if (numDevices > 0) //GPU available.
75     {
76         devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id));
77         status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
78     }
79     return devices;
80 }

View Code

5.2核函数文件

  HelloWorld_Kernel.cl

1 __kernel void helloworld(__global double* in, __global double* out)
2 {
3     int num = get_global_id(0);
4     out[num] = in[num] / 2.4 *(in[num]/6) ;
5 }

View Code

5.3主函数文件

  HelloWorld.cpp

 1 //For clarity,error checking has been omitted.
 2 #include <CL/cl.h>
 3 #include "tool.h"
 4 #include <string.h>
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 #include <iostream>
 8 #include <string>
 9 #include <fstream>
10 using namespace std;
11
12 int main(int argc, char* argv[])
13 {
14     cl_int    status;
15     /**Step 1: Getting platforms and choose an available one(first).*/
16     cl_platform_id platform;
17     getPlatform(platform);
18
19     /**Step 2:Query the platform and choose the first GPU device if has one.*/
20     cl_device_id *devices=getCl_device_id(platform);
21
22     /**Step 3: Create context.*/
23     cl_context context = clCreateContext(NULL,1, devices,NULL,NULL,NULL);
24
25     /**Step 4: Creating command queue associate with the context.*/
26     cl_command_queue commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL);
27
28     /**Step 5: Create program object */
29     const char *filename = "HelloWorld_Kernel.cl";
30     string sourceStr;
31     status = convertToString(filename, sourceStr);
32     const char *source = sourceStr.c_str();
33     size_t sourceSize[] = {strlen(source)};
34     cl_program program = clCreateProgramWithSource(context, 1, &source, sourceSize, NULL);
35
36     /**Step 6: Build program. */
37     status=clBuildProgram(program, 1,devices,NULL,NULL,NULL);
38
39     /**Step 7: Initial input,output for the host and create memory objects for the kernel*/
40     const int NUM=512000;
41     double* input = new double[NUM];
42     for(int i=0;i<NUM;i++)
43         input[i]=i;
44     double* output = new double[NUM];
45
46     cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, (NUM) * sizeof(double),(void *) input, NULL);
47     cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY , NUM * sizeof(double), NULL, NULL);
48
49     /**Step 8: Create kernel object */
50     cl_kernel kernel = clCreateKernel(program,"helloworld", NULL);
51
52     /**Step 9: Sets Kernel arguments.*/
53     status = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&inputBuffer);
54     status = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&outputBuffer);
55
56     /**Step 10: Running the kernel.*/
57     size_t global_work_size[1] = {NUM};
58     cl_event enentPoint;
59     status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, global_work_size, NULL, 0, NULL, &enentPoint);
60     clWaitForEvents(1,&enentPoint); ///wait
61     clReleaseEvent(enentPoint);
62
63     /**Step 11: Read the cout put back to host memory.*/
64     status = clEnqueueReadBuffer(commandQueue, outputBuffer, CL_TRUE, 0, NUM * sizeof(double), output, 0, NULL, NULL);
65     cout<<output[NUM-1]<<endl;
66
67     /**Step 12: Clean the resources.*/
68     status = clReleaseKernel(kernel);//*Release kernel.
69     status = clReleaseProgram(program);    //Release the program object.
70     status = clReleaseMemObject(inputBuffer);//Release mem object.
71     status = clReleaseMemObject(outputBuffer);
72     status = clReleaseCommandQueue(commandQueue);//Release  Command queue.
73     status = clReleaseContext(context);//Release context.
74
75     if (output != NULL)
76     {
77         free(output);
78         output = NULL;
79     }
80
81     if (devices != NULL)
82     {
83         free(devices);
84         devices = NULL;
85     }
86     return 0;
87 }

View Code

编译、链接、执行:

  g++ -I /opt/AMDAPP/include/ -o A  *.cpp -lOpenCL ; ./A

  

分类: GPU/OpenCL
好文要顶 关注我 收藏该文

旭东的博客
关注 - 12
粉丝 - 269

+加关注

0
0

« 上一篇:去掉linux 系统vi中出现^M字符的方法
» 下一篇:GPGPU OpenCL 获取设备信息

posted on 2014-03-06 17:37 旭东的博客 阅读(10882) 评论(0) 编辑 收藏

OpenCL编程实例: 向量计算相关推荐

  1. AMD院士站台 异构计算与OpenCL编程师资培训首站清华开讲

    摘要:2013年10月14日,"2013年异构计算与OpenCL编程师资培训"在清华大学召开.本活动邀请到AMD.Khronos Group及清华大学的多位并行计算领域专家,与参会 ...

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

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

  3. Python并发编程实例教程

    有关Python中的并发编程实例,主要是对Threading模块的应用,文中自定义了一个Threading类库. 一.简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态 ...

  4. iOS网络编程-iCloud键值数据存储编程实例

    iCloud键值数据存储设计 iCloud键值数据存储编程实例,画面中有两个开关控件,左图是设备1点击"设置iCloud数据"按钮,将控件状态保存到iCloud服务器.右图是设备2 ...

  5. NIO Socket编程实例

    1.阻塞模式实例 NIOUtil类,用来通过SOcket获取BufferedReader和PrintWriter. package IO;import java.io.BufferedReader; ...

  6. linux c编程项目实例,Linux c编程实例_例子

    例一:字符与整型变量的实现 #include int main() { int c1,c2; char c3; c1='a'-'A'; c2='b'-'B'; c3='c'-; printf(&quo ...

  7. C#中Socket多线程编程实例

    C#是微软随着VS.net新推出的一门语言.它作为一门新兴的语言,有着C++的强健,又有着VB等的RAD特性.而且,微软推出C#主要的目的是为了对抗Sun公司的Java.大家都知道Java语言的强大功 ...

  8. 《突破C#编程实例五十讲》源文件下载(2)

    上接<<突破C#编程实例五十讲>源文件下载(1)> 有兴趣的朋友下载看看吧,一共有9个压缩包分3篇文章,下载要注意哦,不然解压要出错哦! 转载于:https://blog.51 ...

  9. java编程50实例_java编程实例大全及详解谜底(50例).doc

    java编程实例大全及详解谜底(50例).doc 还剩 33页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: 谓 ...

  10. Hadoop Streaming编程实例

    Hadoop Streaming是Hadoop提供的多语言编程工具,通过该工具,用户可采用任何语言编写MapReduce程序,本文将介绍几个Hadoop Streaming编程实例,大家可重点从以下几 ...

最新文章

  1. 二维码检测哪家强?五大开源库测评比较
  2. 创建文档库时指定文件夹(路径)
  3. 从 ThinkPHP 开发规范 看 PHP 的命名规范和开发建议
  4. 一般图最大匹配——带花树
  5. servlet3.0新特性_查看Servlet 3.0的新增功能
  6. Android设计模式之——迭代器模式
  7. LeetCode 1122. 数组的相对排序
  8. 保镖机器人作文_关于机器人作文400字
  9. python中用于绘制各种图形的区域称作_Python--matplotlib绘图可视化知识点整理(示例代码)...
  10. 设计模式笔记六:适配器模式
  11. 论坛在线时间挂机器_直播预告 | 智控未来——控制与机器人专题研讨会
  12. free -m 下的含义
  13. 2022年考研数据结构_2 线性表
  14. 关闭win7的程序兼容性助手
  15. 2005高中数学联赛第15题补充解答
  16. cuda9.0和cudnn7.3 win10百度网盘地址
  17. HTTP状态404-未找到
  18. Java奠基】Java经典案例讲解
  19. Win7下如何在windows资源管理器中打开FTP
  20. 【超图+CESIUM】【基础API使用示例】10、超图|CESIUM - 场景出图、下载当前截图

热门文章

  1. 自建服务器解网络锁,跟断刀学越狱】10分钟掌握iPhone1-4代刷机技巧
  2. 统计自然语言处理---信息论基础
  3. CATIA二次开发VBA:(一)宏的录制、修改及回放
  4. (转) [it-ebooks]电子书列表
  5. Java 学生成绩管理系统
  6. 3.Maven实战 --- maven使用入门
  7. 新能源汽车防撞预警系统FCW系统介绍
  8. 嵌入式Linux开发笔记(韦东山2)
  9. 计算机打字怎么学笔,学电脑·非常简单:五笔打字
  10. Linux的百度云有限速吗,mac(linux)下配置aria2解决百度云限速问题