OpenCL 设备

每个平台可能关联不同的设备,在把内核程序送到OpenCL设备上执行前,编程人员需要指定执行该内核代码的计算设备。

clGetDeviceIDs

OpenCL中设备对象的类型为cl_device_id,我们可以通过以下函数来查询支持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 )

该函数与clGetPlatformIDs函数类似,第一次调用时,devices参数设置为NULL,num_devices返回指定平台中的设备数;

第二次调用时,根据第一次调用得到设备数量分配设备空间,调用该函数来初始化可用设备。

需要注意的是,如果devices不为NULL,num_entries的值必须大于0,num_entries用于指定devices所指向的设备对象列表中最多可存放多少个设备对象,这样此函数所输出的设备对象个数不会超过num_entries的值。而num_devices则输出实际给出的设备对象的个数。

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

cl_uint num_platform;
cl_uint num_device;
cl_platform_id *platform;
cl_device_id *devices;
cl_int err;
err = clGetPlatformIDs(0, 0, &num_platform);
platform = (cl_platform_id *)malloc(sizeof(cl_platform_id) *
                                          num_platform);
err = clGetPlatformIDs(num_platform, platform, NULL);
//获得第一个平台上的设备数量
err = clGetDeviceIDs(platform[0], CL_DEVICE_TYPE_GPU, 0, NULL,
                        &num_device);
devices = (cl_device_id *)malloc(sizeof(cl_device_id) *
                                        num_device);
//初始化可用的设备
err = clGetDeviceIDs(platform[0], CL_DEVICE_TYPE_GPU, num_device,
                        devices, NULL);

在上面的例子中,我们查询第一个平台上GPU类型的可用OpenCL设备数量,并初始化这些设备。

对于上述例子,查询的是GPU类型的OpenCL设备。对于函数中的device_type参数,可用类型如下表所示:

OpenCL设备类型



clGetDeviceInfo

给定一个OpenCL设备后,使用如下函数可以获得设备的各个属性信息:

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 )

这个函数返回给定设备的属性信息。

第一个参数device指定查询的设备。

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

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

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

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

OpenCL设备查询

OpenCL设备查询

OpenCL设备查询

OpenCL设备查询



下面代码清单展示了如何使用clGetDeviceInfo()来查询指定平台上GPU设备的属性信息。

