OpenCL入门
初入OpenCL,做个记录。
在Windows下开发OpenCL程序,必须先下载OpenCL的SDK,现在AMD,NVIDIA,Intel均提供各自的OpenCL库,基本是大同小异。安装好SDK后新建Win32控制台项目,然后需要配置下包含文件路径和库路径,具体见下图(我安装的Intel的SDK )。
1.其中那个包含Intel的路径就是包含cl.h文件的目录。

2.如图中那个Intel的lib目录

3.添加需要连接的静态库OpenCL.lib

配置完成后就可以开始写代码调试了,OpenCL的初始化还是很复杂的,和CUDA几行代码搞定完全没可比性,刚开始可能对流程不太熟悉,慢慢熟悉就好,当然也可以自己写个框架来做这些复杂的初始化工作。OpenCL的内核代码是即时编译的,代码中我为了方便没有从cl文件中读入Kernel代码,直接以字符串的形式定义了。
#include "stdafx.h" #include <iostream>
#include <fstream>
#include <string.h>
#include <vector>
using namespace std; #if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.h>
#endif #define KERNEL(...) #__VA_ARGS__ #define ARRAY_X_LEN 16
#define ARRAY_Y_LEN 16 const char *kernelSourceCode = KERNEL(
__kernel void VecAdd(__global int *buffer1, __global int *buffer2, __global int *buffer3)
{
size_t idx = get_global_id();
size_t idy = get_global_id();
int dimX = get_global_size();
int dimY = get_global_size();
int id = idx + idy*dimX;
buffer3[id] = buffer1[id] + buffer2[id];
}); int main()
{
cl_int status = ;
size_t deviceListSize;
cl_uint numPlatforms;
cl_platform_id platform = NULL;
status = clGetPlatformIDs(, NULL, &numPlatforms);
if (status != CL_SUCCESS)
{
printf("获取平台数目失败");
return EXIT_FAILURE;
}
if (numPlatforms >)
{
cl_platform_id* platforms = (cl_platform_id*)malloc(numPlatforms*sizeof(cl_platform_id));
status = clGetPlatformIDs(numPlatforms, platforms, NULL);
if (status != CL_SUCCESS)
{
printf("初始化平台失败");
return -;
}
for (unsigned int i = ; i<numPlatforms; ++i)
{
char *vendor = (char*)malloc();
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);
platform = platforms[i];
if (!strcmp(vendor, "NVIDIA Corporation"))
{
break;
}
}
delete platforms;
}
cl_context_properties cps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, };
cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
cl_context context = clCreateContextFromType(cprops, CL_DEVICE_TYPE_GPU, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
printf("创建上下文失败");
return EXIT_FAILURE;
}
status = clGetContextInfo(context, CL_CONTEXT_DEVICES, , NULL, &deviceListSize);
if (status != CL_SUCCESS)
{
printf("获取设备数目失败");
return EXIT_FAILURE;
}
cl_device_id *devices = (cl_device_id *)malloc(deviceListSize);
if (devices == )
{
printf("为设备分配空间失败");
return EXIT_FAILURE;
}
status = clGetContextInfo(context, CL_CONTEXT_DEVICES, deviceListSize, devices, NULL);
if (status != CL_SUCCESS)
{
printf("初始化设备失败");
return EXIT_FAILURE;
} size_t sourceSize[] = { strlen(kernelSourceCode) };
cl_program program = clCreateProgramWithSource(context, , &kernelSourceCode, sourceSize, &status);
if (status != CL_SUCCESS)
{
printf("创建程序失败");
return EXIT_FAILURE;
}
status = clBuildProgram(program, , devices, NULL, NULL, NULL);
if (status != CL_SUCCESS)
{
printf("编译程序失败");
return EXIT_FAILURE;
}
cl_kernel kernel = clCreateKernel(program, "VecAdd", &status);
if (status != CL_SUCCESS)
{
printf("创建内核失败");
return EXIT_FAILURE;
}
cl_command_queue commandQueue = clCreateCommandQueue(context, devices[], , &status);
if (status != CL_SUCCESS)
{
printf("创建命令队列失败");
return EXIT_FAILURE;
}
int arrayLenght = ARRAY_X_LEN*ARRAY_Y_LEN;
int arraySize = arrayLenght*sizeof(int); int *hA = new int[arrayLenght];
int *hB = new int[arrayLenght];
int *hC = new int[arrayLenght]; memset(hA, , arraySize);
memset(hB, , arraySize);
memset(hC, , arraySize); for (int i = ; i<arrayLenght; i++)
{
hA[i] = i;
hB[i] = i;
} cl_mem dA = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, arraySize, NULL, &status);
if (status != CL_SUCCESS)
{
printf("创建内存对象失败");
return EXIT_FAILURE;
}
cl_mem dB = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, arraySize, NULL, &status);
if (status != CL_SUCCESS)
{
printf("创建内存对象失败");
return EXIT_FAILURE;
}
cl_mem dC = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, arraySize, NULL, &status);
if (status != CL_SUCCESS)
{
printf("创建内存对象失败");
return EXIT_FAILURE;
}
status = clEnqueueWriteBuffer(commandQueue, dA, CL_TRUE, , arraySize, hA, , NULL, NULL);
if (status != CL_SUCCESS)
{
printf("输入值写入内存对象失败");
return EXIT_FAILURE;
}
status = clEnqueueWriteBuffer(commandQueue, dB, CL_TRUE, , arraySize, hB, , NULL, NULL);
if (status != CL_SUCCESS)
{
printf("输入值写入内存对象失败");
return EXIT_FAILURE;
}
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void*)&dA);
if (status != CL_SUCCESS)
{
printf("设置内核参数失败");
return EXIT_FAILURE;
}
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void*)&dB);
if (status != CL_SUCCESS)
{
printf("设置内核参数失败");
return EXIT_FAILURE;
}
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void*)&dC);
if (status != CL_SUCCESS)
{
printf("设置内核参数失败");
return EXIT_FAILURE;
}
size_t globalThreads[] = { ARRAY_X_LEN, ARRAY_Y_LEN };
size_t localThreads[] = { , };
status = clEnqueueNDRangeKernel(commandQueue, kernel, , NULL, globalThreads, localThreads, , NULL, NULL);
if (status != CL_SUCCESS)
{
printf("将内核放入命令队列失败");
return EXIT_FAILURE;
}
status = clFinish(commandQueue);
if (status != CL_SUCCESS)
{
printf("队列还没有完成");
return EXIT_FAILURE;
}
status = clEnqueueReadBuffer(commandQueue, dC, CL_TRUE, , arraySize, hC, , NULL, NULL);
if (status != CL_SUCCESS)
{
printf("读内存对象失败");
return EXIT_FAILURE;
}
printf("结果:\n");
for (int i = ; i<arrayLenght; i++)
{
printf("%d ", hC[i]);
if ((i + ) % ARRAY_X_LEN == )
printf("\n");
}
status = clReleaseKernel(kernel);
status = clReleaseProgram(program);
status = clReleaseMemObject(dA);
status = clReleaseMemObject(dB);
status = clReleaseMemObject(dC);
status = clReleaseCommandQueue(commandQueue);
status = clReleaseContext(context);
free(devices);
delete [] hA;
delete [] hB;
delete [] hC;
return ;
}
运行结果:

