跳转至内容

通用图形处理器计算

来自 ArchWiki
(重定向自 ROCm)

通用图形处理器计算 (GPGPU) API 定义包括了厂商无关的 OpenCL、SYCL、HIP、OpenMP 和 Vulkan 计算着色器,以及 Nvidia 的 CUDA。每个 API 都可以在多种硬件或软件上拥有多个实现:GPU、CPU、NPU、FPGA,或仅仅是另一个 GPGPU API(Shim/Transpiler)。

OpenCL

OpenCL(Open Computing Language)是 Khronos Group(一个非营利性联盟)开发的一个开放、免版税的并行编程规范。

OpenCL 规范描述了一种基于 C 的编程语言、一个必须存在的通用环境,以及一个 C API,使程序员能够调用到这个环境。此外,还有一些绑定允许其他语言调用该环境,以及用于编写 OpenCL 计算内核的替代语言。

提示 clinfo 工具可用于列出 OpenCL 平台、存在的设备和 ICD 加载器属性。

OpenCL 环境至少包括以下一项:

  • libOpenCL.so 副本,即提供完整 OpenCL API 接口的 ICD 加载器。
  • ICD 加载器加载的平台相关驱动程序。

ICD 加载器 (libOpenCL.so)

一个系统通常拥有多个支持 OpenCL 的硬件,因此也就拥有多个 OpenCL 运行时实现。一个名为“OpenCL ICD 加载器”的组件是一个平台无关的库,它通过 OpenCL API 提供加载设备特定驱动程序的手段。大多数 OpenCL 厂商都提供自己的 OpenCL ICD 加载器实现,这些应该都能与其他厂商的 OpenCL 实现配合使用。不幸的是,大多数厂商提供的 ICD 加载器并未完全更新,因此 Arch Linux 决定从一个独立项目(ocl-icd)提供此库,该项目提供了当前 OpenCL API 的一个正常工作的实现。截至 2025 年,当前 OpenCL 版本为 3.0。

其他 ICD 加载器库作为每个厂商 SDK 的一部分安装。如果您想确保使用 ocl-icd 软件包中的 ICD 加载器,可以在 /etc/ld.so.conf.d 中创建一个文件,将 /usr/lib 添加到动态程序加载器的搜索目录中。

/etc/ld.so.conf.d/00-usrlib.conf
/usr/lib

这是必需的,因为所有 SDK 都通过 ld.so.conf.d 文件将它们的运行时库目录添加到搜索路径中。

包含各种 OpenCL ICD 的可用软件包是:

注意 ICD 加载器的厂商在功能上无关紧要:它们应该是厂商无关的,并且可以互换使用,只要它们实现正确。厂商仅用于区分它们。

管理实现

要查看当前系统中哪些 OpenCL 实现处于活动状态,请使用以下命令:

$ ls /etc/OpenCL/vendors

要找出系统中所有可用的 OpenCL 平台和设备的(已知)属性,请安装 clinfo

本文或本章节的准确性存在争议。

原因: OCL_ICD_VENDORS 的 bug 是否仍然存在尚不确定。对于 ocl-icd 2.3.3,将 OCL_ICD_VENDORS 设置为单个文件似乎可以正常工作,并且 clinfo -l 会产生正确的结果。(在 Talk:General-purpose computing on graphics processing units 中讨论)

您可以使用 ocl-icd-chooseAUR 指定您的应用程序应该看到哪些实现。例如:

$ ocl-icd-choose amdocl64.icd:mesa.icd davinci-resolve-checker

ocl-icd-choose 是一个简单的包装脚本,它设置 OCL_ICD_FILENAMES 环境变量。如果 OCL_ICD_VENDORS 可以像手册建议的那样处理单个 icd 文件,那么它就不需要了;这是一个正在跟踪的已知 bug:OCL-dev/ocl-icd#7

运行时

执行使用 OpenCL 的程序,需要安装一个可以被 libOpenCL.so 加载的运行时。

通用 GPU 上的 OpenCL