#include 〈stdio.h>
#include 〈stdlib.h>
#ifdef _APPLE_
#include 〈OpenCL/cl.h>
#else
#include 〈CL/cl.h>
#endif
void checkErr(cl_int err, int num)
{
    if(CL_SUCCESS != err)
    {
        printf("OpenCL error(%d) at %d\n", err, num - 1);
    }
}
int main(int argc, char **argv)
{
    cl_device_id *device;
    cl_platform_id platform;
    cl_int err;
    cl_uint NumDevice;
    //选择第一个平台
    err = clGetPlatformIDs(1, &platform, NULL);
    checkErr(err, _LINE_);
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU,
                              0, NULL, &NumDevice);
    checkErr(err, _LINE_);
    device = (cl_device_id *)malloc(sizeof(cl_device_id) *
                                          NumDevice);
    //选择GPU设备
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU,
                              NumDevice, device, NULL);
    checkErr(err, _LINE_);
    for(int i = 0; i 〈 NumDevice; i++)
    {
        //查询设备名称
        char buffer[100];
        err = clGetDeviceInfo(device[i], CL_DEVICE_NAME,
                                    100, buffer, NULL);
        checkErr(err, _LINE_);
        printf("Device Name:%s\n", buffer);
        //查询设备计算单元最大数目
        cl_uint UnitNum;
        err = clGetDeviceInfo(device[i],
                                    CL_DEVICE_MAX_COMPUTE_UNITS,
                                    sizeof(cl_uint), &UnitNum, NULL);
        checkErr(err, _LINE_);
        printf("Compute Units Number: %d\n", UnitNum);
        //查询设备核心频率
        cl_uint frequency;
        err = clGetDeviceInfo(device[i],
                          CL_DEVICE_MAX_CLOCK_FREQUENCY,
                          sizeof(cl_uint), &frequency, NULL);
        checkErr(err, _LINE_);
        printf("Device Frequency: %d(MHz)\n", frequency);
        //查询设备全局内存大小
        cl_ulong GlobalSize;
        err = clGetDeviceInfo(device[i], CL_DEVICE_GLOBAL_MEM_SIZE,
                          sizeof(cl_ulong), &GlobalSize, NULL);
        checkErr(err, _LINE_);
        printf("Device Global Size: %0.0f(MB)\n",
        (float)GlobalSize / 1024 / 1024);
        //查询设备全局内存缓存行
        cl_uint GlobalCacheLine;
        err = clGetDeviceInfo(device[i],
                          CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE,
                          sizeof(cl_uint), &GlobalCacheLine,
                          NULL);
        checkErr(err, _LINE_);
        printf("Device Global CacheLine: %d(Byte)\n",
        GlobalCacheLine);
        //查询设备支持的OpenCL版本
        char DeviceVersion[100];
        err = clGetDeviceInfo(device[i], CL_DEVICE_VERSION,
                          100, DeviceVersion, NULL);
        checkErr(err, _LINE_);
        printf("Device Version:%s\n", DeviceVersion);
        //查询设备拓展名
        char *DeviceExtensions;
        cl_uint ExtenNum;
        err = clGetDeviceInfo(device[i], CL_DEVICE_EXTENSIONS,
                          0, NULL, &ExtenNum);
        checkErr(err, _LINE_);
        DeviceExtensions = (char *)malloc(ExtenNum);
        err = clGetDeviceInfo(device[i], CL_DEVICE_EXTENSIONS,
                          ExtenNum, DeviceExtensions, NULL);
        checkErr(err, _LINE_);
        printf("Device Extensions:%s\n", DeviceExtensions);
        free(DeviceExtensions);
  }
  free(device);
  return 0;
}



在AMD Radeon R9 285设备上,上述代码输出结果如下:

Device Name:Tonga
   Compute Units Number: 28
   Device Frequency: 965(MHz)
   Device Global Size: 2048(MB)
   Device Global CacheLine: 64(Byte)
   Device Version:OpenCL 1.2 AMD-APP (1642.5)
   Device Extensions:cl_khr_fp64 cl_amd_fp64 cl_khr_global_int32_base_atomics cl_
khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_
int32_extended_atomics cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_
khr_3d_image_writes cl_khr_byte_addressable_store cl_khr_gl_sharing cl_ext_atomic_
counters_32 cl_amd_device_attribute_query cl_amd_vec3 cl_amd_printf cl_amd_media_
ops cl_amd_media_ops2 cl_amd_popcnt cl_khr_d3d10_sharing cl_khr_d3d11_sharing cl_
khr_dx9_media_sharing cl_khr_image2d_from_buffer cl_khr_spir cl_khr_gl_event

需要注意的是:查询设备不同的属性信息对应的返回值类型不同。初学者可能对此不太注意,接收返回值的变量与所需类型不一致,造成查询属性信息输出结果不正确。

