GPGPU OpenCL编程步骤与简单实例

QT+opencl(二)向量相乘 1.opencv的基本流程 获取平台ID->获取设备ID->创建上下文->创建队列->读取源码->编译源码->创建核函数->设置变量->运行函数 2.cpp基本代码: m_cl_errNum = clGetPlatformIDs(1, &m_cl_platform, NULL); m_cl_errNum = clGetDeviceIDs( m_cl_platform, 阅读详情

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
复制代码

  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 }
复制代码

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 }

 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 }
复制代码

 

编译、链接、执行:

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

   $> ./A

  

GPU编程--OpenCL基本概念 本篇结构: 背景 OpenCL是什么 框架组成 基本概念 编写OpenCL程序的基本步骤 参考博文 一、背景 在过去利用GPU对图像渲染进行加速的技术非常成熟,因为GPU是典型的单指令多数据(SIMD)的体系结构,擅长大规模的并行计算;而CPU是多指令单数据流(MISD)的体系结构,更擅长逻辑控制。 在当今数据量计算越发庞大的情况下,为了提升计算效率,人们希望将GPU大规模的并行计... 阅读详情

相关推荐

Vortex GPGPU:基于RISC-V指令集的GPU

论文:《Vortex: Extending the RISC-V ISA for GPGPU and 3D-Graphics Research》

u014756627的博客 3694

GPGPU OpenCL编程步骤与简单实例

http://www.cnblogs.com/xudong-bupt/p/3582780.html  1.OpenCL概念   OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU、GPU或其他类型的处理器组成。OpenCL由一门用于编写kernels (在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定义并控制平台的API组成。   OpenCL提供了两种层面的并...

weixin_33869377的博客 390

游戏显卡与图形显卡的区别及编程实践

现代显卡通常支持基于CUDA(Compute Unified Device Architecture)或OpenCL(Open Computing Language)的编程模型,这些模型允许开发人员使用C、C++或其他支持的语言编写显卡上的并行计算代码。此外,游戏显卡在设计上还注重提供更好的散热和供电能力,以满足游戏应用对于长时间高强度运行的需求。需要注意的是,上述代码只是一个简单的示例,实际的GPGPU编程可能更加复杂,涉及到数据分块、线程同步等问题。然后,在显卡上分配了相应的内存空间,并使用。

TechSavant的博客 359

OpenCL 初始化代码[2]

