hgfatbinary使用指南(v2.1)
1. 概述
hgfatbinary是PPU Fatbinary文件管理工具。在PPU中,Fatbinary 是一种特殊的文件格式,它可以将多个PPU架构的代码打包到单一文件中,使驱动程序能够根据运行时可用的硬件自动选择最合适的二进制进行加载,主要功能如下:
多架构支持:在一个文件中包含针对不同PPU硬件架构的编译代码。
运行时选择:驱动程序启动时自动检测硬件并加载匹配架构的二进制。
减少部署复杂度:避免为不同设备维护多个二进制文件。
压缩优化:内置压缩功能减小二进制体积。
1.1. 工作原理
PPU SDK在编译过程中可以为多个设备架构的生成对应的设备代码包括(如 ByteCode、DeviceBinary等)。
编译器会调用hgfatbinary工具将这些文件打包成一个 fatbinary 文件。
链接器将 fatbinary 嵌入到最终可执行文件中。
运行时根据硬件自动加载适合架构二进制。
2. 使用介绍
2.1. 命令行选项
选项 | 参数 | 描述 | 默认值/说明 |
基础架构选项 | | | |
--64 | 无 | 指定这是 64 位编译 | |
-hggc | 无 | 指定使用 HGGC 架构 | |
编译类型选项 | |||
--debug | 无 | 指定这是调试编译 | 注意:当前版本未支持 |
-g | 无 | --debug 的别名 | 注意:当前版本未支持 |
--device-c | 无 | 指定包含可重定位代码 | 注意:当前版本未支持 |
--link | 无 | 指定包含已链接代码 | |
文件操作选项 | |||
--create | <file name> | 创建包含 fat 二进制的文件 | 需指定文件名 |
--embedded-fatbin | <file name> | 指定 C include文件的名称,该文件定义了嵌入式 fatbinary 描述符,用于保存所有"内部"镜像 | 需指定文件名 |
代码镜像指定选项 | |||
--image | <image spec>,... | 指定带有编译配置文件的镜像列表 | 用于单 SM 架构 |
--image2 | <image spec>,... | 指定带有类型和编译器配置的镜像列表(允许多个 SM 在一个文件中,例如主机对象、库) | 用于多 SM 架构 |
--image3 | <image spec>,... | 指定带有类型和编译它的 SM 的镜像列表 | 用于详细 SM 规格 |
--no-asm | 无 | 指定输出 fatbin 不应使用汇编 | 注意:当前版本未支持 |
压缩选项 | | | |
--compress-all | 无 | 压缩 fatbinary 中的所有镜像 | 默认压缩算法:ZSTD |
--compress | <value> | 压缩 fatbinary 中的IR和ELF镜像 | 默认值: true |
--compress-mode | <value> | 调整压缩等级,允许压模模式有speed,balance,default,size,none | 默认值: speed |
辅助选项 | | | |
--help | 无 | 打印此工具的帮助信息 | |
-h | 无 | --help 的别名 | |
--version | 无 | 打印此工具的版本信息 | |
-V | 无 | --version 的别名 | |
--verbose | 无 | 启用详细模式,打印代码生成统计信息 | |
-v | 无 | --verbose 的别名 | |
--ident | <identifier name> | 指定bundle file标识符名称 | 注意:当前版本未支持 |
2.2. 使用示例
2.2.1. 创建fatbinary
hgfatbinary -create=/tmp/vector_add-7019ef.hgfb \
-image3=file=/tmp/vector_add-76beaa.bc,kind=hgvm,mcpu=ppu001 \
-image3=file=/tmp/vector_add-3c1b8b.out,kind=hggc,mcpu=ppu001
2.2.2. embeded方式创建fatbinary
hgfatbinary -64 --cmdline=--compile-only --link --compress-all \
--create=test.tmp3.fatbin --embedded-fatbin=test.tmp3_dlink_hdrs.h \
-image3=file=/tmp/vector_add-3c1b8b.out,kind=hggc,mcpu=ppu001 \
-register-link-binaries test.tmp3.h
2.2.3. 创建fatbinary,并开启压缩
hgfatbinary -create=/tmp/vector_add-7019ef.hgfb --compress-all --compress-mode=speed \
-image3=file=/tmp/vector_add-76beaa.bc,kind=hgvm,mcpu=ppu001 \
-image3=file=/tmp/vector_add-3c1b8b.out,kind=hggc,mcpu=ppu001
3. hgFatbin API
以下描述了 hgFatbin 库中提供的所有函数及其参数和返回值。这些函数用于创建、管理及操作 fatbinary。
3.1. Error codes
enum hgFatbinResult
功能: 用于表示hgFatbin API接口等返回结果
HGFATBIN_SUCCESS = 0,
HGFATBIN_ERROR_INTERNAL,
HGFATBIN_ERROR_ELF_ARCH_MISMATCH,
HGFATBIN_ERROR_ELF_SIZE_MISMATCH,
HGFATBIN_ERROR_MISSING_TIX_VERSION,
HGFATBIN_ERROR_NULL_POINTER,
HGFATBIN_ERROR_COMPRESSION_FAILED,
HGFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED,
HGFATBIN_ERROR_INVALID_ARCH,
HGFATBIN_ERROR_INVALID_HGVM,
HGFATBIN_ERROR_EMPTY_INPUT,
HGFATBIN_ERROR_MISSING_TIX_ARCH,
HGFATBIN_ERROR_TIX_ARCH_MISMATCH,
HGFATBIN_ERROR_MISSING_FATBIN,
HGFATBIN_ERROR_INVALID_INDEX,
HGFATBIN_ERROR_IDENTIFIER_REUSE,
HGFATBIN_ERROR_INTERNAL_TIX_OPTION,
HGFATBIN_ERROR_UNCOMPRESSED_IMAGE = 1 << 10
const char *hgFatbinGetErrorString(hgFatbinResult result);
功能: 用于获取对应错误码的描述信息
3.2. 函数列表
3.2.1. hgFatbinCreate
功能: 创建一个新的句柄
原型:
hgFatbinResult hgFatbinCreate(hgFatbinHandle *handle_indirect, const char **options, size_t optionsCount);
参数说明:
[out] handle_indirect: 新的 hgFatbin 句柄地址。
[in] options: 包含单个选项的字符串数组。
[in] optionsCount: 选项的数量。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_UNRECOGNIZED_OPTION: 未识别的选项。
HGFATBIN_ERROR_INTERNAL: 内部错误。
3.2.2. hgFatbinDestroy
功能: 销毁句柄
原型:
hgFatbinResult hgFatbinDestroy(hgFatbinHandle *handle_indirect);
参数说明:
[in] handle_indirect: 要销毁的句柄指针。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 注意: 在调用此函数后,使用其他指向该句柄的指针会导致未定义行为。传递的句柄将被设置为 nullptr。
3.2.3. hgFatbinAddTIX
功能: 向 fatbinary 添加 TIX 原型:
hgFatbinResult hgFatbinAddTIX(hgFatbinHandle handle, const char *code, size_t size, const char *arch, const char *identifier, const char *optionsCmdLine);
参数说明:
[in] handle: hgFatbin 句柄。
[in] code: TIX 代码。
[in] size: TIX 代码的大小(包括终止符 '\0')。
[in] arch: 此 TIX 对应的架构。
[in] identifier: TIX 的名称,在提取 fatbin 时有用。
[in] optionsCmdLine: JIT 编译期间使用的选项。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INVALID_ARCH: 无效的架构。
HGFATBIN_ERROR_TIX_ARCH_MISMATCH: TIX 架构不匹配。
HGFATBIN_ERROR_COMPRESSION_FAILED: 压缩失败。
HGFATBIN_ERROR_UNRECOGNIZED_OPTION: 未识别的选项。
HGFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED: 压缩后的大小超出限制。
HGFATBIN_ERROR_EMPTY_INPUT: 空输入。
HGFATBIN_ERROR_MISSING_TIX_VERSION: 缺少 TIX 版本。
HGFATBIN_ERROR_MISSING_TIX_ARCH: 缺少 TIX 架构。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保所有字符串格式正确。如果最后一个字符不是 '\0',则会自动添加,但在此过程中,代码可能会被复制。
3.2.4. hgFatbinAddHgbin
功能: 向 fatbinary 添加 HGGC 二进制文件
原型:
hgFatbinResult hgFatbinAddHgbin(hgFatbinHandle handle, const void *code, size_t size, const char *arch, const char *identifier);
参数说明:
[in] handle: hgFatbin 句柄。
[in] code: hgbin 二进制文件。
[in] size: hgbin 文件的大小。
[in] arch: 此 hgbin 对应的架构。
[in] identifier: hgbin 的名称,在提取 fatbin 时有用。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_INVALID_ARCH: 无效的架构。
HGFATBIN_ERROR_ELF_ARCH_MISMATCH: ELF 架构不匹配。
HGFATBIN_ERROR_ELF_SIZE_MISMATCH: ELF 大小不匹配。
HGFATBIN_ERROR_COMPRESSION_FAILED: 压缩失败。
HGFATBIN_ERROR_UNRECOGNIZED_OPTION: 未识别的选项。
HGFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED: 压缩后的大小超出限制。
HGFATBIN_ERROR_EMPTY_INPUT: 空输入。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保所有字符串格式正确。
3.2.5. hgFatbinAddCompressed
功能: 向 fatbinary 添加压缩的 HGGC 二进制文件
原型:
hgFatbinResult hgFatbinAddCompressed(hgFatbinHandle handle, const void *code, size_t size);
参数说明:
[in] handle: hgFatbin 句柄。
[in] code: 二进制文件。
[in] size: 二进制文件的大小。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_INVALID_ARCH: 无效的架构。
HGFATBIN_ERROR_ELF_ARCH_MISMATCH: ELF 架构不匹配。
HGFATBIN_ERROR_ELF_SIZE_MISMATCH: ELF 大小不匹配。
HGFATBIN_ERROR_COMPRESSION_FAILED: 压缩失败。
HGFATBIN_ERROR_UNRECOGNIZED_OPTION: 未识别的选项。
HGFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED: 压缩后的大小超出限制。
HGFATBIN_ERROR_EMPTY_INPUT: 空输入。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保所有字符串格式正确。
3.2.6. hgFatbinAddLTOIR
功能: 向 fatbinary 添加 LTOIR
原型:
hgFatbinResult hgFatbinAddLTOIR(hgFatbinHandle handle, const void *code, size_t size, const char *arch, const char *identifier, const char *optionsCmdLine);
参数说明:
[in] handle: hgFatbin 句柄。
[in] code: LTOIR 代码。
[in] size: LTOIR 代码的大小。
[in] arch: 此 LTOIR 对应的架构。
[in] identifier: LTOIR 的名称,在提取 fatbin 时有用。
[in] optionsCmdLine: JIT 编译期间使用的选项。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INVALID_ARCH: 无效的架构。
HGFATBIN_ERROR_COMPRESSION_FAILED: 压缩失败。
HGFATBIN_ERROR_UNRECOGNIZED_OPTION: 未识别的选项。
HGFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED: 压缩后的大小超出限制。
HGFATBIN_ERROR_EMPTY_INPUT: 空输入。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保所有字符串格式正确。
3.2.7. hgFatbinAddRDCIR
功能: 向 fatbinary 添加 RDCIR
原型:
hgFatbinResult hgFatbinAddRDCIR(hgFatbinHandle handle, const void *code, size_t size, const char *arch, const char *identifier, const char *optionsCmdLine);
参数说明:
[in] handle: hgFatbin 句柄。
[in] code: RDCIR 代码。
[in] size: RDCIR 代码的大小。
[in] arch: 此 RDCIR 对应的架构。
[in] identifier: RDCIR 的名称,在提取 fatbin 时有用。
[in] optionsCmdLine: JIT 编译期间使用的选项。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INVALID_ARCH: 无效的架构。
HGFATBIN_ERROR_COMPRESSION_FAILED: 压缩失败。
HGFATBIN_ERROR_UNRECOGNIZED_OPTION: 未识别的选项。
HGFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED: 压缩后的大小超出限制。
HGFATBIN_ERROR_EMPTY_INPUT: 空输入。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保所有字符串格式正确。**说明:**本版本尚未支持
3.2.8. hgFatbinSize
功能: 返回 fatbinary 的大小
原型:
hgFatbinResult hgFatbinSize(hgFatbinHandle handle, size_t *size);
参数说明:
[in] handle: hgFatbin 句柄。
[out] size: fatbinary 的大小。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
3.2.9. hgFatbinGet
功能: 返回完成的 fatbinary
原型:
hgFatbinResult hgFatbinGet(hgFatbinHandle handle, void *buffer);
参数说明:
[in] handle: hgFatbin 句柄。
[out] buffer: 存储 fatbinary 的内存。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保缓冲区大小适合 fatbinary。在使用此函数之前必须调用 hgFatbinSize,否则会返回错误。
3.2.10. hgFatbinEmbeddedSize
功能: 返回嵌入式 fatbinary 的大小
原型:
hgFatbinResult hgFatbinEmbeddedSize(hgFatbinHandle handle, size_t *size);
参数说明:
[in] handle: hgFatbin 句柄。
[out] size: 嵌入式 fatbinary 的大小。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
3.2.11. hgFatbinEmbeddedGet
功能: 返回嵌入式完成的 fatbinary
原型:
hgFatbinResult hgFatbinEmbeddedGet(hgFatbinHandle handle, void *buffer);
参数说明:
[in] handle: hgFatbin 句柄。
[out] buffer: 存储嵌入式 fatbinary 的内存。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保缓冲区大小适合 fatbinary。在使用此函数之前必须调用 hgFatbinSize,否则会返回错误。
3.2.12. hgFatbinUncompress
功能: 解压
原型:
hgFatbinResult hgFatbinUncompress(hgFatbinHandle handle);
参数说明:
[in] handle: hgFatbin 句柄。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
3.2.13. hgFatbinGetUncompressSize
功能: 返回解压图像的大小
原型:
hgFatbinResult hgFatbinGetUncompressSize(hgFatbinHandle handle, size_t *uncompressSize);
参数说明:
[in] handle: hgFatbin 句柄。
[out] uncompressSize: 解压图像的大小。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
3.2.14. hgFatbinGetUncompressBuffer
功能: 返回解压图像
原型:
hgFatbinResult hgFatbinGetUncompressBuffer(hgFatbinHandle handle, void* unCompressBuf);
参数说明:
[in] handle: hgFatbin 句柄。
[out] unCompressBuf: 存储解压二进制文件的内存。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
> 用户需确保缓冲区大小适合 fatbinary。在使用此函数之前必须调用 hgFatbinGetUncompressSize,否则会返回错误。
3.2.15. hgFatbinVersion
功能: 返回当前版本的 hgFatbin
原型:
hgFatbinResult hgFatbinVersion(const char** version);
参数说明:
[out] version: 当前版本。
返回值:
HGFATBIN_SUCCESS: 成功。
HGFATBIN_ERROR_NULL_POINTER: 输入指针为空。
HGFATBIN_ERROR_INTERNAL: 内部错误。
3.3. 示例
本节演示了一个简单例子如何运行时创建fatbin
#include <iostream>
#include <fstream>
#include <vector>
#include "hgFatbin.h"
// 读取二进制文件到 vector 中
bool readBinaryFile(const std::string& filename, std::vector<unsigned char>& buffer) {
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filename << std::endl;
return false;
}
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
buffer.resize(static_cast<size_t>(size));
if (buffer.size() != static_cast<size_t>(size)) {
std::cerr << "分配内存失败" << std::endl;
return false;
}
if (!file.read(reinterpret_cast<char*>(buffer.data()), size)) {
std::cerr << "读取文件失败" << std::endl;
return false;
}
return true;
}
int main() {
hgFatbinHandle handle = nullptr;
const char* options[] = {};
size_t optionsCount = 0;
// 1. 创建句柄
hgFatbinResult result = hgFatbinCreate(&handle, options, optionsCount);
if (result != HGFATBIN_SUCCESS || handle == nullptr) {
std::cerr << "hgFatbinCreate 失败,错误码: " << static_cast<int>(result) << std::endl;
return 1;
}
std::cout << "hgFatbinCreate 成功!handle: " << handle << std::endl;
// 2. 读取 hgbin 文件(假设你的 hgbin 文件是 test.hgbin)
std::string hgbinFilename = "test.hgbin";
std::vector<unsigned char> hgbinData;
if (!readBinaryFile(hgbinFilename, hgbinData)) {
std::cerr << "读取 hgbin 文件失败" << std::endl;
hgFatbinDestroy(&handle);
return 1;
}
// 3. 添加 hgbin 到 fatbinary
const void* code = hgbinData.data();
size_t size = hgbinData.size();
const char* arch = "ppu001";
const char* identifier = "my_test";
result = hgFatbinAddHgbin(handle, code, size, arch, identifier);
if (result != HGFATBIN_SUCCESS) {
std::cerr << "hgFatbinAddHgbin 失败,错误码: " << static_cast<int>(result) << std::endl;
hgFatbinDestroy(&handle);
return 1;
}
std::cout << "hgbin 添加成功!" << std::endl;
// 4. 获取 fatbinary 的大小
size_t fatbinSize = 0;
result = hgFatbinSize(handle, &fatbinSize);
if (result != HGFATBIN_SUCCESS || fatbinSize == 0) {
std::cerr << "获取 fatbinary 大小失败,错误码: " << static_cast<int>(result) << std::endl;
hgFatbinDestroy(&handle);
return 1;
}
std::cout << "fatbinary 大小为: " << fatbinSize << " 字节" << std::endl;
// 5. 分配缓冲区并导出 fatbinary
std::vector<unsigned char> fatbinBuffer(fatbinSize);
result = hgFatbinGet(handle, fatbinBuffer.data());
if (result != HGFATBIN_SUCCESS) {
std::cerr << "导出 fatbinary 失败,错误码: " << static_cast<int>(result) << std::endl;
hgFatbinDestroy(&handle);
return 1;
}
std::cout << "fatbinary 导出成功!" << std::endl;
// 可选:将 fatbinary 写入文件
std::ofstream output("output.fatbin", std::ios::binary | std::ios::out);
if (output.is_open()) {
output.write(reinterpret_cast<const char*>(fatbinBuffer.data()), fatbinSize);
output.close();
std::cout << "fatbinary 已写入文件 output.fatbin" << std::endl;
} else {
std::cerr << "无法创建输出文件 output.fatbin" << std::endl;
}
// 6. 销毁句柄
result = hgFatbinDestroy(&handle);
if (result != HGFATBIN_SUCCESS) {
std::cerr << "hgFatbinDestroy 失败,错误码: " << static_cast<int>(result) << std::endl;
return 1;
}
std::cout << "资源已释放。" << std::endl;
return 0;
}
编译运行:
g++ test.cpp -o test -lhgfatbin \
-I /usr/local/PPU_SDK/targets/x86_64-linux/include/
./test
hgFatbinCreate 成功!
hgbin 添加成功!
fatbinary 大小为: 9616 字节
fatbinary 导出成功!
fatbinary 已写入文件 output.fatbin
资源已释放。