【OpenCL】课程笔记

课程链接: https://www.bilibili.com/video/BV1zC4y1s7Ax/?spm_id_from=333.337.search-card.all.click&vd_source=23174149881549c431809ba9bd3acade

OpenCL简介

OpenCL计算架构

在这里插入图片描述

多平台支持
在这里插入图片描述

环境配置

参考:
[1] https://blog.csdn.net/Ciellee/article/details/122379217
也可以使用vcpkg进行opencl环境安装,vcpkg是c++的包管理器,可以方便安装管理c++第三方库

vcpkg install opencv:x64-windows

输出本地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);

	cout << "Platform info: \n";
	// 3. 打印平台信息
	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;
	}
	return 0;
}

这是我的PC输出的结果:

Platform info:
    [0] NVIDIA CUDA
    [1] Intel(R) OpenCL HD Graphics

第2章 主机编程:基本的数据结构

2.1 基本数据类型

  • OpenCL是跨平台的工具包,因而需要一系列同意的基本数据类型作为支撑。
  • 数据类型的声明在 CL/cl_platform.h 中,这些数据只是对c/c++数据类型的再定义而已。
    在这里插入图片描述

2.2 获取平台信息

应用场景举例:

  • 有多个可用的设备,需要指定计算的设备
  • 发布程序时,根据用户的硬件平台,指定设备。
  • 通过 cl_platform_id来对应上述两种情况

2.2.1 创建平台结构

每个 cl_platform_id 对应的是安装在主机上一种不同的OpenCL的具体实现(平台)。
编写平台程序分为两步:

  • 为一个或多个 cl_platform_id 结构分配内存空间
  • 调用 clGetPlatformID来初始化这些数据结构,其函数签名如下:
clGetPlatformIDs(
	cl_uint          num_entries,
    cl_platform_id * platforms,
    cl_uint *        num_platforms);

关于这个函数需要注意三点:

  • 这个函数并不会返回 cl_platform_id, 当成功时返回 0, 返回负数表示检测失败
  • 函数的实际作用是将cl_platform_id 放到platforms指向的内存空间中
  • 把可用的平台数用 num_platforms 保存起来, 反应了平台可用的上限数
  • num_entries 表示想要检测平台的上限数
  • platforms 对象内存地址

使用场景

// 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);

这里调用了两次 clGetPlatformIDs

  • 第一次调用获取到了支持的平台数 num_of_platforms
  • 第二次调用获取到了平台的内存地址,类似handle

2.2.2 获取平台信息

api:

clGetPlatformInfo(cl_platform_id   platform,
                  cl_platform_info param_name,
                  size_t           param_value_size,
                  void *           param_value,
                  size_t *         param_value_size_ret)
  • platform 设备内存地址
  • param_name 平台信息相关参数
    在这里插入图片描述

2.3 访问安装设备

在访问完厂商的平台之后,便可以访问平台相连的各个设备。设备复杂接受来自主机分发的任务和数据。程序中的设备用 cl_device_id 结构来表示。这一节中着重考察两个OpenCL的设备函数。

  • clGetDeviceIDS
  • clGetDeviceInfo

2.3.1 创建设备结构

在向设备发送 kernel 之前,我们需要创建一个 cl_device_id 结构来表示某个设备。可以通过
clGetDeviceIDs 实现。它会将 OpenCL设备所对应的结构保存在 cl_device_id型数组中,其函数签名如下:


猜你喜欢

转载自blog.csdn.net/qq_30340349/article/details/131370312