用户可借助此项目实现 LLVM IR 与 SPIR-V 之间的双向转换,支持 OpenCL/compute 类型的 SPIR-V 模块,提供库和命令行工具 llvm-spirv,具备解码、编码及翻译功能。【此简介由AI生成】
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 |
LLVM/SPIR-V 双向转换器
本仓库包含 LLVM/SPIR-V 双向转换器的源代码,这是一个用于在 LLVM IR 与 SPIR-V 之间进行转换的库和工具。
目前,该项目仅支持 SPIR-V 的 OpenCL/计算“版本”:它接收并生成声明 Kernel 功能的 SPIR-V 模块。
LLVM/SPIR-V 双向转换器是开源软件。您可以根据 LICENSE.txt 中的许可协议条款自由分发。
目录结构
与转换器相关的文件/目录:
- include/LLVMSPIRVLib.h - 头文件
- lib/SPIRV - SPIR-V 内存中表示、解码器/编码器以及 LLVM/SPIR-V 转换器的库
- tools/llvm-spirv - 用于在 LLVM 位码和 SPIR-V 二进制文件之间进行转换的命令行工具
构建说明
此仓库的 main 分支旨在能够使用最新的 LLVM main 修订版进行构建。
使用预安装的 LLVM 进行构建
转换器可以使用最新的 LLVM nightly 包进行构建。对于 Ubuntu 和 Debian 系统,LLVM 在 http://apt.llvm.org/ 提供了包含 nightly 构建的仓库。例如,可以使用以下命令安装适用于 Ubuntu 16.04 的最新包:
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial main"
sudo apt-get update
sudo apt-get install llvm-19-dev llvm-19-tools clang-19 libclang-19-dev
默认情况下,翻译器的树外构建将使用已安装的 LLVM 版本。
git clone https://github.com/KhronosGroup/SPIRV-LLVM-Translator.git
mkdir SPIRV-LLVM-Translator/build && cd SPIRV-LLVM-Translator/build
cmake ..
make llvm-spirv -j`nproc`
使用预构建的 LLVM 进行构建
如果您拥有(基于最新版本的)LLVM 库的自定义构建版本,可以将转换器链接到该版本。
git clone https://github.com/KhronosGroup/SPIRV-LLVM-Translator.git
mkdir SPIRV-LLVM-Translator/build && cd SPIRV-LLVM-Translator/build
cmake .. -DLLVM_DIR=<llvm_build_dir>/lib/cmake/llvm/
make llvm-spirv -j`nproc`
如果此转换器作为其他 CMake 项目的一部分使用,则需要定义 LLVM_SPIRV_BUILD_EXTERNAL:
cmake .. -DLLVM_DIR=<llvm_build_dir>/lib/cmake/llvm/ -DLLVM_SPIRV_BUILD_EXTERNAL=YES
其中 llvm_build_dir 是 LLVM 构建目录。
LLVM 树内构建
该转换器可以作为常规 LLVM 子项目进行构建。为此,您需要将其克隆到 llvm/projects 或 llvm/tools 目录中。
git clone https://github.com/llvm/llvm-project.git
cd llvm-project/llvm/projects
git clone https://github.com/KhronosGroup/SPIRV-LLVM-Translator.git
按照 LLVM 的常规方式运行(或重新运行)cmake。之后,你应该会看到 llvm-spirv 和 check-llvm-spirv 目标可用。
mkdir llvm-project/build && cd llvm-project/build
cmake ../llvm -DLLVM_ENABLE_PROJECTS="clang"
make llvm-spirv -j`nproc`
关于启用 clang 项目的说明:翻译器中存在依赖 clang 二进制文件的测试,这使得 clang 成为 check-llvm-spirv 目标的必要依赖项(可在 test/CMakeLists.txt 中搜索 LLVM_SPIRV_TEST_DEPS)。
从源代码构建 clang 会耗费时间和资源,不过可通过以下方式避免:
- 若您在构建后不打算运行翻译器的单元测试,可通过传递
-DLLVM_SPIRV_INCLUDE_TESTS=OFF选项来禁用测试目标的生成。 - 若您希望运行单元测试,但不想构建
clang,可传递-DSPIRV_SKIP_CLANG_BUILDCMake 选项,以避免将clang添加为check-llvm-spirv目标的依赖项。然而,在启动测试时,LIT 会搜索clang二进制文件,此时该文件必须可用。 - 目前不支持完全不使用
clang进行构建和测试,有关进度跟踪、讨论及贡献,请参见 KhronosGroup/SPIRV-LLVM-Translator#477。
使用 SPIRV-Tools 构建
翻译器可借助 SPIRV-Tools 生成采用广泛使用语法的汇编。如果在构建翻译器之前已安装 SPIRV-Tools,系统会自动检测并使用它。不过,也可按照以下说明从自定义位置启用 SPIRV-Tools:
- 使用 以下说明 检出、构建并安装 SPIRV-Tools。使用 CMake 和 Ninja 的示例:
cmake -G Ninja <SPIRV-Tools source location> -DCMAKE_INSTALL_PREFIX=<SPIRV-Tools installation location>
ninja install
- 配置转换器时,通过在调用 cmake 命令行之前设置
PKG_CONFIG_PATH=<SPIRV-Tools installation location>/lib/pkgconfig/变量,将 pkg-config 指向 SPIR-V 工具的安装位置。 示例:
PKG_CONFIG_PATH=<SPIRV-Tools installation location>/lib/pkgconfig/ cmake <other options>
要验证翻译器构建中的 SPIR-V Tools 集成,请运行以下命令行
llvm-spirv --spirv-tools-dis input.bc -o -
输出应采用标准汇编语法打印。
配置 SPIR-V 头文件
转换器的构建依赖于官方 Khronos 头文件 spirv.hpp,该文件将 SPIR-V 扩展、修饰符、指令等映射到数值令牌。官方头文件版本可在 KhronosGroup/SPIRV-Headers 获取。获取头文件有以下几种方式:
- 默认情况下,头文件仓库将从 Khronos Group GitHub 下载,并放置到
<build_dir>/SPIRV-Headers。 - 如果在树内构建转换器,可以手动将 SPIR-V Headers 仓库下载到
llvm/projects——LLVM 构建脚本会自动识别此位置。确保该文件夹保留默认名称SPIRV-Headers。 - 任何构建类型都可以使用外部安装的 SPIR-V Headers——如果已在系统中某个位置下载了头文件并希望使用该版本,对于树内构建,只需在 CMake 命令中添加
-DLLVM_EXTERNAL_PROJECTS="SPIRV-Headers" -DLLVM_EXTERNAL_SPIRV_HEADERS_SOURCE_DIR=</path/to/headers_dir>;对于树外构建,只需添加-DLLVM_EXTERNAL_SPIRV_HEADERS_SOURCE_DIR=</path/to/headers_dir>。
测试说明
所有与转换器相关的测试都放在 test 目录中。部分测试需要 spirv-as(SPIR-V Tools 的一部分)才能运行,但其余测试无需此工具也可运行。测试还可以选择使用 spirv-val(SPIR-V Tools 的一部分),以根据官方 SPIR-V 规范验证生成的 SPIR-V。
如果由于 SPIRV-Tools 不支持某些 SPIR-V 功能而导致测试失败,请获取更新的软件包。可以使用 PKG_CONFIG_PATH 环境变量让 cmake 指向自定义安装位置。
在构建目录内执行以下命令以运行转换器测试:
make test
这要求在构建步骤中将 -DLLVM_SPIRV_INCLUDE_TESTS=ON 参数传递给 CMake。此外,当使用预安装版本的 LLVM 进行构建时,还需要 -DLLVM_EXTERNAL_LIT="/usr/lib/llvm-19/build/utils/lit/lit.py"。
通过向 CMake 传递 -DLLVM_SPIRV_INCLUDE_TESTS=OFF,可以禁用翻译器测试套件。
llvm-spirv 的运行说明
要在 LLVM IR 和 SPIR-V 之间进行转换:
-
执行以下命令,将
input.bc转换为input.spvllvm-spirv input.bc -
执行以下命令,将
input.spv转换为input.bcllvm-spirv -r input.spv推荐选项:
-spirv-target-env- 指定要转换到的 OpenCL 内置函数的目标版本(默认 CL1.2)
-
llvm-spirv接受的其他选项-o file_name- 指定输出名称-spirv-debug- 输出调试信息-spirv-text- 以内部文本格式读写 SPIR-V,用于调试目的。此文本格式未在 SPIR-V 规范中定义。--spirv-tools-dis- 以 SPIRV-Tools 格式打印 SPIR-V 汇编。仅在使用 SPIRV-Tools 构建时可用。-help- 查看完整选项列表
从 LLVM IR 转换到 SPIR-V,然后再转换回 LLVM IR,不能保证生成原始的 LLVM IR。特别是,LLVM 内在函数调用指令可能会被替换为对 OpenCL 内置函数的函数调用,并且元数据可能会丢失。
处理翻译器生成的 SPIR-V 版本
有一个选项可控制翻译器在生成/消费 SPIR-V 文件版本方面的行为。
-
-spirv-max-version=- 此选项允许限制 SPIRV-LLVM-Translator 不 生成版本高于通过此选项指定的 SPIR-V。如果同时指定了
-r选项,那么如果输入文件中的 SPIR-V 版本高于通过此选项指定的版本,SPIRV-LLVM-Translator 将拒绝该输入文件并发出错误。
允许的值为 1.0、1.1、1.2、1.3、1.4、1.5 和 1.6。
更多信息可在 SPIR-V 版本和扩展处理 中找到。
处理翻译器生成的 SPIR-V 扩展
默认情况下,在生成 SPIR-V 的过程中,翻译器不使用任何扩展。 但在消费 SPIR-V 时,翻译器会接受使用任何已知扩展的输入文件。
如果需要启用或禁用某些特定扩展,可使用以下命令行选项:
--spirv-ext=- 此选项用于控制允许/禁止哪些扩展
该选项的有效值是用逗号分隔的扩展名称列表,每个名称前需加上 + 或 - 前缀——加号表示允许使用该扩展,减号表示禁止使用该扩展。此外,还有一个特殊值可作为此选项中的扩展名称:all——它会影响翻译器已知的所有扩展。
如果 --spirv-ext 中包含翻译器未知的扩展名称,将会发出错误。
更多信息可参见 SPIR-V 版本和扩展处理
分支策略
此仓库 main 分支上的代码旨在与 llvm 项目的 main 分支保持兼容。也就是说,对于由最新 git 版本的 Clang 编译为 llvm 位码的 OpenCL 内核,应能使用 llvm-spirv 工具将其翻译为 SPIR-V。
所有新开发工作都应在 main 分支上进行。
为了提供与 LLVM 和 Clang 发布版本兼容的翻译器版本,此仓库中提供了相应的标签。例如,要使用 LLVM 7.0.0 构建翻译器,应使用 v7.0.0-1 标签。7.x 版本系列在 llvm_release_70 分支上进行维护。一般而言,只要 main 分支上的提交不依赖于更高版本 LLVM/Clang 的特性,且维护者无异议,就可以将这些提交反向移植到发布分支。不保证旧的发布分支会主动与 main 分支保持同步,但你可以通过在 GitHub 上创建拉取请求或提交 issue,请求将特定提交应用到旧的发布分支。
发布策略
如前所述,存在 llvm_release_* 分支用于接收回溯更改。如果存在这些更改,github CI 会按月自动发布,格式为 <llvm_major>.<llvm_minor>.<最新补丁 +1>。