对于 Mesa 支持的任何 GPU,您都可以通过安装 opencl-mesa 来使用 rusticl。可以通过 环境变量 RUSTICL_ENABLE=driver 来启用它,其中 driver 是一个 Gallium 驱动程序,例如 radeonsiiris。它适用于最广泛的硬件,但不一定提供最佳性能。如果您在使用其他驱动程序时遇到问题,可以尝试使用它:启用它只需要很少的配置。

AMD/ATI GPU 上的 OpenCL

  • rocm-opencl-runtime:AMD ROCm GPU 计算堆栈的一部分,官方支持一小部分 GPU 型号(其他显卡可能在非官方或部分支持下可用)。为了支持早于 Vega 的显卡,您需要设置运行时变量 ROC_ENABLE_PRE_VEGA=1。这与在 Ubuntu 的 amdgpu-install 中指定 opencl=rocr 类似,但不完全等同,因为此软件包的 rocm 版本与 Ubuntu 的安装程序版本不同。
  • opencl-legacy-amdgpu-proAUR:从 AMD 的 Ubuntu 版本重新打包的旧版 Orca OpenCL。等同于在 Ubuntu 的 amdgpu-install 中指定 opencl=legacy
  • opencl-amdAUR, opencl-amd-devAUR:从 AMD 的 Ubuntu 版本重新打包的 ROCm 组件。等同于在 Ubuntu 的 amdgpu-install 中指定 opencl=rocr,legacy
OpenCL 图像支持

最新的 ROCm 版本现在包括 OpenCL 图像支持,这被 Darktable 等 GPGPU 加速软件使用。ROCm 和 AMDGPU 开源图形驱动程序是所有必需的。不需要 AMDGPU PRO。

$ /opt/rocm/bin/clinfo | grep -i "image support"
Image support                                   Yes

NVIDIA GPU 上的 OpenCL

Intel GPU 上的 OpenCL

  • intel-compute-runtime:即 Neo OpenCL 运行时,适用于 Gen12 (Alder Lake) 及更新的 Intel HD Graphics GPU 的开源实现。
  • intel-compute-runtime-legacyAUR:与上面相同,但适用于 Gen11 (Rocket Lake) 及更低版本。
  • beignetAUR:适用于 Gen7 (Ivy Bridge) 及更新的 Intel HD Graphics GPU 的开源实现,已由 Intel 弃用,推荐使用 NEO OpenCL 驱动程序,对于旧硬件平台(如 Ivy Bridge、Haswell)仍是推荐的解决方案。
  • intel-openclAUR:适用于 Gen7 (Ivy Bridge) 及更新的 Intel HD Graphics GPU 的专有实现,已由 Intel 弃用,推荐使用 NEO OpenCL 驱动程序,对于旧硬件平台(如 Ivy Bridge、Haswell)仍是推荐的解决方案。

CPU 上的 OpenCL

以下允许在 CPU 上运行 OpenCL:

  • intel-opencl-runtimeAUR:Intel 的 LLVM 和基于 oneAPI 的 x86_64 处理器实现。官方用于 Intel Core 和 Xeon 处理器,但实际上适用于所有支持 SSE4.1 的 x86_64 处理器。即使在 AMD Zen 处理器上,其性能也优于 pocl。
  • pocl:基于 LLVM 的 OpenCL 实现,适用于 LLVM 支持的所有 CPU 架构以及一些 GPU(Nvidia 通过 libCUDA,Intel 通过 Level Zero)以及 OpenASIP。尽管覆盖范围广泛,但其性能仍有待提高。
  • amdapp-sdkAUR:AMD CPU 运行时,已弃用。

Vulkan 上的 OpenCL

以下允许在 Vulkan 运行时之上运行 OpenCL:

  • clspv-gitAUR:Clspv 是一个将 OpenCL C 的子集编译为 Vulkan 计算着色器的原型编译器。
  • clvk-gitAUR:clvk 是一个基于 Vulkan 和 clspv 编译器的 OpenCL 3.0 的原型实现。

FPGA 上的 OpenCL

32 位运行时

执行使用 OpenCL 的 32 位程序,需要安装一个兼容的硬件 32 位运行时。

提示 clinfo 工具只能用于列出 64 位 OpenCL 平台、存在的设备和 ICD 加载器属性。对于 32 位,您需要为 32 位编译 clinfo 或使用 archlinux32 项目提供的 32 位 clinfo

