现在的卷积实现无非是那么几种:直接卷积、im2col+gemm、局部gemm、wingrod、FFT。如果直接卷积的话,其实kernel函数是比较好实现。以下代码参考至《OpenCL Programing Guide》,主要是main函数各种构造比较麻烦,个人感觉,OpenCL为了追求平台的移植性,使用起来实在是太不方便了。(代码仅表示思路,未测试)

Convolution.cl:

//Convolution.cl
__kernel void convolve(const __global uint * const input, __constant uint *const mask, __global uint * const output, const int inputWidth, const int maskWidth)
{
const int x = get_global_id();
const int y = get_global_id(); uint sum =;
for(int r =;r<maskWidth;r++)
{
const int idxIntmp = (y +r) *inputWidth +x ;
for(int c = ; c<maskWidth;c++)
{
sum +=mask[(r*maskWidth) +c] * input[idxIntmp +c];
}
}
outpu[y* get_global_size() +x] = sum;
}

//Convolution.cpp

//Convolution.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <CL/cl.h> //Constants
const unsigned int inputSignalWidth = ;
const unsigned int inputSignalHeight= ; cl_uint inputSignal[inputSignalWidth][inputSignalHeight] =
{
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , }
};
const unsigned int outputSignalWidth = ;
const unsigned int outputSignalHeight= ; cl_uint ouputSignal[outputSignalWidth][outputSignalHeight];
const unsigned int maskWidth = ;
const unsigned int maskHeight= ; cl_uint mask[maskWidth][maskHeight] =
{
{, , },
{, , },
{, , }
}; inline void checkErr(cl_int err, const char* name)
{
if(err != CL_SUCCESS)
{
std::cerr <<"ERROR: "<< name
<<" (" << err << ")"<<std::endl;
exit(EXIT_FAILURE);
}
} void CL_CALLBACK contextCallback(const char * errInfo, const void * private_info, size_t cb, void * user_data)
{
std::cout << "Error occurred during context user: "<< errInfo << std::endl;
exit(EXIT_FAILURE);
} int main(int argc, char** argv)
{
cl_int errNum;
cl_uint numPlatforms;
cl_uint numDevices;
cl_platform_id * platformIDs;
cl_context context =NULL;
cl_command_queue queue;
cl_program program;
cl_kernel kernel;
cl_mem inputSignalBuffer;
cl_mem outputSignalBuffer;
cl_mem maskBuffer; errNum = clGetPlatformIDs(, NULL, &numPlatforms);
checkErr( (errNum != CL_SUCCESS )? errNum: (numPlatforms <= ? -: CL_SUCCESS),"clGetPlatformIDs"); deviceIDs = NULL;
cl_uint i;
for(i =; i <numPlatforms; i++)
{
errNum = clGetDeviceIDs(platformIDs[i], CL_DEVICE_TYPE_CPU, , NULL, &numDevices);
if(errNum != CL_SUCCESS && errNum !=CL_DEVICE_NOT_FOUND)
{
checkErr(errNum, "clGetDeviceIDs");
}
else if(numDevices > )
{
deviceIDs = (cl_device_id *)alloca(sizeof(cl_device_id) * numDevices);
break;
}
} cl_context_properties contextProperties[] =
{
CL_CONTEXT_PLATFORM, (cl_context_properties)platformIDs[i],
};
context = clCreateContext(contextProperties, numDevices, deviceIDs,&contextCallback, NULL, &errNum);
checkErr(errNum, "clCreateContext"); std::ifstream srcFile("Convolution.cl");
std::string srcProg(std::istreambuf_iterator<char>(srcFile),(std::istreambuf_iterator<char>())); const char * src = srcProg.c_str();
size_t length = srcProg.length(); program = clCreateProgramWithSource(context, , &src, &length, &errNum);
checkErr(errNum, "clCreateProgramWithSource"); errNum = clBuildProgram(program, numDevices, deviceIDs, NULL, NULL, NULL);
checkErr(errNum, "clBuildProgram"); kernel = clCreateKernel(program, "convolve", &errNum);
checkErr(errNum, "clCreateKernel"); inputSignalBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_uint) * inputSignalHeight * inputSignalWidth,
static_cast<void*> (inputSignal), &errNum);
checkErr(errNum, "clCreateBuffer(inputSignal)"); maskBuffer = clCreateBuffer(context,CL_MEM_READ_ONLY| CL_MEM_COPY_HOST_PTR, sizeof(cl_uint)* maskHeight *maskWidth, static_cast<void*>(mask), &errNum);
checkErr(errNum, "clCreateBuffer(mask)"); outputSignalBuffer= clCreateBuffer(context,CL_MEM_WRITE_ONLY ,sizeof(cl_uint)* outputSignalHeight *outputSignalWidth, NULL, &errNum);
checkErr(errNum, "clCreateBuffer(outputSignal)"); queue = clCreateCommandQueue(context, deviceIDs[], , &errNum);
checkErr(errNum, "clCreateCommandQueue"); errNum = clSetKernelArg(kernel, , sizeof(cl_mem), &inputSignalBuffer);
errNum |=clSetKernelArg(kernel, , sizeof(cl_mem), &maskBuffer);
errNum |=clSetKernelArg(kernel, , sizeof(cl_mem), &outputSignalBuffer);
errNum |=clSetKernelArg(kernel, , sizeof(cl_uint),&inputSignalWidth);
errNum |=clSetKernelArg(kernel, , sizeof(cl_uint),&maskWidth);
checkErr(errNum, "clSetKernelArg"); const size_t globalWorkSize[] = {outputSignalWidth *outputSignalHeight};
const size_t localWorkSize[] = {}; errNum = clEnqueueNDRangeKernel(queue,kernel, , NULL, globalWorkSize, localWorkSize, , NULL, NULL);
checkErr(errNum, "clEnqueueNDRangeKernel"); errNum = clEnqueueReadBuffer(queue, outputSignalBuffer,CL_TRUE, , sizeof(cl_uint)*outputSignalHeight*outputSignalWidth, outputSignal, , NULL, NULL);
checkErr(errNum, "clEnqueueReadBuffer");
return ;
}