OpenCL入门的更多相关文章
- OpenCL入门:(二:用GPU计算两个数组和)
本文编写一个计算两个数组和的程序,用CPU和GPU分别运算,计算运算时间,并且校验最后的运算结果.文中代码偏多,原理建议阅读下面文章,文中介绍了OpenCL相关名词概念. http://opencl. ...
- OpenCL入门:(三:GPU内存结构和性能优化)
如果我们需要优化kernel程序,我们必须知道一些GPU的底层知识,本文简单介绍一下GPU内存相关和线程调度知识,并且用一个小示例演示如何简单根据内存结构优化. 一.GPU总线寻址和合并内存访问 假设 ...
- OpenCL入门:(一:Intel核心显卡OpenCL环境搭建)
组装的电脑没带独立显卡,用的是CPU自带的核显,型号是Intel HD Graphics 530,关于显卡是否可以使用OpenCL,可以下载GPU-Z软件查看. 本文在Windows 10 64位系统 ...
- OpenCl入门——实现简单卷积
现在的卷积实现无非是那么几种:直接卷积.im2col+gemm.局部gemm.wingrod.FFT.如果直接卷积的话,其实kernel函数是比较好实现.以下代码参考至<OpenCL Progr ...
- OpenCl入门getting-started-with-opencl-and-gpu-computing
原文来自于:getting-started-with-opencl-and-gpu-computing/ 对整个程序的注释:http://www.kimicat.com/opencl-1/opencl ...
- 《OpenCL异构并行编程实战》补充笔记散点,第一至四章
▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...
- OpenCL学习笔记(三):OpenCL安装,编程简介与helloworld
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. OpenCL安装 安装我不打算 ...
- 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV
这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...
- 从零開始学习OpenCL开发(一)架构
多谢大家关注 转载本文请注明:http://blog.csdn.net/leonwei/article/details/8880012 本文将作为我<从零開始做OpenCL开发>系列文章的 ...
随机推荐
- MVC,MVVM,MVP等设计模式的分析
从Script到Code Blocks.Code Behind到MVC.MVP.MVVM 三个模式按照大致的历史进程将这些概念进行划分: Script Code Blocks.Code Behind ...
- Spring3.0 核心jar包详解
org.springframework.aop 包含在应用中使用Spring的AOP特性时所需的类. org.springframework.asm Spring独立的ASM程序, Spring ...
- python----tkinterm模块
python tkinter学习——布局 目录 一.pack() 二.grid() 三.place() 四.Frame() 正文 布局 一.pack() pack()有以下几个常用属性: side ...
- QuerySetAPI笔记
学习Django时做的笔记MarkDown文件点这里 # 模型.objects:这个对象是`django.db.models.manager.Manager`的对象,这个类是一个空壳类,他上面的所有方 ...
- FreeMarker初探--介绍
FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP.它不仅可以用作表现层的实现 ...
- springcloud- FeginClient 调用统一拦截添加请求头 RequestInterceptor ,被调用服务获取请求头
使用场景: 在springcloud中通过Fegin调用远端RestApi的时候,经常需要传递一些参数信息到被调用服务中去,比如从A服务调用B服务的时候, 需要将当前用户信息传递到B调用的服务中去,我 ...
- KindEditor富文本编辑框和BeautifulSoup的基本使用
KindEditor富文本编辑框 1.进入官网 2.下载 官网下载:http://kindeditor.net/down.php 本地下载:http://files.cnblogs.com/files ...
- APUE学习笔记——8.1-8.4 进程基础
进程ID 1 进程id是唯一的.(不会有进程id一样的两个进程) 2进程id是可复用的,一个进程销毁后,它的id号可以被新的进程使用.但是Unix采用了延迟复用的算法,也就是进程 销毁后它的id不 ...
- Linux系统在启动过程中grub引导文件丢失的解决方法
在/boot/grub2目录下有一个grub.cfg文件:该文件主要是用来自动地引导系统启动内核程序和系统的初始化程序. 问题一:当系统在启动的情况下,我们不小心删除/boot/grub2/grub. ...
- 表单隐藏域与display:none
有时候前端进行表单填写是分步骤的,每一步的时候其他步骤相关的表单视图不可见: 针对"不可见",以下有两种处理方式: ①display:none 这种方式呢,比较简单,就是将三个步骤 ...