通用 GPU 上的 OpenCL (32 位)

NVIDIA GPU 上的 OpenCL (32 位)

开发

对于 OpenCL 开发,所需的最低附加软件包是:

  • ocl-icd:OpenCL ICD 加载器实现,与最新的 OpenCL 规范保持同步。
  • opencl-headers:OpenCL C/C++ API 头文件。

厂商的 SDK 提供了大量的工具和支持库:

  • intel-opencl-sdkAURIntel OpenCL SDK(旧版本,新的 OpenCL SDK 已包含在 INDE 和 Intel Media Server Studio 中)
  • amdapp-sdkAUR:此软件包安装为 /opt/AMDAPP,除了 SDK 文件外,还包含许多代码示例(/opt/AMDAPP/SDK/samples/)。它还提供了 clinfo 工具,该工具列出系统中存在的 OpenCL 平台和设备,并显示有关它们的详细信息。由于 SDK 本身包含一个 CPU OpenCL 驱动程序,因此无需额外的驱动程序即可在 CPU 设备上执行 OpenCL(无论其厂商如何)。
  • rocm-opencl-sdk:为 AMD 平台开发基于 OpenCL 的应用程序。
  • cuda:Nvidia 的 GPU SDK,包括对 OpenCL 3.0 的支持。

语言绑定

这些绑定允许其他语言调用 OpenCL 环境。它们通常不改变用 OpenCL C 编写内核的要求。

SYCL

根据 Wikipedia:SYCL

SYCL 是一种高级编程模型,旨在提高各种硬件加速器的编程效率。它是一种基于纯 C++17 的单源码嵌入式领域特定语言 (eDSL)。

SYCL [...] 受到 OpenCL 的启发,它使得可以使用完全标准的 C++ 以“单源码”风格编写异构处理器代码。SYCL 支持单源码开发,其中 C++ 模板函数可以同时包含主机和设备代码,以构建使用硬件加速器的复杂算法,然后在源代码中的不同数据类型上重用它们。

虽然 SYCL 标准最初是 OpenCL 工作组的高级编程模型子组,并最初为与 OpenCL 和 SPIR 配合使用而开发,但 SYCL 是一个独立于 OpenCL 工作组的 Khronos Group 工作组 [...] 从 SYCL 2020 开始,SYCL 已被泛化为一个更通用的异构框架,能够面向其他系统。这现在可以通过通用后端概念来实现,该后端可以面向任何加速 API,同时实现与目标 API 的完全互操作性,例如使用现有的原生库以达到最佳性能并简化编程工作。例如,OpenSYCL 实现通过 AMD 的跨厂商 HIP 面向 ROCm 和 CUDA。

换句话说,SYCL 定义了一个基于 C++17 的编程环境。这个环境旨在与生成 CPU 和 GPGPU 代码的编译器结合使用。用于 GPGPU 端的语言曾经是 SPIR,但也有针对其他中间表示的编译器存在。

实现

  • trisycl-gitAUR:开源实现,主要由 Xilinx 推动。
  • adaptivecppAUR:适用于所有厂商的 CPU 和 GPU 的多种编程模型(SYCL、C++ 标准并行、HIP/CUDA)的编译器。
  • intel-oneapi-dpcpp-cpp:Intel 的 Data Parallel C++:SYCL 的 LLVM/oneAPI 实现。
  • computecppAUR:Codeplay 的 SYCL 1.2.1 专有实现。可面向 SPIR、SPIR-V 和实验性的 PTX(NVIDIA)作为设备目标(于 2023 年 9 月 1 日结束支持,将合并到 Intel LLVM 实现中来源)。

oneAPI

oneAPI 是 Intel 的许多高性能计算库使用的营销名称。软件包 intel-oneapi-dpcpp-cpp 提供了 /opt/intel/oneapi/setvars.sh,可用于设置 SYCL 程序的编译和链接环境。该组件的一些部分(如编译器)由 Intel 在 GitHub 上开源,而其他部分则不开源。