OpenCl入门——实现简单卷积的更多相关文章

  1. OpenCL入门:(二:用GPU计算两个数组和)

    本文编写一个计算两个数组和的程序,用CPU和GPU分别运算,计算运算时间,并且校验最后的运算结果.文中代码偏多,原理建议阅读下面文章,文中介绍了OpenCL相关名词概念. http://opencl. ...

  2. 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)

    1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...

  3. [电子书] 《Android编程入门很简单》

    <Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...

  4. Redis入门很简单之六【Jedis常见操作】

    Redis入门很简单之六[Jedis常见操作] http://www.tuicool.com/articles/vaqABb http://www.cnblogs.com/stephen-liu74/ ...

  5. 《Mysql 入门很简单》(读后感①)

    下载完整版<Mysql 入门很简单>,点击这里~: http://files.cnblogs.com/files/zhengyeye/MySQL%E5%85%A5%E9%97%A8%E5% ...

  6. Hibernate入门2.简单的项目开发实例

    Hibernate入门2.简单的项目开发实例 这一节通过一个简单的项目学习Hibernate项目的配置 代码下载 : 链接: http://pan.baidu.com/s/1zlgjl 密码: p34 ...

  7. 资深架构师Sum的故事:正则!入门就是这样简单

    | 故事背景 职场如战场!Sum带领三个小队友用了两周,成功把代理功能给干出来了.如果说产品经理是最魔鬼的指挥官,那测试就是最魔鬼的教官.这两周,让Sum深深领略了什么是X市的日出. 不过话又说回来, ...

  8. Redis入门很简单之七【使用Jedis实现客户端Sharding】

    Redis入门很简单之七[使用Jedis实现客户端Sharding] 博客分类: NoSQL/Redis/MongoDB redisjedisspringsharding分片 <一>. 背 ...

  9. Redis入门很简单之五【Jedis和Spring的整合】

    Redis入门很简单之五[Jedis和Spring的整合] 博客分类: NoSQL/Redis/MongoDB redisnosql缓存jedisspring  在上一篇文章中,简单介绍了Jedis的 ...

随机推荐

  1. JDBC的工具类

    A: 抽取两个方法,一个获取Connection对象,一个是释放资源 import java.io.FileReader; import java.sql.Connection; import jav ...

  2. 怎么通过原生JS改变元素的class属性

    解决方法:document.getElementById('test').className = 'emphasis' Eg: <!doctype html> <html lang= ...

  3. kafka----简单的脚本命令重点

    kafka命令如下: kafka-shell基本命令 在节点hadoop-2,hadoop-3,hadoop-5,启动kafka 启动命令如下 kafka-server-start.sh /usr/l ...

  4. unittest快速装载目前下所有测试用例的方法

    import unittest from BeautifulReport import BeautifulReport #导入BeautifulReport if __name__ == '__mai ...

  5. JAVA 基础编程练习题24 【程序 24 根据输入求输出】

    24 [程序 24 根据输入求输出] 题目:给一个不多于 5 位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. package cskaoyan; public class cskaoya ...

  6. Entity Framework链接数据库设置

    本人不才,学习EntityFramwork同时做个记录供大家参考.不多说,直接上步骤 1.在WebConfig中添加如下代码段 <connectionStrings> <add na ...

  7. CSS - clearfix清除浮动

    首先,我们来解释一下为什么要使用 clearfix(清除浮动). 通常我们在写html+css的时候,如果一个父级元素内部的子元素是浮动的(float),那么常会发生父元素不能被子元素正常撑开的情况, ...

  8. 移动端自动化测试之android模拟器问题集合

    黑屏 在做移动端自动化测试过程中,android模拟器启动黑屏的问题一直困扰着我,网上找了许多方法尝试了都不能解决我的问题,最后重新安装了镜像文件,问题才得以解决,当然并不是网上的解决办法都是错的,只 ...

  9. 【ABAP系列】ABAP CL_ABAP_CONV_IN_CE

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]ABAP CL_ABAP_CON ...

  10. 大周末的不休息,继续学习pandas吧,pandas你该这么学,No.7

    其实,写文章真的挺难的 每天抽点时间,写写文采飘逸的文章 坚持个几年,成为称霸一方的大佬 坚持就会成功吧~ 最近碰到瓶颈了, 一直找不到好的运营公众号的方式(好想有人指导唉~,对了,橡皮擦有个100多 ...