openCL学习记录

来源:互联网 发布:屏幕截图软件下载 编辑:程序博客网 时间:2024/06/06 12:44

最近两天一直在看从图书馆借来的一本关于openCL书,看完了,效果不理想,接下来看着别人的博客写的还不错,清晰明了。

AMD OpenCL


编写OpenCL程式
先取得系统上所有的OpenCL platform(先取得platform的数目;取得platform的ID);
建立一个OpenCL context;
取得装置的列表;
建立Command Queue:Command queue 可以接收对一個 OpenCL 裝置的各种操作,並按照顺序执行

OpenCL编程的过程:

1、获得平台,clGetPlatformIDs

2、创建上下文,clCreateContextFromType,这个函数的第一个参数为NULL时在AMD的平台上运行不能通过,必须为该函数指定第一个参数。

3、通过上下文得到设备信息,clGetContextInfo

4、为相应设备创建comandQueue, clCreateCommandQueue

5、创建源程序,build源程序,生成kernel

6、分配buffer空间,逐个设置程序参数。

7、执行kernel,clEnqueueNDRangeKernel

8、从buffer读回数据,clEnqueueReadBuffer

---------------------------------------------------------------------------------------------------------------------------
OpenCL应用分两个部分:一个是主机端应用;一个是OpenCL内核。


创建一个opencl应用:


1.获得设备ID:使用clGetDeviceIDs()来获取一个或多个设备ID;调用完这个函数后,如果返回值为成功,那么以后就可以用这个ID来创建上下文了;


2.获取上下文:使用clCreateContext()来获得上下文;在OpenCL运行时,上下文用于管理对象和在上下文中所指定的一个或多个设备上的执行内核;


3.创建一个命令队列:使用clCreateCommandQueue()来创建一个OpenCL命令队列;OpenCL命令队列用于将工作提交给设备,它们安排一个设备上内核的执行,且操作存储器对象;


4.用源代码缓存创建程序:使用clCreateProgramWithSource()或clCreateProgramWithBinary()来创建程序对象;一个OpenCL程序是由一组内核构成;一个内核是源代码中用__kernel限定符修饰的函数;OpenCL程序也可包含辅助函数和常量数据;它们被内核函数所使用

一个程序对象包含了以下信息:
一个相关联的上下文;一个程序源代码或二进制代码;最近成功被构建的可执行程序,该可执行程序是根据前面所创建好的设备列表而被构建;当前所连接的内核对象的个数;


5.构建OpenCL程序:使用clBuildProgram()来构建OpenCL程序;使用clCreateProgramWithSource()创建完的是一个包含源代码的程序对象;要运行设备上的OpenCL程序必须对它进行编译、连接;而对于用clCreateProgramWithBinary创建的程序对象,则需要进行连接;这样就可以构建成一个完整的可加载的执行程序;


6.创建内核对象:使用clCreateKernel()创建一个内核对象;一个内核对象对应着一个OpenCL程序中用__kernel修饰的一个内核函数;内核对象封装了内核函数以及执行此内核函数时的实参;


7.创建缓存对象:使用clCreateBuffer()来创建缓存对象;OpenCL的存储器对象分为两种类型,一种是缓存对象,另一种是图像对象;缓存对象存放的是一组一维的元素集;而图像对象存放一个二维或三维的纹理或帧缓存或图像;缓存对象中的数据可以通过一个指针任意获得;而图像对象的数据则是需要通过相应的API进行访问;存储器对象通过作为对内核函数的实参被OpenCL内核函数操作;


8.将输入缓存写入设备端:使用clEnqueueWriteBuffer()来实现写命令;创建好了输入缓存对象后,需要把数据传输到OpenCL设备端可访问的存储器中,那么可以通过命令队列,发布写命令来执行此操作;


9.对计算内核传递实参:使用clSetKernelArg()来为计算内核传递实参;要执行一个内核,必须首先对它设置参数;


10.获得在设备上执行内核的工作组的最大大小:使用clGetKernelWorkGroupInfo()来获得指定内核对象的最大工作组大小;


11.执行内核函数:使用clEnqueueNDRangeKernel()来排队执行计算一个内核的命令;如果内核使用单个工作项来执行——比如运行在一个CPU上,那么可以使用clEnqueueTask()函数;


12.等待执行结束且获取结果:通过调用clFinish()来等待命令队列中的所有命令执行完成;通过调用clEnqueueReadBuffer()来获取OpenCL内核计算函数的计算结果;

0 0
原创粉丝点击