可以安装一些软件包以获得附加功能。例如,intel-oneapi-mkl-sycl 支持 Math Kernel Library (MKL) 的 GPU 卸载。

检查 SPIR 支持

SYCL 最初旨在编译为 SPIR 或 SPIR-V。两者都是 Khronos 设计的中间语言,可以被 OpenCL 驱动程序使用。SPIR 作为 OpenCL 1.0 或 2.0 扩展包含,而 SPIR-V 从 2.1 版本开始(clCreateProgramWithIL)包含在 OpenCL 核心中。要检查是否支持 SPIR 或 SPIR-V,可以使用 clinfo

$ clinfo | grep -i spir
Platform Extensions                             cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_depth_images cl_khr_3d_image_writes cl_intel_exec_by_local_thread cl_khr_spir cl_khr_fp64 cl_khr_image2d_from_buffer cl_intel_vec_len_hint 
  IL version                                    SPIR-V_1.0
  SPIR versions                                 1.2

ComputeCpp 还附带一个工具,可以总结相关的系统信息。

$ computecpp_info
Device 0:

  Device is supported                     : UNTESTED - Untested OS
  CL_DEVICE_NAME                          : Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz
  CL_DEVICE_VENDOR                        : Intel(R) Corporation
  CL_DRIVER_VERSION                       : 18.1.0.0920
  CL_DEVICE_TYPE                          : CL_DEVICE_TYPE_CPU 

已知至少部分支持 SPIR 或 SPIR-V 的驱动程序包括 intel-compute-runtimeintel-opencl-runtimeAURpocl

SPIR/SPIR-V 的其他用法

SPIR-V 不仅涵盖计算内核,还涵盖图形着色器。它能够作为 OpenGL 和 Vulkan 的着色器中间语言,以及 OpenCL、Vulkan 和 SYCL 的计算中间语言。它也可以被反编译,作为一种将内核或着色器从一种语言转换为另一种语言的方法。

C++ for OpenCL 语言(不要与短命的“OpenCL C++”混淆)将 C++17 与 OpenCL C 结合。少数 OpenCL 驱动程序支持使用 clBuildProgram() 直接加载它,就像处理 OpenCL C 一样,但主要预期用法是通过 clang 首先将其转换为 SPIR-V。对于希望在编写 OpenCL 内核时使用 C++17 但又不想拥抱 SYCL 整个模型的程序员来说,这可能是一个选择。

开发

SYCL 需要一个已设置的、工作的 C++11 环境。

有几个开源库可用于利用 SYCL 从其 C++17 语言中的并行功能:

CUDA

CUDA(Compute Unified Device Architecture)是 NVIDIA 的专有、闭源并行计算架构和框架。它需要 NVIDIA GPU,并包含几个组件:

  • 必需
    • NVIDIA 内核模块
    • CUDA “驱动”和“运行时”库
  • 可选
    • 附加库:CUBLAS、CUFFT、CUSPARSE 等。
    • CUDA 工具包,包括 nvcc 编译器。
    • CUDA SDK,包含许多 CUDA 和 OpenCL 程序的代码示例。

内核模块和 CUDA “驱动”库包含在 nvidia-openopencl-nvidia 中。“运行时”库和其余的 CUDA 工具包在 cuda 中可用。cuda-gdb 需要安装 ncurses5-compat-libsAUR,参见 FS#46598

开发

cuda 软件包将所有组件安装在 /opt/cuda 目录下。/etc/profile.d/cuda.sh 中的脚本会设置相关的环境变量,以便所有支持 CUDA 的构建系统都能找到它。

要查看安装是否成功以及 CUDA 是否正常运行,您可以编译 CUDA 示例。一种检查安装的方法是运行 deviceQuery 示例。

语言绑定

ROCm

ROCm (Radeon Open Compute Platform) 是 AMD 对 CUDA 的回应。它包含从驱动程序 (AMDGPU) 到编译器和运行时库的许多软件组件,与 CUDA 类似。有些组件特定于选定的 AMD GPU,其他组件则完全与硬件无关。有关更多信息,请参阅 Arch Linux 的 ROCm 存储库

