当前位置: 首页 > article >正文

OpenCL 学习(2)---- OpenCL Platform 和 Device

目录

        • OpenCL Platform
        • OpenCL Device
        • 参考代码

OpenCL Platform

opencl 支持的 Platform 可以使用 clGetPlatformIDs 函数查询,函数原型如下:

clGetPlatformIDs(cl_uint          /* num_entries */,
                 cl_platform_id * /* platforms */,
                 cl_uint *        /* num_platforms */);

如果将platforms参数设置为nullptrnum_platforms会返回当前平台上可用的platform数量
一般将 num_entriesplatforms 设置为 0 和 nullptr 来查询可用的platform数量

在得到当前支持platform 的前提下,设置 num_entriesplatforms 就可以获取到所有的 platfromID,参考代码如下:

	std::vector<cl_platform_id> clplatform;
	cl_uint num_platform;

	err = clGetPlatformIDs(0, nullptr, &num_platform);
	std::cout << "number of platforms: " << num_platform << std::endl;
	clplatform.resize(num_platform);
	err = clGetPlatformIDs(num_platform, clplatform.data(), NULL);

获取到 platfromID 之后,可以使用 clGetPlatformInfo 获取平台的信息,其原型如下:

clGetPlatformInfo(cl_platform_id   /* platform */, 
                  cl_platform_info /* param_name */,
                  size_t           /* param_value_size */, 
                  void *           /* param_value */,
                  size_t *         /* param_value_size_ret */);
  • cl_platform_id 前面获取的的 platformId
  • cl_platform_info 设置需要获取到的 platformInfo
  • param_value_size 对应的 param_value 的字符串大小
  • param_value 对应的 param_value 的字符串指针
  • 返回获取的 param_value_size

一般先将param_value_sizeparam_value设置为 0 和nullptr,返回param_valuesize大小,
然后使用获取到的size 传递给param_value_size,得到对应的param_value

对于不同的platformInfo信息,含义如下:

platformInfo返回类型说明
CL_PLATFORM_PROFILEchar[]FULL_PROFILE 或者 EMBEDDED_PROFILE
CL_PLATFORM_VERSIONchar[]opencl 版本
CL_PLATFORM_NAMEchar[]平台名称
CL_PLATFORM_VENDORchar[]平台厂商
CL_PLATFORM_EXTENSIONSchar[]平台支持扩展名

FULL_PROFILE:支持定位为核心规范的所有功能
EMBEDDED_PROFILE: 支持定位为核心规范的所有功能的一个子集

OpenCL Device

每个平台可能关联到一组计算设备,应用程序通过这些计算设备执行内核程序,使用
clGetDeviceIDs 查询支持的设备列表

extern CL_API_ENTRY cl_int CL_API_CALL
clGetDeviceIDs(cl_platform_id   /* platform */,
               cl_device_type   /* device_type */, 
               cl_uint          /* num_entries */, 
               cl_device_id *   /* devices */, 
               cl_uint *        /* num_devices */) CL_API_SUFFIX__VERSION_1_0;

这个函数会得到于 platformID 关联的所有的 OpenCL 设备列表,如果参数 devices 设置为 null,clGetDeviceIDs 会返回设备数,返回的设备数可以用 num_entries来限制(0 < num_entries <= 设备数)

其中的 cl_device_type 可以是下表中的一个值:

cl_device_type描述
CL_DEVICE_TYPE_CPU作为宿主机处理器的 OpenCL 设备
CL_DEVICE_TYPE_GPU作为 GPU 的 OpenCL 设备
CL_DEVICE_TYPE_ACCELERATOROpenCL 加速器
CL_DEVICE_TYPE_ALL和平台关联的所有 OpenCL 设备

给定一个设备,可以使用下面函数查询各种属性:

