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开发>系列文章的 ...
随机推荐
- iOS自动化探索(七)自动化测试框架pytest - 测试报告
这里我们单独来看下关于如何生存测试报告 准备测试代码如下: #coding: utf- import pytest @pytest.fixture() def login(): print '输入账号 ...
- MYSQL-实现分组排序 对比 ORACLE 和SQLserver用 row_number() over(partition by ) 分组排序功能
以下是个人笔记: 本文是为了理解 row_number() over(partition by ) 和实现各种数据库的分组排序功能 select ROW_NUMBER()over( partitio ...
- PIVOT 和 UNPIVOT 命令的SQL Server版本
I:使用 PIVOT 和 UNPIVOT 命令的SQL Server版本要求 1.数据库的最低版本要求为 SQL Server 2005 或 更高 2.必须将数据库的兼容级别设置为 90 或 更高 3 ...
- MySQL20个经典面试题
MySQL20个经典面试题 Part2:经典题目 1.MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联: 2.MySQL中myisam与innodb的区别,至少5点 (1).问5点不 ...
- SSH服务:packet_write_wait: Connection to 67.218.143.160 port 22: Broken pipe错误处理
1.在~/.ssh/config配置文件中添加 IPQoS lowdelay throughput 2.在/etc/ssh/ssh_config配置文件中添加 IPQoS lowdelay throu ...
- L150 Mystery Illness Causing Paralysis in Children Baffles Doctors
Federal and state health officials are baffled by a mysterious and rare illness that seems to target ...
- jquery 判断checkbox状态
jquery判断checked的三种方法:.attr('checked): //看版本1.6+返回:”checked”或”undefined” ;1.5-返回:true或false.prop('c ...
- vue.js 源代码学习笔记 ----- instance inject
/* @flow */ import { hasSymbol } from 'core/util/env' import { warn } from '../util/index' import { ...
- Nginx 作为反向代理优化要点proxy_buffering
当nginx用于反向代理时,每个客户端将使用两个连接:一个用于响应客户端的请求,另一个用于到后端的访问: 那么,可以从如下配置起步: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- Android 开发 Tip 17 -- 为什么getBackground().setAlpha(); 会影响别的控件?
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/75670018 http://www.jb51.net/article/110035.h ...