1. 选择OpenCL平台并创建一个上下文
平台是指主机和OpenCL管理框架下的若干个设备构成的可以运行的OpenCL程序的完整硬件系统,这个是跑OpenCL程序的基础,所以第一步要选择一个可用的OpenCL平台,一台机器上可以有不止一个这样的平台,一个平台也可以有不止一个GPU。
主要涉及的函数:clGetPlatformIDs(),用于获取可用的平台;
clCreateContextFormType(),创建一个OpenCL运行时上下文环境;
2. 选择设备并创建命令队列
选择平台并创建好OpenCL上下文环境之后,要做的事情选择运行时需要用的设备,还要创建一个命令队列,命令队列里定义了设备要完成的操作,以及各个操作的运行次序。
主要涉及的函数:clCreateCommandQueue(),用于创建一个指定设备上的命令队列,第二个参数定义了选择的设备。
3. 创建和构建程序对象
程序对象用来存储和上下文关联的设备的已编译可执行代码,同时也完成内核源代码的加载编译工作。
主要涉及的函数:clCreateProgramWithSource(),这个函数会创建一个程序对象,在创建的同时,把已经转化成字符串形式的内核源代码加载到该程序对象中。
4. 创建内核和内存对象
要执行程序对象中的已编译成功的内核运算,需要在内存中创建内核并分配内核函数的参数,在GPU上定义内存对象并分配存储空间。
主要涉及的函数:clCreateKernel(),创建内核;
clCreateBuffer(),分配内存对象的存储空间,这些对象可以用内核函数直接访问。
5. 设置内核数据并执行内核
创建内核和内存对象之后,接下来要设置核函数的数据,并将要执行的内核排队。
主要涉及的函数:clEnqueueNDRangeKernel(),用于设置内核函数的所有参与运算的数据。利用命令队列对要在设备上执行的内核排队。需要注意的是,执行内核排队之后并不意味着这个内核一定会立即执行,只是排队到了执行队列中。
6. 读取执行结果并释放OpenCL资源
内核执行完成之后,需要把数据从GPU拷贝到CPU中,供主机进一步处理,所有者写工作完成之后需要释放所有的OpenCL资源。
主要涉及的函数:clEnqueueReadBuffer(),读取设备内存数据到主机内存;
clReleaseXXX(),释放OpenCL资源。