在使用GPU之前,要对GPU进行一些配置,简单记录一下流程。 class gpu { public: //并行计算内部句柄 cl_device_id* devices;//设备 cl_context _context;//上下文 cl_command_queue _commandQueue;//命令队列 int dev_id=0; int argNum = 0; gpu(); ...

ARTELE的博客 3138

GPGPU与GPU编程的区别及示例代码

GPGPU(General-purpose computing on graphics processing units)是一种利用图形处理单元(GPU)进行通用计算的技术。虽然GPGPU和GPU都涉及使用GPU进行计算,但它们之间存在一些重要的区别。GPGPU(通用图形处理单元计算)是一种利用图形处理单元(GPU)进行通用计算的技术。尽管GPGPU和GPU都涉及使用GPU进行计算,但它们之间存在一些重要的区别。GPGPU和GPU编程都利用了GPU的并行计算能力,但它们的目标和编程模型有所不同。

ByteEchoX的博客 661

PTGui_Pro9.1汉化版

PTGui PRO的多功能全景制作工具的一个用户界面。Panorama Tools是目前功能最为强大的全景制作工具,但是它需要用户编写脚本命令才能工作。PTGui通过为全景制作工具(Panorama Tools)提供可视化界面来实现对图像的拼接,从而创造出高质量的全景图象。

GPGPU OpenCL编程步骤与简单实例zz

http://www.cnblogs.com/xudong-bupt/p/3582780.html 1.OpenCL概念   OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU、GPU或其他类型的处理器组成。OpenCL由一门用于编写kernels (在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定义并控制平台的API组成。   OpenCL提供...

anjuenz87013的博客 209

全景软件PTGui.Pro.8.3.3带注册机

用于制作全景图片的拼接,制作球形全景而且带注册码

OpenCL编程实例: 向量计算

GPGPU OpenCL编程步骤与简单实例 转自:  http://www.cnblogs.com/xudong-bupt/p/3582780.html  1.OpenCL概念   OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU、GPU或其他类型的处理器组成。OpenCL由一门用于编写kernels (在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定

Cafe 1200

ArcGIS拓扑面错误批量修改

在工作学习中经常会遇到拓扑修改的问题,当数据量巨大的时候会产生拓扑问题 当拓扑错误数量巨大时,人工逐一修改是不现实的,基于此利用gis自带工具箱实现拓扑面类错误的批量修改。 一、.常见拓扑错误的类型: 1面重叠 2空隙(绿色部分) 二、拓扑检查 1新建数据库-----新建数据集—导入数据. 2新建拓扑 3修改拓扑容差及名称 添加拓扑修改规则 完成拓扑检查-查看拓扑错误 三、拓扑批量...

qq_43173805的博客 3万+

AI大模型驱动Web UI自动化测试:Playwright与RobotFramework智能整合实践

Web自动化测试是软件质量保障的关键环节,其核心原理是通过脚本模拟用户操作,对Web应用界面进行功能验证。传统方法依赖固定的元素定位和脚本逻辑,在应对频繁的UI变更时面临维护成本高、脚本脆弱的挑战。随着AI大模型技术的发展,其强大的自然语言理解和代码生成能力为自动化测试带来了新的技术价值。通过将大模型的意图理解与代码生成能力,与Playwright强大的浏览器自动化执行引擎以及RobotFramework灵活的关键字驱动框架相结合,可以构建出能够理解自然语言指令、动态生成稳定操作脚本的智能测试系统。这种融合

weixin_28718769的博客 412

从零开始学习OpenCL开发(一)架构

多谢大家关注 转载本文请注明:http://blog.youkuaiyun.com/leonwei/article/details/8880012   本文将作为我《从零开始做OpenCL开发》系列文章的第一篇。   1 异构计算、GPGPU与OpenCL   OpenCL是当前一个通用的由很多公司和组织共同发起的多CPU\GPU\其他芯片 异构计算(heterogeneous)的标准,它是跨平台的

leon 12万+

手把手教你用Docker快速部署开源MES系统(附避坑指南)

本文提供了一份详细的实战指南,手把手教你使用Docker容器化技术快速部署开源MES系统。内容涵盖从环境准备、项目选型、数据库配置到应用服务器优化、前端部署及生产环境监控的全流程,并附有避坑指南,旨在帮助中小制造企业IT人员和开发者低成本、高效率地构建智能制造解决方案。

f0g1h2的博客 1060

OpenCL学习入门

1.OpenCL概念 OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU、GPU或其他类型的处理器组成。OpenCL由一门用于编写kernels (在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定义并控制平台的API组成。 OpenCL提供了两种层面的并行机制:任务并行与数据并行。 名词的概念: Platform (平台):主机加上OpenCL框架管理下的若干设备构成了这个平台,通过这个平台,应用程序可以与设备共享资源并在设备上执行kernel。实际使用中基本上一个厂商对应一个

silencez_w的博客 8785

强化学习代码实现PPO

梯度更新:通过截断(clipping)限制策略更新幅度,避免策略变化过大影响稳定性。首先是数据预处理,将相关数据(状态、采取的动作、状态奖励、下一个状态)放到gpu上。根据当前状态 state,利用策略网络生成每个动作的概率分布 probs。2. 修改了策略模型的输出,从每个动作的概率分布变成了动作的均值和方差。1. 修改了动作空间,离散空间变成了连续空间,使用正太分布来采样。3. 修改了动作的ratio的计算,从离散分布变成了正太分布计算。Update函数:通过经验缓冲数据来优化策略模型和价值模型。

wlxsp的博客 635

golang 线上事故

golang 线上事故 最近公司要做大促的一些活动。并且单量,qps持续上涨。之前使用的是django python 语言做的一个服务端。目前已经部署的国家里面最多的国家会有300+个实例。大促期间还可能会增加一个实例数。这么多的实例部署,回滚的时间都会特变长,除了问题也不好定位。并且如此多的一个机器,连接数* 实例数也会导致DB等其他服务扛不住这么大的并发。所以决定上go服务解决性能问题。 ...

lcf枫的博客 1537

GPGPU概述

GPGPU是一种利用GPU进行通用计算的技术,适用于需要大规模并行处理的任务。通过CUDA、OpenCL等编程模型,开发者可以方便地编写并行计算代码,利用GPU的强大计算能力。GPGPU已经在科学计算、机器学习、高性能计算等多个领域得到广泛应用。

MHD0815的博客 1777

CS5511芯片实战:如何用DP转LVDS驱动高刷显示器(附配置代码)

本文详细解析了CS5511芯片在DP转LVDS高刷显示器驱动方案中的应用,包括核心架构、寄存器配置、时序优化及典型问题排查。通过实战案例和配置代码,帮助开发者快速实现120Hz高刷新率显示,特别适合医疗影像和工业HMI等严苛场景。

m3n5b7v8c9x的博客 1075

GPGPU面临的工程困境闲聊

GPGPU面临的工程困境闲聊,Metal,CUDA,OpenCL各个厂商的利益纠葛,以及对开发带来的影响。

Z.Jiang 1811

【产品】 产品设计:如何解决铝合金氧化着色后表面硬度低的问题(硬质氧化)

1、氧化处理技术 1)化学氧化 化学氧化处理所获得的膜层较薄,一般厚度为0.5μm ~4μm,质软不耐磨,抗蚀能力低于阳极氧化膜。 一般不宜单独便用,由于化学氧化膜吸附能力好,主要作用于油漆的底层,化学氧化按其溶液性可分为碱性和酸性两种。按其膜层性质可分为氧化膜,磷酸盐膜、铬酸盐膜及磷酸一铬酸盐膜等(这类型的氧化膜是可导电)。 2)电化学氧化(阳极氧化) 电化学氧化(俗称阳极氧化)是铝及...

产品线负责人 9732

【WLAN】【基础知识】WIFI那些事儿之AP扫描周边AP和STA

如本文对你有些许帮助,欢迎大佬打赏: 支付宝及微信打赏方式

一介草民,只为生活。 2883
上一篇: Around the World in 60 Days: Getting Deep Speech to Work in Mandarin
下一篇: 详细程序注解学OpenCL一 环境配置和入门程序
凌风探梅
博客等级 码龄19年 2575粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值