OpenCL 平台

OpenCL程序的第一步就是选择OpenCL平台。OpenCL平台指的是OpenCL设备和OpenCL框架的组合,不同的OpenCL厂商属于不同的OpenCL平台。一个异构计算机上可以同时存在多个OpenCL平台。

例如,在一个系统中,可能存在NVIDIA GPU、AMD GPU与Intel CPU,多个OpenCL实现并存,对于这种平台有3个不同平台。在OpenCL程序开发中,我们需要显式地指定选择用哪个平台。

对于同一平台上可能关联有不同的设备,如在Qualcomm平台,CPU和Adreno GPU都支持OpenCL,都可以作为OpenCL设备,在这种一个平台中含有多个可用计算设备的环境下,编程人员就需要人为选择使用哪种OpenCL设备。

OpenCL平台

clGetPlatformIDs

OpenCL中,cl_platform_id结构表示了一个不同的OpenCL实现(称为平台),可以使用如下函数查询来获得系统平台列表:

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

在OpenCL程序中,上述函数可以调用两次:

  • 第一次调用,platforms设置为NULL,调用该函数,num_platforms中获得系统中可用的OpenCL平台数量;
  • 第二次调用,根据第一次调用得到平台数量分配平台空间,调用该函数来初始化可用平台。

下面的代码清单用来说明以上操作:

cl_int err;
cl_uint num_platform;
cl_platform_id *platform;
//获得平台数量
err = clGetPlatformIDs(0, NULL, &num_platform);
//分配平台空间
platform = (cl_platform_id *)malloc(sizeof(cl_platform_id) *
                                          num_platform);
//初始化可用平台
err = clGetPlatformIDs(num_platform, platform, NULL);

上述代码查询了系统中所有OpenCL平台,并初始化了查询到的所有平台。回过头看OpenCL 第一个程序中的例子,在这个例子中clGetPaltformIDS只调用了一次,这是为什么呢?这是因为只初始化了第一个可用的OpenCL平台。

需要指出的是,OpenCL API函数执行完成后都会有相应的返回状态,类型为cl_int,如上述例子中定义的err变量,成功执行则返回状态是CL_SUCCESS,失败则返回相应的错误状态。这部分内容将在本章最后讲解,开发人员可以通过返回状态检查函数是否成功执行。

clGetPaltformIDs可以获得平台个数信息,但是却无法知道平台属性信息,如平台名称、平台支持的OpenCL版本、平台供应商等信息。如果需要查询这些信息怎么办呢?OpenCL已经提供这样的函数可供开发人员使用。

clGetPlatformInfo

给定一个平台,使用如下函数可以获得平台的各个属性信息:

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

这个函数返回给定平台的属性信息。

第一个参数platform指定查询的平台。

第二个参数param_name为查询平台的属性信息,param_name的取值如下表所示。

最后一个参数param_value_size_ret返回属性信息实际的长度。

第四个参数param_value为指向保存平台属性信息的指针。

第三个参数param_value_size指定param_value参数指向的内存空间大小,这个值必须大于等于第四个参数的返回值。

OpenCL平台信息参数

  • FULL_PROFILE:OpenCL实现支持OpenCL规范的所有功能;
  • EMBEDDED_PROFILE:OpenCL实现支持OpenCL嵌入式简档,是OpenCL规范的一个子集。

下面的代码来获得指定平台的5个属性信息。

size_t size;
err = clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL,
                            &size);
char *PName = (char *)malloc(size);
err = clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, PName,
                            NULL);
printf("CL_PLATFORM_NAME: % s\n", PName);
err = clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, 0, NULL,
                            &size);
char *PVendor = (char *)malloc(size);
err = clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, size,
                            PVendor, NULL);
printf("CL_PLATFORM_VENDOR: % s\n", PVendor);
err = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL,
                            &size);
char *PVersion = (char *)malloc(size);
err = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size,
                            PVersion, NULL);
printf("CL_PLATFORM_VERSION: % s\n", PVersion);
err = clGetPlatformInfo(platform, CL_PLATFORM_PROFILE, 0, NULL,
                            &size);
char *PProfile = (char *)malloc(size);
err = clGetPlatformInfo(platform, CL_PLATFORM_PROFILE, size,
                            PProfile, NULL);
printf("CL_PLATFORM_PROFILE: % s\n", PProfile);
err = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, 0,
                            NULL, &size);
char *PExten = (char *)malloc(size);
err = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, size,
                            PExten, NULL);
printf("CL_PLATFORM_EXTENSIONS: % s\n", PExten);

针对NVIDIA GPU,上述代码输出为:

  • CL_PLATFORM_NAME:NVIDIA CUDA
  • CL_PLATFORM_VENDOR:NVIDIA Corporation
  • CL_PLATFORM_VERSION:OpenCL 1.1 CUDA 6.0.1
  • CL_PLATFORM_PROFILE:FULL_PROFILE
  • CL_PLATFORM_EXTENSIONS:cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_d3d9_sharing cl_nv_d3d10_sharing cl_khr_d3d10_sharing cl_nv_d3d11_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll

综合clGetPlatformIDs和clGetPlatformInfo两个函数。

下面的代码清单演示了列举系统可用平台,查询输出每个可用平台的属性信息。

#include〈CL/cl.h>
#include〈stdio.h>
#include〈string.h>
#include〈malloc.h>
int main()
{
    cl_platform_id *platform;
    cl_uint num_platform;
    cl_int err;
    err = clGetPlatformIDs(0, NULL, &num_platform);
    platform = (cl_platform_id *)malloc(sizeof(cl_platform_id) *
                                                num_platform);
    err = clGetPlatformIDs(num_platform, platform, NULL);
    for(int i = 0; i 〈 num_platform; i++)
    {
        size_t size;
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_NAME, 0, NULL, &size);
        char *PName = (char *)malloc(size);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_NAME, size,
                                      PName, NULL);
        printf("\nCL_PLATFORM_NAME: % s\n", PName);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_VENDOR,
                                      0, NULL, &size);
        char *PVendor = (char *)malloc(size);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_VENDOR,
                                      size, PVendor, NULL);
        printf("CL_PLATFORM_VENDOR: % s\n", PVendor);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_VERSION,
                                      0, NULL, &size);
        char *PVersion = (char *)malloc(size);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_VERSION,
                                      size, PVersion, NULL);
        printf("CL_PLATFORM_VERSION: % s\n", PVersion);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_PROFILE, 0,
                                      NULL, &size);
        char *PProfile = (char *)malloc(size);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_PROFILE,
                                      size, PProfile, NULL);
        printf("CL_PLATFORM_PROFILE: % s\n", PProfile);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_EXTENSIONS,
                                      0, NULL, &size);
        char *PExten = (char *)malloc(size);
        err = clGetPlatformInfo(platform[i], CL_PLATFORM_EXTENSIONS,
                            size, PExten, NULL);
        printf("CL_PLATFORM_EXTENSIONS: % s\n", PExten);
        free(PName);
        free(PVendor);
        free(PVersion);
        free(PProfile);
        free(PExten);
}
}

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程