clGetPlatformIDs error -1001和OpenCL、CUDA安装


目录

一、问题描述

二、Ubuntu系统配置Intel OpenCL环境

2.1 安装OpenCL Graphic Technology Runtime & Drivers

2.2 安装OpenCL SDK(可选)

三、Intel官网samples

四、Intel OpenCL简述

4.1 CPU作为OpenCL的目标设备

4.2 GPU作为OpenCL的目标设备

五、OpenCL资源

六、OpenCL在不同平台实现支持

七、Ubuntu系统配置NVIDIA CUDA环境

7.1 安装NVIDIA显卡驱动

7.2 下载和安装CUDA


一、问题描述

在Ubuntu18.04运行OpenCL程序时函数接口 clGetPlatformIDs() 返回“-1001”,对应状态宏CL_PLATFORM_NOT_FOUND_KHR,安装clinfo查看支持OpenCL的设备,也是显示“Number of platforms 0

 (1)安装clinfo

sudo apt install clinfo     //据说qualcomm的CL驱动clinfo无法解析(在QRB5165实测确实如此)

安装后会在目录 /usr/lib/x86_64-linux-gnu/ 里面创建1.0版本的库 libOpenCL.so.1.0.0

 (2)终端执行clinfo

Number of platforms     0

为此百度谷歌了很多方法,比如:

sudo apt install mesa-opencl-icd //Clover(mesa)

sudo apt-get install beignet //Intel Gen OCL Driver

sudo apt install opencl-headers ocl-icd-dev ocl-icd-opencl-dev

虽然把“Number of platforms 0”变成了“Number of platforms 1”甚至“Number of platforms 2”,但却又出现“Number of devices 0”,也就是程序运行时 clGetDeviceIDs() 返回“-1

最终几经折腾,还是把问题解决了,不堪回首之前将各种平台混用,究其原因在于不熟悉该领域。为了让其他刚涉及该领域的开发者少走弯路,故撰写此文。

笔者两台PC系统环境分别如下图所示(右图PC带独显,原始默认显卡也是左图Intel集显。如果不是Intel显卡,本文前面六章节不一定适合读者):

  

   

二、Ubuntu系统配置Intel OpenCL环境

需安装两部分:

        OpenCL Graphic Runtime & Drivers

        OpenCL SDK(可选)

2.1 安装OpenCL Graphic Technology Runtime & Drivers

去Intel官网下载,地址如下:

OpenCL™ Runtimes for Intel® Processors

法一:Repository Install Guidance *Easy*

该方式执行以下三条指令即可:

sudo add-apt-repository ppa:intel-opencl/intel-opencl
sudo apt update
sudo apt install intel-opencl-icd   //通过 dpkg -s intel-opencl-icd 可查看已安装包信息

进入路径参考如下图所示:

   

法二:Manual Download and Install