extern CL_API_ENTRY cl_int CL_API_CALL
clGetDeviceInfo(cl_device_id    /* device */,
                cl_device_info  /* param_name */, 
                size_t          /* param_value_size */, 
                void *          /* param_value */,
                size_t *        /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;

可以将param_value_sizeparam_value设置为 0 和 nullptr 来查询返回值的大小

具体可以查询的 Device 属性如下图所示:
OpenCL device

参考代码

获取 platform 和 device 属性的参考代码如下:

void getCLPlatformInfo() {
	cl_int err;
	//cl_platform_id* platform;
	std::vector<cl_platform_id> clplatform;
	cl_uint num_platform;

	std::vector<cl_device_id> cldevice;
	cl_uint num_device;

	err = clGetPlatformIDs(0, nullptr, &num_platform);
	std::cout << "number of platforms: " << num_platform << std::endl;
	clplatform.resize(num_platform);
	err = clGetPlatformIDs(num_platform, clplatform.data(), NULL);

	for (auto& platform : clplatform) {
		size_t size;
		err = clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
		cl_char* PName = new cl_char[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);
		cl_char* PVendor = new cl_char[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);
		cl_char* PVersion = new cl_char[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);
		cl_char* PProfile = new cl_char[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);
		cl_char* PExten = new cl_char[size];
		err = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, size, PExten, NULL);
		printf("CL_PLATFORM_EXTENSIONS: %s\n", PExten);

		delete[] PName;
		delete[] PVendor;
		delete[] PVersion;
		delete[] PProfile;
		delete[] PExten;
	}
	std::cout << "\n=======================================================\n" << std::endl;
	for (auto& platform : clplatform) {
		size_t size;
		err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, nullptr, &num_device);
		std::cout << "num of device:" << num_device << std::endl;
		cldevice.resize(num_device);
		err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, num_device, cldevice.data(), nullptr);
		for (auto& device : cldevice) {
			// deviceName
			err = clGetDeviceInfo(device, CL_DEVICE_NAME, 0, nullptr, &size);
			cl_char* PDeviceName = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DEVICE_NAME, size, PDeviceName, nullptr);
			std::cout << "PDeviceName:" << PDeviceName << std::endl;
			// device vendor
			err = clGetDeviceInfo(device, CL_DEVICE_VENDOR, 0, nullptr, &size);
			cl_char* PDeviceVendor = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DEVICE_VENDOR, size, PDeviceVendor, nullptr);
			std::cout << "PDeviceVendor:" << PDeviceVendor << std::endl;
			// driver version
			err = clGetDeviceInfo(device, CL_DRIVER_VERSION, 0, nullptr, &size);
			cl_char* PDriverVersion = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DRIVER_VERSION, size, PDriverVersion, nullptr);
			std::cout << "PDriverVersion:" << PDriverVersion << std::endl;
			// device profile
			err = clGetDeviceInfo(device, CL_DEVICE_PROFILE, 0, nullptr, &size);
			cl_char* PProfile = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DEVICE_PROFILE, size, PProfile, nullptr);
			std::cout << "PProfile:" << PProfile << std::endl;
			// device version
			err = clGetDeviceInfo(device, CL_DEVICE_VERSION, 0, nullptr, &size);
			cl_char* PDeviceVersion = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DEVICE_VERSION, size, PDeviceVersion, nullptr);
			std::cout << "PDeviceVersion:" << PDeviceVersion << std::endl;
			// device opencl c version
			err = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, 0, nullptr, &size);
			cl_char* POpenCLCVersion = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, size, POpenCLCVersion, nullptr);
			std::cout << "POpenCLCVersion:" << POpenCLCVersion << std::endl;
			// device extension
			err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, 0, nullptr, &size);
			cl_char* PDeviceExtensions = new cl_char[size];
			err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, size, PDeviceExtensions, nullptr);
			std::cout << "PDeviceExtensions:" << PDeviceExtensions << std::endl;

			// 最大计算单元数
			cl_uint UnitNum;
			err = clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &UnitNum, nullptr);
			std::cout << "Max ComputeUnit Number:" << UnitNum << std::endl;

			// 最高核心频率
			cl_uint frequency;
			err = clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(cl_uint), &frequency, nullptr);
			std::cout << "Max clock frequency:" << frequency << std::endl;

			// 查询设备全局内存大小
			cl_ulong GlobalSize;
			err = clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &GlobalSize, nullptr);
			std::cout << "GlobalSize Uniform Memory Size(B):" << GlobalSize << std::endl;

			// 查询设备全局内存缓存行
			cl_uint GlobalCacheLine;
			err = clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, sizeof(cl_uint), &GlobalCacheLine, nullptr);
			std::cout << "Device Global CacheLine(B):" << GlobalCacheLine << std::endl;

			delete[] PDeviceName;
			delete[] PDeviceVendor;
			delete[] PDriverVersion;
			delete[] PProfile;
			delete[] PDeviceVersion;
			delete[] POpenCLCVersion;
			delete[] PDeviceExtensions;
		}
	}

}

