初入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. table 转实体

    public class Table2Entity<T> where T : class,new() { public static List<T> GetEntitys(Da ...

  2. vue的v-model绑定数据问题

    在我的项目中有一个这样的功能模块: 我们修改数据全是在前台的table中修改,然后把这个table的值带到后台.(理想:修改值后,点击确认值改变,点击取消值恢复原来的值)那么问题就来了: a)你修改值 ...

  3. LeetCode OJ:Power of Two(2的幂)

    Given an integer, write a function to determine if it is a power of two. 看一个数是不是2的幂,代码如下: class Solu ...

  4. functools 和 itertools

    functools 补充 1 wraps 在编写装饰器时,在实现前加入 @functools.wraps(func) 可以保证装饰器不会对被装饰函数造成影响.wraps 保存被装饰函数的原信息 def ...

  5. Kotlin Reference (八) Classes and Objects

    most from reference 类 Kotlin的类的声明使用关键字class class Invoice { } 类声明由类名.类头(指定其类型参数,构造函数等)和类体组成,由大括号括起来. ...

  6. Gradle 1.12用户指南翻译——第六十五章. Maven 发布(新)

    其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上的地址:https://gith ...

  7. TeamTalk源码分析(十一) —— pc客户端源码分析

           --写在前面的话  在要不要写这篇文章的纠结中挣扎了好久,就我个人而已,我接触windows编程,已经六七个年头了,尤其是在我读研的三年内,基本心思都是花在学习和研究windows程序上 ...

  8. [Github] 本地git push免用户名和密码的配置

    在终端通过git config --global命令进行配置 git config --global user.email "xxx@xxmail.com" git config ...

  9. chrome 55 zepto tap事件出错?

    刚才升级chrome后发现的,在54.0.2840.98上点击没有问题,在新升级的55.0.2883.75 上点击后会报错Cannot read property 'trigger' of undef ...

  10. .pyc和.pyo文件有何用

    百度知道:http://zhidao.baidu.com/link?url=_tFP1xglFnoEBObWtIArI3b3Ft0PQowx5m5ruIaX3mFIAFVr7vX45Lfb0geCjA ...