OpenCL中的工作组、工作项--转

2024-05-15 00:18
文章标签 工作 工作组 opencl

本文主要是介绍OpenCL中的工作组、工作项--转,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://blog.csdn.net/zhouxuanyuye/article/details/80445076

 

理解OpenCL中的工作组、工作项的索引

 ==============================================================

目录结构

1、工作组和工作项

2、一维数据的工作组和工作项

3、深度学习中二维图像的池化(Pooling)

4、参考

 ==============================================================

 

关键词:OpenCL   工作组   工作项    深度学习池化Pooling

本文第1节介绍了OpenCL中的工作组和工作项,摘抄自书本《OpenCL编程指南》,因其在并行计算中比较重要,特别作为重点从理论到实践理解。

第2节以核函数为例,该函数的输出是输入数组数据的两倍,同时输出各个工作项对应的全局ID和局部ID。

第3节以深度学习中的池化为例,介绍了2维图像的工作组和工作项ID,以及简单提及3维内容的工作组和工作项ID。

1、工作组和工作项

OpenCL运行时系统会创建一个整数索引空间,索引空间是N维的值网格,N为1、2或3,又称NDRange。

执行内核的各个实例称为工作项(work-item)。工作项在整个索引空间中由一个全局ID标识,就像学校给学生用学号标识。

工作项组织为工作组(work-group)。全局索引为工作组指定了工作组ID(就像学校给班级编号),工作组内又为工作项指定了局部ID(就像班级里又为学生编了号)。

所以,如何通过坐标方式找到工作项。

(1)可以通过工作项的全局索引

(2)先通过工作组索引号,再通过局部索引号

使用(gx,gy)表示工作项的全局ID,全局索引工具大小为(Gx,Gy)。

所以工作项的坐标范围为[(0,Gx-1), (0,Gy-1)]。

用w表示工作组ID,W工作组各个维度的维度大小。

把一个工作组内的索引空间称为局部索引空间。各个维度的大小用字母L表示,局部ID使用小写字母l表示。

因此,大小为(Gx,Gy)的NDRange索引空间划分为Wx*Wy空间上的工作组,工作组的索引号为(wx,wy)。各个工作组大小为Lx*Ly。

Lx = Gx / Wx

Ly = Gy / Wy

通过工作项的全局ID(gx,gy)来定义工作项,或者通过局部ID(lx,ly)和工作组ID(wx,wy)定义:

gx = wx*Lx + lx

gy = wy*Ly + ly

全局索引空间各个维度起始点从0开始,不过在全局索引空间的起始点定义了一个偏移量,用小写字母o表示

gx = wx*Lx + lx + ox

gy = wy*Ly + ly + oy

图1. 2维NDRange中全局ID、局部ID和工作组索引之间关系的一个例子。索引空间的其他参数在图中定义。阴影方块的全局ID为(gx, gy) = (6, 5),工作组及局部ID分别为(wx,wy) = (1, 1)和(lx, ly) = (2, 1)。

2、一维数据的工作组和工作项

本例中的核函数如下,功能为将输入数据乘以2后输出。输入数据为8*8的数组,在主函数中将设置64个核一起处理,最后打印出输入数据、全局ID号、局部ID号和输出结果,通过以下语句实现:

           

work_dim:工作项的维度,此处为1维。

global_item_size:给每一个核函数编号的全局变量,此处为8*8=64,ID号从0~63。

local_item_size:4,给所有的核函数分组,每四个一组,每组内的ID从0到3。

clEnqueueNDRangeKernel函数的解析可以参考以下网址:

https://blog.csdn.net/gflytu/article/details/7686130

 

            cl_uint work_dim = 1;
            size_t global_item_size;
            size_t local_item_size;
 
            global_item_size = width*height; /*Global number of work items */
            local_item_size = 4; /* Number ofwork items per work group */
                                /*--> global_item_size / local_item_size which indirectly sets the
                                 numberof workgroups*/
 
            /* Execute Data Parallel Kernel */
            ret =clEnqueueNDRangeKernel(command_queue, kernel, work_dim, NULL,
                                        &global_item_size,&local_item_size,
                                        0, NULL, NULL);


图2. 工作组共有64/4=16个

以上设置共有16个工作组,每个工作组的局部ID有0,1,2,3四个,注意观察控制台打印输出。

核函数:add_vec.cl

__kernel void add_vec(__global int * data_in,
                      __global int *mem_global_id,
                      __global int *mem_local_id,
                      __global int *data_out,
                      int length)
{
            int i,j;
            int global_id;
            int local_id;
 
            global_id = get_global_id(0);
            local_id  = get_local_id(0);
 
            mem_global_id[global_id] =global_id;
            mem_local_id [global_id] = local_id;
 
 
            for(i=0; i<length; i++)
            {
                       data_out[i] =data_in[i]*2;
            }
 
}
主函数:main.cpp

https://github.com/yywyz/OpenCL-Programming-Examples/blob/master/work_id_1dim/main.cpp

 

图3. 一维数组的输入数据、全局ID数组、局部ID数组和输出数据数组

3、深度学习中二维图像的池化(Pooling)

以下例子为二维数据的例子,以深度学习中的池化(Pooling)为例,在深度学习中,池化可以降低数据维度,聚合数据特征,减少计算量等。池化的方法有多种,如平均值池化,最大值池化。可参考https://blog.csdn.net/silence1214/article/details/11809947

本例使用2*2最大值池化,输入数据8*8,输出数据4*4。

使用2维工作组,打印输出各个工作组全局ID和局部ID,如全局ID为(x,y),则输出表示为xy,在核函数中记为10*x+y。

图4. 2*2 max_pooling例子

图5. 二维图像工作组的全局ID和局部ID

