初入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入门的更多相关文章

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

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

  2. OpenCL入门:(三:GPU内存结构和性能优化)

    如果我们需要优化kernel程序,我们必须知道一些GPU的底层知识,本文简单介绍一下GPU内存相关和线程调度知识,并且用一个小示例演示如何简单根据内存结构优化. 一.GPU总线寻址和合并内存访问 假设 ...

  3. OpenCL入门:(一:Intel核心显卡OpenCL环境搭建)

    组装的电脑没带独立显卡,用的是CPU自带的核显,型号是Intel HD Graphics 530,关于显卡是否可以使用OpenCL,可以下载GPU-Z软件查看. 本文在Windows 10 64位系统 ...

  4. OpenCl入门——实现简单卷积

    现在的卷积实现无非是那么几种:直接卷积.im2col+gemm.局部gemm.wingrod.FFT.如果直接卷积的话,其实kernel函数是比较好实现.以下代码参考至<OpenCL Progr ...

  5. OpenCl入门getting-started-with-opencl-and-gpu-computing

    原文来自于:getting-started-with-opencl-and-gpu-computing/ 对整个程序的注释:http://www.kimicat.com/opencl-1/opencl ...

  6. 《OpenCL异构并行编程实战》补充笔记散点,第一至四章

    ▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...

  7. OpenCL学习笔记(三):OpenCL安装,编程简介与helloworld

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. OpenCL安装 安装我不打算 ...

  8. 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV

    这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...

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

    多谢大家关注 转载本文请注明:http://blog.csdn.net/leonwei/article/details/8880012 本文将作为我<从零開始做OpenCL开发>系列文章的 ...

随机推荐

  1. MongoDB 3.4 分片 由副本集组成

    要在真实环境中实现MongoDB分片至少需要四台服务器做分片集群服务器,其中包含两个Shard分片副本集(每个包含两个副本节点及一个仲裁节点).一个配置副本集(三个副本节点,配置不需要仲裁节点),其中 ...

  2. mysql中一个字段根据另一字段的值分割为不同列

    1.数据结构如下: vehicleId mileage_type mileage 11AM6897           0 120 11AM6897           1 60 13AY9180 0 ...

  3. HighCharts 特性;Highcharts 环境配置

    Highcharts Highcharts 是一个用纯JavaScript编写的一个图表库. Highcharts 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表 Highchart ...

  4. 008-对象—— 对象$this self parent 内存方式及使用方法讲解

    <?php /** * */ /*class Web{ private $webname; private $weburl; function __construct($webname,$web ...

  5. hdu3829

    题解: 对于每一个孩子裂点+建边 如果i孩子讨厌的和j孩子喜欢的相同,那么建边 然后跑最大独立集 代码: #include<cstdio> #include<cstring> ...

  6. js 多个倒计时,毫秒倒计时

    其实主要是借鉴了了这篇文的写法(http://tuzwu.iteye.com/blog/819081),俺稍作了修改,以便更适合我的需要: 实现功能:调用一个函数,传入html元素的id,和一个截止时 ...

  7. 201621123005《Java程序设计》第四周学习总结

    201621123005<Java程序设计>第四周学习总结 标签(空格分隔): 1.本章学习总结 1. 面向对象设计 1.1 写出你认为本周学习中比较重要的知识点关键词 继承.多态.覆盖. ...

  8. PostgreSQL基于时间点故障恢复PITR( point-in-time recovery )

    PostgreSQL在使用过程中经常会发生一些失误的操作,但往往是可以弥补的.但是如果真遇到了无法挽回的误操作,只能寄希望于有备份了. 接下来的故障恢复也是基于有备份的情况,没有备份的情况,目前还没有 ...

  9. Swift 3 实现拍照功能

    编辑.plist文件,添加两个key-value,打开相机和相册的访问权限1) 申请相机权限: <key>NSCameraUsageDescription</key> < ...

  10. 关于Instruments-Leaks工具的归纳总结

    前言: 本篇文章,在于学习,我把别人的一些感觉好的文章汇总成了一篇,亲自实现了一下,留用于今后学习资料. 文章脉络: 文章脉络: 一.内存优化 简介:Objective_C 有3种内存管理方法, 它们 ...