OpenCL设备查询

#注释都在代码里

#include<iostream>
#include<CL/cl.h>
using namespace std;

void displayDeviceDetails(cl_device_id id, cl_device_info param_name,
	const char* paramnamestr);

void displayDeviceinfo(cl_platform_id id, cl_device_type dev_type)
{
	cl_int error = 0;
	cl_uint numofdevice = 0;

	/*平台关联多少设备,id应该提前初始化*/
	error = clGetDeviceIDs(id, dev_type, 0, nullptr, &numofdevice);
	if (error != CL_SUCCESS)
	{
		perror("Unable to obtain any opencl compliant device info");
		exit(1);
	}

	cl_device_id* devices = new cl_device_id[sizeof(cl_device_id) * numofdevice];
	//初始化/load info about device
	error = clGetDeviceIDs(id, dev_type, numofdevice, devices, nullptr);
	if (error != CL_SUCCESS)
	{
		perror("Unable to obtain any opencl compliant device info");
		exit(1);
	}

	cout <<"    " << "numofdevice " << numofdevice << endl;

	for (int i = 0; i < numofdevice; i++)
	{
		displayDeviceDetails(devices[i], CL_DEVICE_TYPE/*deviceinfo枚举类型*/, "CL_DEVICE_TYPE");
		displayDeviceDetails(devices[i], CL_DEVICE_VENDOR, "CL_DEVICE_VENDOR");//CL_DEVICE_VENDOR 用于获取表示设备供应商的字符串。
		displayDeviceDetails(devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, "CL_DEVICE_MAX_COMPUTE_UNITS");
		displayDeviceDetails(devices[i], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS");
		displayDeviceDetails(devices[i], CL_DEVICE_MAX_WORK_ITEM_SIZES, "CL_DEVICE_MAX_WORK_ITEM_SIZES");
		displayDeviceDetails(devices[i], CL_DEVICE_MAX_WORK_GROUP_SIZE, "CL_DEVICE_MAX_WORK_GROUP_SIZE");

	}

}

void displayDeviceDetails(cl_device_id id, cl_device_info param_name,
	const char* paramnamestr)
{
	cl_int error = 0;
	size_t paramsize = 0;
	//获取平台设备数
	error = clGetDeviceInfo(id, param_name, 0/*自定义大小:表示自己希望用于存储*/, nullptr/*存储结果的设备指针*/, &paramsize/*指针指向的空间大小*/);
	/*
device:要查询信息的 OpenCL 设备。
param_name:要查询的设备信息的参数名称,它是 cl_device_info 枚举类型的一个成员,用于指定查询的信息类型。例如,可以查询设备的供应商信息、设备类型、最大工作组大小等等。
param_value_size:param_value 缓冲区的大小(以字节为单位)。这表示用于存储查询结果的缓冲区的大小。如果 param_value 为 nullptr,则可以将 param_value_size 设置为 0,此时函数将忽略 param_value 参数,仅返回信息的大小。
param_value:用于存储查询结果的缓冲区指针。这是一个指向内存的指针,用于存储查询的信息。缓冲区的大小由 param_value_size 参数指定。
param_value_size_ret:用于返回实际查询结果的大小。这是一个 size_t 类型的指针。如果不需要知道实际的查询结果大小,可以将该参数设置为 nullptr。*/
	if (error != CL_SUCCESS)
	{
		perror("unable to obtain device info");
		exit(1);
	}
	/*the device info are preprocessor directives defined in cl.h*/
	switch(param_name)
	{
		cout <<"        " << paramnamestr << "  ";
	case CL_DEVICE_TYPE:
	{
		cl_device_type* dev_type = new cl_device_type[sizeof(cl_device_type) * paramsize];
		error = clGetDeviceInfo(id, param_name, paramsize, dev_type, nullptr);
		if (error != CL_SUCCESS)
		{
			perror("unable to obtain device info");
			exit(1);
		}

		switch (*dev_type)
		{
		case CL_DEVICE_TYPE_CPU:
		{
			cout << "    CPU detected" << endl;
			break;
		}
		case CL_DEVICE_TYPE_GPU:
		{
			cout << "    GPU detected" << endl;
			break;
		}
		case CL_DEVICE_TYPE_DEFAULT:
		{
			cout << "    default detected" << endl;
			break;
		}
		}
		break;
	}
	case CL_DEVICE_VENDOR:
	{
		char vendor_name[1024] = { 0 }; // 存储供应商信息的字符串
		size_t vendor_name_size=0; // 供应商信息字符串的大小
		// 获取供应商信息字符串的大小
		clGetDeviceInfo(id, CL_DEVICE_VENDOR, sizeof(vendor_name), nullptr, &vendor_name_size);

		// 获取供应商信息字符串
		clGetDeviceInfo(id, CL_DEVICE_VENDOR, vendor_name_size, vendor_name, nullptr);

		// 输出供应商信息
		std::cout << "    Device Vendor: " << vendor_name << std::endl;
		break;
	}

	case CL_DEVICE_MAX_COMPUTE_UNITS:
	{
		cl_uint max_compute_units; // 存储最大计算单元数的变量
		// 获取设备的最大计算单元数
		clGetDeviceInfo(id, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &max_compute_units, nullptr);
		// 输出最大计算单元数
		std::cout << "    Max Compute Units: " << max_compute_units << std::endl;
		break;
	}

	case CL_DEVICE_MAX_WORK_GROUP_SIZE:
	{
		cl_uint max_work_group_zise = 0;
		size_t max;
		clGetDeviceInfo(id, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(cl_uint), &max_work_group_zise, &max);
		std::cout << "    Max Work Group Size: " << max_work_group_zise <<"   " << max << endl;
		break;
	}
	case CL_DEVICE_MAX_WORK_ITEM_SIZES:
	{
		cl_uint max_work_item_zise = 0;
		clGetDeviceInfo(id, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(cl_uint), &max_work_item_zise, nullptr);
		std::cout << "    Max Work Item Sizes : " << max_work_item_zise << endl;
		break;
	}
	case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
	{
		cl_uint max_work_item_dimensions; // 存储最大工作项维度数量的变量

		// 获取设备支持的最大工作项维度数量
		clGetDeviceInfo(id, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(cl_uint), &max_work_item_dimensions, nullptr);

		// 输出最大工作项维度数量
		std::cout << "    Max Work Item Dimensions: " << max_work_item_dimensions << std::endl;

		break;
	}
	break;
	}
}

int main()
{
	cl_int error = 0;
	cl_platform_id* id;
	cl_device_type* dev;
	cl_uint numofplatform = 0;
	error = clGetPlatformIDs(0, nullptr, &numofplatform);//获取平台数
	if (error!= CL_SUCCESS)
	{
		perror("unable to obtain the platform");
		return 1;
	}
	dev = new cl_device_type[5];
	/*cl_device_type系列*/
	dev[0] = CL_DEVICE_TYPE_CPU;//cpu 设备
	dev[1] = CL_DEVICE_TYPE_GPU;//gpu 设备
	dev[2] = CL_DEVICE_TYPE_DEFAULT;//默认设备
	dev[3] = CL_DEVICE_TYPE_ALL;//所有可用设备
	dev[4] = CL_DEVICE_TYPE_ACCELERATOR;//加速设备
	
	id = new cl_platform_id[numofplatform * sizeof(cl_platform_id)];
	error = clGetPlatformIDs(numofplatform, id, nullptr);//初始化设备id
	/*num_entries:用于指定 platforms 数组的大小,即你期望能够获取多少个平台。
	如果 platforms 不为 nullptr,则 num_entries 表示 platforms 数组的大小。
	如果 platforms 为 nullptr,则 num_entries 可以设置为 0,此时函数将忽略 platforms 参数,并仅返回平台数量。
	platforms:用于存储获取到的平台列表。platforms 是一个 cl_platform_id 类型的指针数组,通过此参数,函数将获取到的平台列表存储在 platforms 数组中。
	num_platforms:用于存储获取到的平台数量。它是一个 cl_uint 类型的指针,通过此参数,函数将返回获取到的平台数量。*/
	if (error != CL_SUCCESS)
	{
		perror("unable to obtain the platform");
		return 1;
	}
	cout << "ableable platforms: " << numofplatform << endl;
	for (int i = 0; i < numofplatform; i++)
	{
		cout << "platform:  " << i << endl;
		displayDeviceinfo(id[i], dev[1]);
		//displayDeviceinfo(id[i], dev[0]);
	}
	delete[] id;
	delete[] dev;
	return 0;
}

/*OpenCL平台-->OpenCL设备-->context上下文-->命令队列-->工作组-->工作项(kernel)*/

初出茅庐,有误海涵

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值