0
点赞
收藏
分享

微信扫一扫

【OpenCL开发入门】02 - 获取当前设备所有OpenCL的信息

雅典娜的棒槌 2022-01-08 阅读 30

【OpenCL开发入门】02 - 获取当前设备所有OpenCL的信息

本章只是OpenCL的入门代码,我们先来获取获取当前设备所有支持OpenCL的平台下的所有设备的信息。
代码中配有详细注释,就不额外单独写代码解读了。

一、未封装前的代码

#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cassert>

#include <CL/cl.h>

using namespace std;

// 检查返回值错误
#define CHECK_ERRORS(ERR) \
	if(ERR != CL_SUCCESS){ \
		cerr << "OpenCL error code" << ERR << "file: " << __FILE__  << "line: " << __LINE__ << ".\nExiting..." << endl; \
		exit(1); \
	}

int main(int argc, const char** argv)
{
	cl_int err = CL_SUCCESS;

	// 1. 获取当前设备所有支持OpenCL的平台的数量
	cl_uint num_of_platforms = 0;
	err = clGetPlatformIDs(0, 0, &num_of_platforms);
	CHECK_ERRORS(err);

	// 2. 获取当前设备所有支持OpenCL的平台的信息
	cl_platform_id* platforms = new cl_platform_id[num_of_platforms];
	err = clGetPlatformIDs(num_of_platforms, platforms, 0);
	CHECK_ERRORS(err);

	cl_char platform_names[10][50];
	// 3. 打印平台信息
	cout << "平台信息:\n";
	for (cl_uint i = 0; i < num_of_platforms; i++)
	{
		// 获取平台字符串的长度
		size_t platform_name_length = 0;
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 0, 0, &platform_name_length);
		CHECK_ERRORS(err);

		// 获取平台字符串
		char* platform_name = new char[platform_name_length];
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, platform_name_length, platform_name, 0);
		CHECK_ERRORS(err);

		cout << "    [" << i << "] " << platform_name << endl;

		// 备份platform name
		if (i < 10) {
			memset(platform_names[i], 0, 50);
			memcpy(platform_names[i], platform_name, platform_name_length);
		}

		delete[] platform_name;
	}

	// 4. 查询各平台设备数量
	struct {
		cl_device_type type;
		const  char* name;
		cl_uint count;
	}devices[] = {
		{CL_DEVICE_TYPE_GPU, "CL_DEVICE_TYPE_GPU", 0},					// GPU
		{CL_DEVICE_TYPE_CPU, "CL_DEVICE_TYPE_CPU", 0},					// CPU
		{CL_DEVICE_TYPE_ACCELERATOR, "CL_DEVICE_TYPE_ACCELERATOR", 0}	// 加速器
	};

	// 5. 遍历查询各个平台下拥有的设备数量
	for (cl_int j = 0; j < num_of_platforms; j++) {
		cl_platform_id platform = platforms[j];
		cout << "\nplatform:" << platform_names[j] << endl;

		// 6. 遍历查询GPU、CPU、ACCELERATOR设备的数量
		for (cl_int i = 0; i < (sizeof(devices) / sizeof(devices[0])); i++)
		{
			err = clGetDeviceIDs(platform, devices[i].type, 0, 0, &devices[i].count);
			if (err == CL_DEVICE_NOT_FOUND) {
				devices[i].count = 0;
				err = CL_SUCCESS;
			}
			CHECK_ERRORS(err);

			cout << "\tdevices:" << devices[i].name
				<< "\tcount:" << devices[i].count;

			if (devices[i].count != 0) {
				// 7. 遍历查询GPU、CPU、ACCELERATOR 所有设备的信息
				cl_device_id* device = new cl_device_id[devices[i].count];
				err = clGetDeviceIDs(platform, devices[i].type, devices[i].count, device, 0);

				cout << "\t\tdevice name:";
				for (cl_int k = 0; k < devices[i].count; k++)
				{
					// 8. 获取和打印各个设备的name
					size_t length = 0;
					cl_device_id each_device = device[k];
					err = clGetDeviceInfo(each_device, CL_DEVICE_NAME, 0, 0, &length);
					CHECK_ERRORS(err);

					char* value = new char[length];
					err = clGetDeviceInfo(each_device, CL_DEVICE_NAME, length, value, 0);
					CHECK_ERRORS(err);
					cout << value << " ";

					// 9. 获取和打印各个设备的version
					err = clGetDeviceInfo(each_device, CL_DEVICE_VERSION, 0, 0, &length);
					CHECK_ERRORS(err);

					char* version = new char[length];
					err = clGetDeviceInfo(each_device, CL_DEVICE_VERSION, length, version, 0);
					CHECK_ERRORS(err);
					cout << version << " ";

					delete[] value;
					delete[] version;
				}

				delete[] device;
			}
			cout << endl;
		}
	}

	delete[] platforms;

	return 0;
}

运行结果如下:
在这里插入图片描述


二、封装后的代码

C:\Program Files (x86)\Intel\oneAPI\compiler\2022.0.0\windows\lib\oclfpga\host\include\CL\cl.h 头文件中定义了很多设备信息类型,当我们需要获取很多信息的时候,就需要写很多调用 clGetDeviceInfo() 函数的代码,其实这些代码都是可以折叠在一起的,我们用宏控来对它进行封装下:


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cassert>

#include <CL/cl.h>

using namespace std;