在我的 Ryen5 集成 Radeon Graphics Vega 8 集成显卡的笔记本得到的结果如下:

CL_PLATFORM_PROFILE: FULL_PROFILE
CL_PLATFORM_EXTENSIONS: cl_khr_icd cl_khr_d3d10_sharing cl_khr_d3d11_sharing cl_khr_dx9_media_sharing cl_amd_event_callback cl_amd_offline_devices
=======================================================
num of device:1
PDeviceName:gfx902
PDeviceVendor:Advanced Micro Devices, Inc.
PDriverVersion:3570.0 (PAL,HSAIL)
PProfile:FULL_PROFILE
PDeviceVersion:OpenCL 2.0 AMD-APP (3570.0)
POpenCLCVersion:OpenCL C 2.0
PDeviceExtensions: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_fp16 cl_khr_gl_sharing 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_subgroups cl_khr_gl_event cl_khr_depth_images cl_khr_mipmap_image cl_khr_mipmap_image_writes cl_amd_copy_buffer_p2p cl_amd_planar_yuv
Max ComputeUnit Number:8
Max clock frequency:1201
GlobalSize Uniform Memory Size(B):7534542848
Device Global CacheLine(B):64

http://www.kler.cn/a/315157.html

相关文章:

  • 编写红绿起爆线指标(附带源码下载)
  • 32位、64位、x86与x64:深入解析计算机架构
  • 【计算机网络】【网络层】【习题】
  • 每日一练:二分查找-搜索插入位置
  • request爬虫库的小坑
  • MYSQL 库,表 基本操作
  • Linux进阶命令-rsync daemon
  • Java :数组array和 Arrays
  • Phoenix使用
  • Zookeeper安装使用教程
  • 爬虫技术抓取网站数据
  • C++进阶|多态知识点详解及经典面试题总结
  • 字节跳动冯佳时:大语言模型在计算机视觉领域的应用、问题和我们的解法
  • java实现系统文件管理
  • 如何在自动化测试中应用装饰器、多线程优化自动化架构?
  • ConflictingBeanDefinitionException | 运行SpringBoot项目时报错bean定义冲突解决方案
  • 音视频入门基础:AAC专题(5)——FFmpeg源码中,判断某文件是否为AAC裸流文件的实现
  • OpenCore Legacy Patcher 2.0.0 发布,83 款不受支持的 Mac 机型将能运行最新的 macOS Sequoia
  • 【Web】御网杯信息安全大赛2024 wp(全)
  • 如何在堆和栈上分别创建一个`QObject`子类对象
  • 走在时代前沿:让ChatGPT成为你的职场超级助手
  • 环形链表问题——力扣141,142
  • Facebook运营:账号类型有哪些?有必要用静态住宅IP吗?
  • 快速理解MySQL索引:优化查询性能的利器
  • 动手深度学习 线性回归从零开始实现实例
  • 招商银行招行笔试难度递增?要点解读