初入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. 大白话,讲编程之《ES6系列连载》汇总

    如果你经历过2,3年前的前端开发,你一定感受过兼容IE6,7的痛苦,一定用过网页三剑客的dreamweaver编写html,面试的时候面试官一定会问你:会用PS切图吗? 刚开始的时候你发现,web前端 ...

  2. IOS-UISearchBar

    UISearchBar控件   最近用到搜索功能.于是,经过不断的研究,终于,有点懂了. 那就来总结一下吧,好记性不如烂笔头! 搜索,无疑可以使用UISearchBar控件! 那就先了解一下UISea ...

  3. 【Error】IOError: [Errno 22] invalid mode

    使用python打开或写入文件时会报以下错误IOError: [Errno 22] invalid mode,比如打开f:\nnpm.txt时,可以在地址前面加上r或R,即r'f:\nnpm.txt' ...

  4. Linux 磁盘管理,Linux vi/vim

    一.Linux 磁盘管理 Linux磁盘管理好坏直接关系到整个系统的性能问题. Linux磁盘管理常用三个命令为df.du和fdisk. df:列出文件系统的整体磁盘使用量 du:检查磁盘空间使用量 ...

  5. CF910C

    题解: 首先考虑暴力不行 然后采用贪心 按位展开 然后注意不能有前缀0 代码: #include<bits/stdc++.h> using namespace std; ],ans; ], ...

  6. 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之ZwSetInformationProcess函数

    1.    DEP内存保护机制 1.1   DEP工作原理 分析缓冲区溢出攻击,其根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计算机体系结构基本上是不可能的,我们只能靠 ...

  7. java根据所给的根目录获取底下所有文件夹结构

    所写工具类背景:项目经理叫我写个工具类实现:给个项目的根目录分析java文件及jsp文件.记录文件类型.路径.文件名和包名. 定义的实体类(这里我用了easypoi以后方便写入excel文档) @Da ...

  8. Cscope 安装和使用

    CScope 安装和使用 一.安装 1. 软件下载 https://sourceforge.net/projects/cscope/files/ 2. 解压 3. 安装 ./configure --p ...

  9. java事务(二)

    本地事务 事务类型 事务可以分为本地事务和分布式事务两种类型.这两种事务类型是根据访问并更新的数据资源的多少来进行区分的.本地事务是在单个数据源上进行数据的访问和更新,而分布式事务是跨越多个数据源来进 ...

  10. MP3格式音频文件结构解析

    MP3的全称是MPEG Audio Layer3,它是一种高效的计算机音频编码方案,它以较大的压缩比将音频文件转换成较小的扩展名为.MP3的文件,基本保持原文件的音质.MP3是ISO/MPEG标准的一 ...