进入手动下载和安装页面后,选一个版本并按照安装过程执行即可。(注意:一定要选择安装环境与PC系统一致的版本,否则将出现组件版本不一致而导致dpkg存在依赖关系不能解决而使得配置流程终止

  

然后执行clinfo若能够找到下图所示信息,证明安装一切顺利。

  

进行到此还不够,因为编译应用程序时可能会报error提示缺少所依赖的OpenCL头文件和库。对此有两种解决措施:

(1)措施一:到Khronos官网下载源码编译安装

具体过程可阅读目录中的README.md文件,或者参照博友文章:OpenCL Installable Client Driver (ICD) Loader编译_10km的专栏-CSDN博客

(2) 措施二:安装 Intel OpenCL SDK,本文2.2节

  

2.2 安装OpenCL SDK(可选)

OpenCL的SDK分为下图三层结构,即:开发调试和分析工具、应用程序所依赖的头文件和库、CPU Runtime (使用多核心CPU模拟GPU工况,不需要实际的GPU硬件支持。代码中将cl_device_type对象设置为CL_DEVICE_TYPE_CPU即可选择该模式)

去Intel官网下载,地址如下(选择Linux):

Choose & Download Intel® SDK for OpenCL™ Applications

然后执行脚本并按照安装界面操作即可(安装方式和路径详见解压包中的README.txt):

sudo ./install.sh

  

此时再次执行clinfo,若显示的是 2 platforms + 2 devices,证明安装一切顺利。

  

附博友OpenVINO配置:

openVINO在Ubuntu18.04上使用GPU的一个问题?[CLDNN ERROR]. clGetPlatformIDs error -1001_我爱加菲猫-CSDN博客

  

三、Intel官网samples

去Intel官网下载,地址如下:

Training & Code Samples for Intel® SDK for OpenCL™ Applications

此外,Intel还提供了一个简单的walkthrough(修改gfx目录.cpp中函数FindOpenCLPlatform()的第一个入参,就可以在非Intel显卡的机器上运行该Demo),代码解析详见以下链接内容Part3,源码在链接页面底部:

Get Started with Intel® SDK for OpenCL™ Applications 2020 on Linux*...

   

四、Intel OpenCL简述

Get Started with Intel® SDK for OpenCL™ Applications 2020: Core...

根据以上链接中的内容介绍可知,Windows系统发行版默认已安装OpenCL相关的组件,但是Linux系统则需要开发人员手动下载安装

OpenCL的目标设备有两种类型:

CPU —— Afforded by the Intel® CPU Runtime for OpenCL™ Applications 18.1(does not require any Intel® Graphics Technology hardware)

GPU —— Afforded by the Intel® Graphics Compute Runtime for OpenCL™ Driver

4.1 CPU作为OpenCL的目标设备

使用多核心CPU模拟GPU工况,不需要实际的显卡、FPGA等硬件支持,故前期开发调试选用该模式很有必要。代码中将cl_device_type对象设置为CL_DEVICE_TYPE_CPU即可选择该模式。

  

4.2 GPU作为OpenCL的目标设备

GPU对应的Driver称为“NEO”,对应本文2.1节内容

  • Purple - apply for both supported Intel® CPU and supported Intel® Graphics Technology platforms.
  • Blue - apply for supported Intel® CPU platforms.
  • Red - apply for supported Intel® Graphics Technology platforms.

   

五、OpenCL资源

官方文档下载:

Khronos OpenCL Registry - The Khronos Group Inc

官方 github:

https://github.com/KhronosGroup/OpenCL-Guide

Boost 基于 OpenCL 的 C++ 的 GPU/parallel-computing 库(自1.61.0版本引入):

https://github.com/boostorg/compute

apt命令安装boost(该方式大概率不是最新版本):

sudo apt install libboost-all-dev  //通过 dpkg -s libboost-all-dev 或 dpkg -s libboost-dev 可查看已安装包信息

其它版本可进入此链接下载安装:https://www.boost.org/users/history/

  

六、OpenCL在不同平台实现支持

NVIDIANVIDIA GPUs only
AMD/ATICPUs and AMD GPUs
IntelCPUs and Intel GPUs
QualcommAdreno
ARMMali
POCLCPUs only
BeignetIntel GPUs only
AppleCPUs and GPUs
XilinxFPGA
GPU型号排名:Top GPU models

   

七、Ubuntu系统配置NVIDIA CUDA环境

7.1 安装NVIDIA显卡驱动

首先通过以下命令确认PC是否带有N卡:

sudo apt install inxi  #没有安装inxi时,通过该行命令安装
inxi -G

或者:
lspci | grep -i nvidia

笔者所用两台PC中Dell那款带有N卡,因此输出结果中显示有两个显卡:

然后在终端输入以下命令确认系统推荐安装的N卡驱动版本:

➜  ~ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001F91sv00001028sd00000922bc03sc02i00
vendor   : NVIDIA Corporation
driver   : nvidia-driver-460-server - distro non-free
driver   : nvidia-driver-460 - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-470 - distro non-free recommended
driver   : nvidia-driver-495 - distro non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-470-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin

== /sys/devices/pci0000:00/0000:00:14.3 ==
modalias : pci:v00008086d0000A370sv00008086sd00004030bc02sc80i00
vendor   : Intel Corporation
manual_install: True
driver   : backport-iwlwifi-dkms - distro free

此时在应用程序面板打开“软件和更新”,安装对应版本驱动(或者直接在命令行使用sudo apt isntall nvidia-driver-xxx),完成后重启电脑。

 注意:为了避免重启时出现画屏、黑屏等异常现象,打开文件/etc/default/grub确认GRUB_CMDLINE_LINUX_DEFAULT行是否存在nomodeset字符串,修改后需执行sudo update-grup。(secure boot是否需要关闭根据实际情况,笔者使用过程未因其遇到问题)

重启后在命令行输入nvidia-smi和nvidia-settings(应用程序面板也存在快捷图标)确认驱动是否安装成功:

此时进入设置查看电脑详细信息时,图形那行显示的将是N卡名称。可见安装N卡驱动时会默认将显卡从Intel集显切换到独显。

   

7.2 下载和安装CUDA

首先需要注意的是,每个版本的CUDA,对N卡驱动版本有个最低要求。具体可通过如下链接中“Table 3. CUDA Toolkit and Corresponding Driver Versions”查询到(N卡驱动版本在上一节终端执行nvidia-***时可看到):

https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions__table-cuda-toolkit-driver-versions

比如笔者想安装当前最新release版本,但发现CUDA 11.5 GA要求N卡最低版本495.29.05,显然不符合条件。因此只能退而求其次下载安装CUDA 11.4 Update 3

确定CUDA版本后,就可进入以下链接选择指定版本,进入下载安装界面按照指示操作即可( 默认安装路径在/usr/local目录,相关示例代码在CUDA根目录的samples目录。位置在安装过程不确定是否可以自定义,笔者是直接将samples目录拷贝到其它位置方便修改调试):

https://developer.nvidia.com/cuda-toolkit-archive

下载安装完成后,需要重启电脑才能正常使用CUDA。然后在终端再次执行clinfo,显示的则是 3 platforms + 3 devices,比本文2.2节末尾截图多了一个平台和设备。 

CUDA只有一个平台和设备,不像其它OpenCL平台那样存在多个平台和设备时需要通过索引来确定使用哪个,因此也不需要host端应用程序在运行时动态编译。

若需要卸载CUDA和N卡驱动,可参考以下链接:https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#removing-cuda-tk-and-driver

   

   

郑重提示:①本文若干架构图片取自Intel官网。

                      ②本文不允许转载,若认可本文,可点赞收藏,请杯咖啡也行。

                      ③若有疑问,可在评论区留言相互讨论。

  

  • 11
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
使用 OpenCL API 调用 GPU 进行计算,需要先编写 OpenCL 程序。OpenCL 程序是由 C 语言编写的,可以使用 OpenCL API 调用 OpenCL 驱动程序来执行计算任务。 以下是一个简单的 OpenCL 程序示例,可以将两个向量相加: ``` __kernel void vectorAdd(__global const float* a, __global const float* b, __global float* c) { int i = get_global_id(0); c[i] = a[i] + b[i]; } ``` 使用 OpenCL API 调用 OpenCL 驱动程序执行上述程序,以下是一个简单的代码示例: ```c #include <CL/opencl.h> int main() { cl_platform_id platform_id; cl_device_id device_id; cl_context context; cl_command_queue command_queue; cl_program program; cl_kernel kernel; cl_mem buffer_a, buffer_b, buffer_c; cl_int err; // 获取可用平台 clGetPlatformIDs(1, &platform_id, NULL); // 获取可用设备 clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); // 创建 OpenCL 上下文 context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err); // 创建命令队列 command_queue = clCreateCommandQueue(context, device_id, 0, &err); // 创建 OpenCL 内核程序 program = clCreateProgramWithSource(context, 1, &source_str, &source_size, &err); // 编译 OpenCL 程序 clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); // 创建内核对象 kernel = clCreateKernel(program, "vectorAdd", &err); // 创建输入缓冲区 buffer_a = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float) * N, NULL, &err); buffer_b = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float) * N, NULL, &err); // 创建输出缓冲区 buffer_c = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float) * N, NULL, &err); // 将数据从主机内存拷贝到设备缓冲区 clEnqueueWriteBuffer(command_queue, buffer_a, CL_TRUE, 0, sizeof(float) * N, a, 0, NULL, NULL); clEnqueueWriteBuffer(command_queue, buffer_b, CL_TRUE, 0, sizeof(float) * N, b, 0, NULL, NULL); // 设置内核参数 clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&buffer_a); clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&buffer_b); clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&buffer_c); // 执行内核 size_t global_item_size = N; size_t local_item_size = 64; // 可以根据设备配置调整 clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL); // 将数据从设备缓冲区拷贝到主机内存 clEnqueueReadBuffer(command_queue, buffer_c, CL_TRUE, 0, sizeof(float) * N, c, 0, NULL, NULL); // 释放资源 clReleaseMemObject(buffer_a); clReleaseMemObject(buffer_b); clReleaseMemObject(buffer_c); clReleaseKernel(kernel); clReleaseProgram(program); clReleaseCommandQueue(command_queue); clReleaseContext(context); return 0; } ``` 以上代码示例中,我们使用了 OpenCL API 创建了一个命令队列和一个内核对象,并将输入数据拷贝到设备缓冲区,最后执行内核程序并将输出数据拷贝到主机内存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值