以上通过在主函数中的以下语句实现,将工作维度设置为2,设置各个维度的全局大小分别为8和8,通过设置局部块大小来确定工作组,设置为2,所以工作组一共有(8/2)*(8/2)=16个:

            cl_uint work_dim = 2;
            size_t global_item_size[2] = {8, 8};
            size_t local_item_size[2] = {2, 2};
 
            /* Execute Data Parallel Kernel */
            ret =clEnqueueNDRangeKernel(command_queue, kernel, work_dim, NULL,
                                        global_item_size,local_item_size,
                                        0,NULL, NULL);
如果需要设置三维工作组ID,则以上同理,另外增加两个数组维度分别控制各个组大小。

以下为本例的核函数核主函数,以及实验结果。

核函数:pooling.cl

 

/**********************************************
function:max_pooling, 2*2
2018/05/24
**********************************************/
 
__kernelvoid pooling(__global int * data_in,
                     __global int *mem_global_id,
                     __global int *mem_local_id,
                     __global int *data_out,
                     int width)
{
            int i,j;
            int global_id_x, global_id_y;
            int local_id_x, local_id_y;
 
            global_id_x = get_global_id(0);
            global_id_y = get_global_id(1);
            local_id_x  = get_local_id(0);
            local_id_y  = get_local_id(1);
 
            //(x,y)
            mem_global_id[global_id_y * width +global_id_x] = global_id_x * 10 + global_id_y;
            mem_local_id [global_id_y * width +global_id_x] = local_id_x * 10  +local_id_y;
 
            if((global_id_x % 2 == 0 )&&(global_id_y % 2 == 0))
            {
                       int index1 = global_id_y* width + global_id_x;
                       int index2 = global_id_y* width + global_id_x + width;
                       int tmp1 =max(data_in[index1],data_in[index1 + 1]);
                       int tmp2 =max(data_in[index2],data_in[index2 + 1]);
                       int tmp  = max(tmp1,tmp2);
                       data_out[global_id_y / 2* width / 2 + global_id_x/2] = tmp ;
            }
}
主函数main.cpp

https://github.com/yywyz/OpenCL-Programming-Examples/blob/master/work_id_2dim_pooling/main.cpp

 

图6. 二维数组的输入数据、全局ID数组、局部ID数组和输出池化结果

 

4、参考

https://blog.csdn.net/zhouxuanyuye/article/details/80445076

这篇关于OpenCL中的工作组、工作项--转的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990268

相关文章

工作常用指令与快捷键

Git提交代码 git fetch  git add .  git commit -m “desc”  git pull  git push Git查看当前分支 git symbolic-ref --short -q HEAD Git创建新的分支并切换 git checkout -b XXXXXXXXXXXXXX git push origin XXXXXXXXXXXXXX

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

未来工作趋势:零工小程序在共享经济中的作用

经济在不断发展的同时,科技也在飞速发展。零工经济作为一种新兴的工作模式,正在全球范围内迅速崛起。特别是在中国,随着数字经济的蓬勃发展和共享经济模式的深入推广,零工小程序在促进就业、提升资源利用效率方面显示出了巨大的潜力和价值。 一、零工经济的定义及现状 零工经济是指通过临时性、自由职业或项目制的工作形式,利用互联网平台快速匹配供需双方的新型经济模式。这种模式打破了传统全职工作的界限,为劳动

Smarty模板引擎工作机制(一)

深入浅出Smarty模板引擎工作机制,我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解。 在没有使用Smarty模板引擎的情况下,我们都是将PHP程序和网页模板合在一起编辑的,好比下面的源代码: <?php$title="深处浅出之Smarty模板引擎工作机制";$content=

3.比 HTTP 更安全的 HTTPS(工作原理理解、非对称加密理解、证书理解)

所谓的协议 协议只是一种规则,你不按规则来就无法和目标方进行你的工作 协议说白了只是人定的规则,任何人都可以定协议 我们不需要太了解细节,这些制定和完善协议的人去做的,我们只需要知道协议的一个大概 HTTPS 协议 1、概述 HTTPS(Hypertext Transfer Protocol Secure)是一种安全的超文本传输协议,主要用于在客户端和服务器之间安全地传输数据

以太网交换机工作原理学习笔记

在网络中传输数据时需要遵循一些标准,以太网协议定义了数据帧在以太网上的传输标准,了解以太网协议是充分理解数据链路层通信的基础。以太网交换机是实现数据链路层通信的主要设备,了解以太网交换机的工作原理也是十分必要的。 1、以太网协议介绍 1.1以太网协议 以太网是当今现有局域网(Local Area Network, LAN)采用的最通用的通信协议标准,该标准定义了在局域网中采用的电缆类型和信号

JVM工作过程

将JVM工作过程粗略分为5个阶段,包括加载阶段、链接阶段、初始化阶段、执行阶段、回收阶段 其中, (1)加载阶段、链接阶段的解析部分主要由类加载器完成 (2)初始化阶段是由JVM的类加载机制在类加载过程的最后阶段自动触发的。 (3)执行阶段主要由执行引擎负责 (4)回收阶段主要是垃圾收集器(Garbage Collector)负责。 所以,在Java虚拟机(JVM)中,读取字节码文件、解析字节码

平时工作学习重要注意的问题

总体原则:抓住重点,条理清晰,可回溯,过程都清楚。 1 要有问题跟踪表,有什么问题,怎么解决的,解决方案。 2 要有常用操作的手册,比如怎么连sqlplus,一些常用的信息,保存好,备查。

Struts 2的工作流程

基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置,该请求被 FilterDispatcher接收。3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。5、Action执行完毕,根据 struts.xml中的配置找到对应的返回结果result