赞(1)
未经允许不得转载:极客笔记 » OpenCL 设备

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
OpenCL 基本概念
OpenCL 是什么OpenCL 平台模型OpenCL 执行模型OpenCL 上下文简介OpenCL 命令队列简介OpenCL 在设备上执行内核OpenCL 存储器区域OpenCL 存储器对象OpenCL 共享虚拟存储器OpenCL 与OpenGL
OpenCL 基础教程
OpenCL 在Windows上搭建开发环境OpenCL 在Linux上搭建开发环境OpenCL 在OS X上搭建开发环境OpenCL 第一个程序OpenCL 平台OpenCL 设备OpenCL 创建上下文OpenCL 创建命令队列OpenCL 创建Program对象OpenCL 编译Program对象OpenCL 查询和管理Program对象OpenCL 创建内核对象OpenCL 设置内核参数OpenCL 查询和管理内核对象OpenCL 执行内核OpenCL 编写内核代码OpenCL 错误处理
OpenCL C特性
OpenCL 地址空间修饰符OpenCL 函数修饰符OpenCL 对象访问修饰符OpenCL 标量数据类型OpenCL 为什么要有矢量数据类型OpenCL 矢量初始化OpenCL 读取和修改矢量分量OpenCL 运算符OpenCL 维度和工作项OpenCL 工作组OpenCL 矢量数据拷贝OpenCL 异步拷贝和预取OpenCL 数学函数OpenCL 公共函数OpenCL 几何函数OpenCL 整数函数OpenCL 关系函数OpenCL 杂项矢量函数OpenCL 同步函数OpenCL 原子函数OpenCL 内建图像读函数OpenCL 内建无采样器图像读函数OpenCL 内建图像写函数OpenCL 内建图像查询函数OpenCL 工作组函数OpenCL 内建管道读/写函数OpenCL 内建工作组管道读/写函数OpenCL 内建管道查询函数OpenCL 设备队列OpenCL Blocks语法OpenCL 设备队列相关函数OpenCL 子内核存储器可见性OpenCL 设备队列的使用示例
OpenCL 存储器对象
OpenCL 存储器对象OpenCL 分配缓冲区对象OpenCL 创建子缓冲区对象OpenCL 图像对象和采样器对象OpenCL 图像对象OpenCL 图像格式描述符OpenCL 图像描述符OpenCL 图像对象查询OpenCL 采样器对象OpenCL 主机端采样器对象OpenCL 设备端采样器对象OpenCL 图像旋转示例OpenCL 管道OpenCL 创建管道对象OpenCL 管道对象查询OpenCL 主机与设备间数据传输OpenCL 图像对象主机与设备间数据拷贝OpenCL 缓冲区对象数据填充OpenCL 图像对象数据填充OpenCL 缓冲区对象间数据传输OpenCL 图像对象和缓冲区对象间数据拷贝OpenCL 缓冲区对象映射OpenCL 图像对象映射OpenCL 解映射OpenCL 共享虚拟存储器OpenCL SVM缓冲创建与释放OpenCL SVM缓冲映射与解映射OpenCL SVM缓冲填充与拷贝OpenCL SVM类型OpenCL SVM特性OpenCL 共享虚拟存储器示例OpenCL 存储器一致性模型OpenCL 存储器次序规则OpenCL 原子操作的存储器次序规则OpenCL 栅栏操作的存储器次序规则OpenCL 工作组函数的存储器次序规则OpenCL 主机端与设备端命令的存储器次序规则OpenCL 关于存储器次序在实际OpenCL计算设备中的实现
OpenCL 同步及事件机制
OpenCL 同步及事件机制OpenCL 主机端的OpenCL同步OpenCL OpenCL事件机制OpenCL 对OpenCL事件的标记和栅栏OpenCL 内核程序中的同步OpenCL 工作组内同步OpenCL 原子操作OpenCL 1.2中的原子操作OpenCL 2.0中的原子操作OpenCL 局部存储器与全局存储器间的异步拷贝OpenCL 工作组间同步
OpenCL 与OpenGL互操作
OpenCL 与OpenGL互操作OpenCL 从一个OpenGL上下文来创建OpenCL上下文OpenCL 使用OpenGL共享的缓存对象OpenCL 使用OpenGL纹理数据OpenCL 共享OpenGL渲染缓存OpenCL 从一个OpenCL存储器对象查询OpenGL对象信息OpenCL 访问共享对象的OpenCL与OpenGL之间的同步OpenCL AMD Cayman架构GPUOpenCL AMD GCN架构的GPUOpenCL NVIDIA CUDA兼容的GPUOpenCL NVIDIA GPU架构的执行模型OpenCL NVIDIA GPU的全局存储器OpenCL NVIDIA GPU的局部存储器OpenCL ARM Mali GPU硬件架构OpenCL ARM Mali GPU存储器层次OpenCL ARM Mali GPU OpenCL映射