// 检查返回值错误
#define CHECK_ERRORS(ERR) \
	if(ERR != CL_SUCCESS){ \
		cerr << "OpenCL error code" << ERR << "file: " << __FILE__  << "line: " << __LINE__ << ".\nExiting..." << endl; \
		exit(1); \
	}


// 获取设备数量信息
#define GET_DEVICE_NUM_INFO(DEV_ID, DEV_INFO, TYPE)					\
	{																\
		cout << "\t\t\t";											\
		TYPE value; 												\
		size_t length = 0;											\
		err = clGetDeviceInfo(DEV_ID, DEV_INFO, sizeof(value), &value, &length);\
		CHECK_ERRORS(err);											\
		cout << #DEV_INFO  <<  ": " << value <<endl;				\
	}

// 获取设备文本信息
#define GET_DEVICE_TEXT_INFO(DEV_ID, DEV_INFO)					\
	{															\
		cout << "\t\t\t";										\
		size_t length = 0;											\
		err = clGetDeviceInfo(DEV_ID, DEV_INFO, 0, 0, &length);		\
		CHECK_ERRORS(err);											\
		char* value = new char[length];								\
		err = clGetDeviceInfo(DEV_ID, DEV_INFO, length, value, 0);	\
		CHECK_ERRORS(err);											\
		cout << #DEV_INFO  <<  ": " << value <<endl;				\
		delete[] value;												\
	}


int main(int argc, const char** argv)
{
	cl_int err = CL_SUCCESS;

	// 1. 获取当前设备所有支持OpenCL的平台的数量
	cl_uint num_of_platforms = 0;
	err = clGetPlatformIDs(0, 0, &num_of_platforms);
	CHECK_ERRORS(err);

	// 2. 获取当前设备所有支持OpenCL的平台的信息
	cl_platform_id* platforms = new cl_platform_id[num_of_platforms];
	err = clGetPlatformIDs(num_of_platforms, platforms, 0);
	CHECK_ERRORS(err);

	cl_char platform_names[10][50];
	// 3. 打印平台信息
	cout << "平台信息:\n";
	for (cl_uint i = 0; i < num_of_platforms; i++)
	{
		// 获取平台字符串的长度
		size_t platform_name_length = 0;
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 0, 0, &platform_name_length);
		CHECK_ERRORS(err);

		// 获取平台字符串
		char* platform_name = new char[platform_name_length];
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, platform_name_length, platform_name, 0);
		CHECK_ERRORS(err);

		cout << "    [" << i << "] " << platform_name << endl;

		// 备份platform name
		if (i < 10) {
			memset(platform_names[i], 0, 50);
			memcpy(platform_names[i], platform_name, platform_name_length);
		}

		delete[] platform_name;
	}

	// 4. 查询各平台设备数量
	struct {
		cl_device_type type;
		const  char* name;
		cl_uint count;
	}devices[] = {
		{CL_DEVICE_TYPE_GPU, "CL_DEVICE_TYPE_GPU", 0},					// GPU
		{CL_DEVICE_TYPE_CPU, "CL_DEVICE_TYPE_CPU", 0},					// CPU
		{CL_DEVICE_TYPE_ACCELERATOR, "CL_DEVICE_TYPE_ACCELERATOR", 0}	// 加速器
	};

	// 5. 遍历查询各个平台下拥有的设备数量
	for (cl_int j = 0; j < num_of_platforms; j++) {
		cl_platform_id platform = platforms[j];
		cout << "\n " << j << ": platform:" << platform_names[j] << endl;

		// 6. 遍历查询GPU、CPU、ACCELERATOR设备的数量
		for (cl_int i = 0; i < (sizeof(devices) / sizeof(devices[0])); i++)
		{
			err = clGetDeviceIDs(platform, devices[i].type, 0, 0, &devices[i].count);
			if (err == CL_DEVICE_NOT_FOUND) {
				devices[i].count = 0;
				err = CL_SUCCESS;
			}
			CHECK_ERRORS(err);

			cout << "\t (" << i << "): devices:" << devices[i].name
				<< "\tcount:" << devices[i].count  << endl;

			if (devices[i].count != 0) {
				// 7. 遍历查询GPU、CPU、ACCELERATOR 所有设备的信息
				cl_device_id* device = new cl_device_id[devices[i].count];
				err = clGetDeviceIDs(platform, devices[i].type, devices[i].count, device, 0);

				for (cl_int k = 0; k < devices[i].count; k++)
				{
					// 8. 获取和打印各个设备的信息
					size_t length = 0;
					cl_device_id each_device = device[k];

					GET_DEVICE_TEXT_INFO(each_device, CL_DEVICE_NAME);
					GET_DEVICE_TEXT_INFO(each_device, CL_DEVICE_VENDOR);
					GET_DEVICE_TEXT_INFO(each_device, CL_DRIVER_VERSION);
					GET_DEVICE_TEXT_INFO(each_device, CL_DEVICE_VERSION);

					GET_DEVICE_NUM_INFO(each_device, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
					GET_DEVICE_NUM_INFO(each_device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint);
					GET_DEVICE_NUM_INFO(each_device, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
					GET_DEVICE_NUM_INFO(each_device, CL_DEVICE_IMAGE_SUPPORT, cl_uint);
					GET_DEVICE_NUM_INFO(each_device, CL_DEVICE_AVAILABLE, cl_uint);
				}

				delete[] device;
			}
			cout << endl;
		}
	}

	delete[] platforms;

	return 0;
}

运行结果如下:

在这里插入图片描述

举报

相关推荐

0 条评论