ROCm 包含一个统一的软件栈,用于在 AMDGPU 驱动程序上实现计算能力。在这个栈之上,它实现了 HIP、OpenMP 和 OpenCL。它还包含一些基于 HIP 构建的组件以及使用 NVIDIA CUDA 栈的 HIP 实现。

支持 ROCm 的型号

ROCm 应支持从 Polaris 架构(RX 500 系列)及以上的 AMD GPU。官方的 GPU 型号列表非常短,主要包含专业型号。然而,同代消费者级 GPU 和 APU 也已知可用。其他代可能在非官方或部分支持下可用。为了支持 Polaris,您需要设置运行时变量 ROC_ENABLE_PRE_VEGA=1

新的 AMD GPU 架构添加到 ROCm 需要一段时间;请参阅 Wikipedia:ROCm#Consumer-grade GPUs 以获取最新的支持矩阵。另请参阅之前的#OpenCL on AMD/ATI GPU

HIP

Heterogeneous Interface for Portability (HIP) 是 AMD 的专用 GPU 编程环境,用于在 GPU 硬件上设计高性能内核。HIP 是一个 C++ 运行时 API 和编程语言,允许开发人员在不同平台上创建可移植应用程序。

HIP 的规范在 rocm-systems 存储库中管理,但 HIP 本身与硬件无关。

HIP 运行时库软件包

  • rocm-hip-runtime:高级运行时库,类似于 OpenCL ICD 加载器。
  • hip-runtime-amd:AMD GPU 的 HIP 实现。
  • hip-runtime-nvidia:ROCm 中用于 NVIDIA GPU 的异构接口。这实际上只是一堆用于 CUDA C++ 编译器的头文件,主要包含 #define 重命名。

rocm-hip-sdk 软件包包含 HIP SDK。所有组件都安装在 /opt/rocm 目录下。设置相关环境变量的脚本在 /etc/profile.d/rocm.sh 中提供。一些软件可能还会检查 HIP_PATH,可以手动将其设置为与 ROCM_PATH 相同的值。

miopen-hip 是 AMD 开源深度学习库的 HIP 后端。


ROCm 故障排除

首先检查您的 GPU 是否在 /opt/rocm/bin/rocminfo 中显示。如果未显示,可能意味着 ROCm 不支持您的 GPU,或者其构建时未包含对您 GPU 的支持。

另请检查ROCm HIP 环境变量以进行调试、GPU 隔离等。

OpenMP 和 OpenACC

OpenMP 因其在 CPU 多进程中的使用而闻名,但它也支持一些卸载功能,可将部分工作移至 GPGPU。OpenACC 处于类似的位置:两者都基于将 pragmas 插入普通 C/C++/Fortran 代码,并由编译器将标记的部分拆分出来以进行卸载或多进程。

  • AMD 为支持 ROCm 的 AMD GPU 提供 OpenMP 实现。 openmp-extrasAUR 软件包提供了 AOMP - 一个开源的基于 Clang/LLVM 的编译器,增加了对 AMD GPU 上 OpenMP API 的支持。
  • Nvidia 的 nvhpc 为其 GPU 提供带有 GPU 卸载的 OpenMP 实现。[1]
  • GCC 可以生成 Nvidia (nvptx) 和 AMD (gfx9, gfx10, gfx11) 代码,用于卸载 OpenMP 和 OpenACC。[2]
  • Clang/LLVM 可以生成 Nvidia (nvptx) 和 AMD (amdgpu) 代码,用于卸载 OpenMP 和 OpenACC。[3] [4]

支持 GPGPU 加速的软件列表

本文章或章节需要扩充。

原因: 更多应用程序可能支持 GPGPU。 (请在 Talk:General-purpose computing on graphics processing units 讨论)

PyTorch on ROCm

要使用 PyTorch 和 ROCm,请安装 python-pytorch-rocm

$ python -c 'import torch; print(torch.cuda.is_available())'
True

ROCm 会模拟 CUDA,因此这应该返回 True。如果不是,则可能是未针对您的 GPU 编译,或者您可能存在冲突的依赖项。您可以通过查看 ldd /usr/lib/libtorch.so 来验证这些——不应该有任何缺失的 .so 文件,也没有相同 .so 的多个版本。

参见