OpenCL 初始化代码[2]

在使用GPU之前,要对GPU进行一些配置,简单记录一下流程。

class gpu
{
public:
	//并行计算内部句柄
	cl_device_id* devices;//设备
	cl_context _context;//上下文
	cl_command_queue _commandQueue;//命令队列
	int dev_id=0;
	int argNum = 0;

	gpu();
	//初始化OpenCL
	cl_int CL_Init(int plat_id);
	//内存申请(数据指针,大小)
	cl_mem gmalloc(void* data, unsigned long size, cl_mem_flags flags);
	//运行
	void run(int dim, gpu_program program, size_t size_xy[2], size_t localWorkSize[2]);

	~gpu();
};

我的目的不单单是写OpenCL程序,我想写一个机器学习的框架(应该是加速工具吧),所以,这里开始就比较模块化了。

其中cl_device_id * devices 是设备指针,理解为指向一个设备,到后面可以了解到具体是神设备,cl_context _context,是设备上下文,应该就是设备的驱动之类的信息。cl_command_queue _commandQueue是命令队列,我们这里使用了通用计算的功能,这个命令队列也就是只接受计算相关指令了,有什么指令直接上传到队列,等待GPU相应。

下面是初始化GPU的步骤,总结一下主要分几个主要步骤

1.先获取指定平台,这个平台就是你电脑里安装的设备,例如是英伟达,AMD,还是核显。

2.在指定平台上获取对应的设备,比如你安装了一个英伟达的显卡,那么这一步你将获取到一个英伟达显卡设备,如果你安装了3块英伟达显卡,这一步你应该能获得三个对应的设备。

3.然后和驱动程序建立好交互。

4.创建 与显卡沟通的通道。

以上四个步骤是我自己理解总结的,可能有不准确的地方。

cl_int gpu::CL_Init(int plat_id)
{
	cl_uint platformNum = 0;
	//获取平台数目,intel,amd,nvidia....
	cl_int status = clGetPlatformIDs(0, NULL, &platformNum);
	if (status != CL_SUCCESS)
		return 1;

	//获取指定平台ID
	cl_platform_id	platform = NULL;
	if (platformNum > 0)
	{
		cl_platform_id* p_id = new cl_platform_id[platformNum];
		memset(p_id, 0, platformNum * sizeof(cl_platform_id));
		//获得平台ID
		clGetPlatformIDs(platformNum, p_id, NULL);
		platform = p_id[plat_id];
		//delete[] p_id;
	}
	if (platform == NULL)
		return 2;

	//获取对应平台GPU数目
	cl_uint deviceNum = 0;
	cl_device_id * device = NULL;
	clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &deviceNum);
	if (deviceNum == 0)
	{
		clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &deviceNum);
		// 为设备分配空间
		device = new cl_device_id[deviceNum];// (cl_device_id*)malloc(deviceNum * sizeof(cl_device_id));
		// 获得设备
		clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, deviceNum, device, NULL);
	}
	else
	{
		device = new cl_device_id[deviceNum];
		clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, deviceNum, device, NULL);
	}

	//创建设备上下文
	cl_context context = clCreateContext(NULL, 1, device, NULL, NULL, NULL);
	if (NULL == context)
		return 3;

	//创建命令队列
	cl_command_queue commandQueue = clCreateCommandQueue(context, device[0], 0, NULL);
	if (NULL == commandQueue)
		return 4;
	//返回重要信息
	devices = device;
	_context = context;
	_commandQueue = commandQueue;
	return 0;
}

有了以上步骤,获得了前面介绍的那三个参数,就可以进行GPU计算 了。

对应的代码

发布了64 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ARTELE/article/details/95376966