第三章 平台、上下文和设备

本章将更详细地研究OpenCL上下文(也就是环境)和设备,具体包括以下概念:

  • 列举和查询OpenCL平台
  • 列举和查询OpenCL设备
  • 创建上下文和关联设备,以及实现由这个隐含环境定义的同步和内存管理

3.1 OpenCL平台

平台集可以用一下命令查询:

cl_int clGetPlatformIDs(cl_uint num_entries, 
                                  cl_platform_id* platforms,
                                  cl_uint* num_platforms)    

这个命令会得到可用的OpenCL平台的列表。如果参数platforms为NULL,clGetPlatformIDs会返回可用平台数。

cl_int errNum;
cl_uint numPlatforms;
cl_platform_id* platformIds;
cl_context context = NULL;
errNum = clGetPlatformIDs(0, NULL, &numPlatforms);
platformIds = (cl_platform_id*) alloca(sizeof(cl_platform_id) * numPlatforms);
errNum = clGetPlatformIDs(numPlatforms, platformIds, NULL);  

给定一个平台,可以用一下命令查询各个属性:

cl_int clGetPlatformInfo(cl_platform_id platform,
                                   cl_platform_info para_name,
                                   size_t param_value_size, 
                                   void* param_value,
                                   size_t* param_value_size_ret)

3.2 OpenCL设备

各个平台可能会分别关联一组计算设备,应用程序将利用这些计算设备执行代码。给定一个平台,可以用一下命令查询支持的设备列表:

cl_int clGetDeviceIDs(cl_platform_id platform,
                                cl_device_type device_type,
                                cl_uint num_entries,
                                cl_device_id* devices,
                                cl_uint* num_devices)

 这个命令会得到与platform关联的可用OpenCL设备列表。如果devices为NULL,clGetDeviceIDs会返回设备数。

cl_int errNum;
cl_uint numDevices;
cl_device_id deviceIds[1];
errNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
if (numDevices < 1) {
    exit(1);  
}
errNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &deviceIds[0], NULL);  

给定一个设备,可以使用以下命令查询各种属性:

cl_int clGetDeviceInfo(cl_device_id device, 
                                cl_device_info param_name,
                                size_t param_value_size,
                                void* param_value,
                                size_t* param_value_size_ret

这个命令会返回关于OpenCL平台的特定信息。

使用clGetDeviceInfo()查询一个设备,得到计算单元的最大数目:

cl_int err;
size_t size;
err = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_COMPUTE_UINTS, sizeof(cl_uint), &maxComputeUints, &size)

3.3 OpenCL上下文

上下文为关联的设备、内存对象、以及命令队列提供了一个容器。正式上下文驱动着应用程序与特定设备之间的通信,为此OpenCL定义了内存模型。

可以使用多个上下文,分别由不同平台创建,并把工作分布到这些上下文和关联的设备上。区别在于,OpenCL的内存由不同平台创建,这说明内存对象不能由不同的上下文共享。这也意味着,需要在上下文之间共享的数据必须手动在上下文之间移动。

          平台、设备和上下文

通常平台和设备会在程序或库的开始位置查询,阈值不同,我们希望在程序运行过程中更新上下文,或者分配或删除内存对象等。一般地,应用程序会这样使用OpenCL:

  1. 查询有哪些平台;
  2. 查询各个平台支持的设备集:使用clGetDeiviceInfo()为特定功能选择设备;
  3. 由选择的设备创建上下文(必须由一个平台的设备创建各个上下文),然后利用上下文可以做到:

    a.创建一个或多个命令队列;

    b.创建程序,使它在一个或多个关联设备上运行;

    c.从这些程序创建一个内核;

    d.在宿主机或设备上分配内存缓冲区和图像;

    e.将数据写至或复制到特定设备,或者由设备写数据;

    f.将内核(设置适当的参数)提交到命令队列来执行;

给定一个平台和一组关联设备,可以使用命令clGreateContext()创建一个OpenCL上下文,如果有平台和设备类型,可以使用clCreateContextFromType()创建上下文。

原文地址:https://www.cnblogs.com/tcsong24/p/7642056.html