hgfatbinary使用指南(v2.1)

更新时间:
复制为 MD 格式

1. 概述

hgfatbinaryPPU Fatbinary文件管理工具。在PPU中,Fatbinary 是一种特殊的文件格式,它可以将多个PPU架构的代码打包到单一文件中,使驱动程序能够根据运行时可用的硬件自动选择最合适的二进制进行加载,主要功能如下:

  • 多架构支持:在一个文件中包含针对不同PPU硬件架构的编译代码。

  • 运行时选择:驱动程序启动时自动检测硬件并加载匹配架构的二进制。

  • 减少部署复杂度:避免为不同设备维护多个二进制文件。

  • 压缩优化:内置压缩功能减小二进制体积。

1.1. 工作原理

  1. PPU SDK在编译过程中可以为多个设备架构的生成对应的设备代码包括(如 ByteCode、DeviceBinary等)。

  2. 编译器会调用hgfatbinary工具将这些文件打包成一个 fatbinary 文件。

  3. 链接器将 fatbinary 嵌入到最终可执行文件中。

  4. 运行时根据硬件自动加载适合架构二进制。

2. 使用介绍

2.1. 命令行选项

选项

参数

描述

默认值/说明

基础架构选项

--64

指定这是 64 位编译

-hggc

指定使用 HGGC 架构

编译类型选项

--debug

指定这是调试编译

注意:当前版本未支持

-g

--debug 的别名

注意:当前版本未支持

--device-c

指定包含可重定位代码

注意:当前版本未支持

--link

指定包含已链接代码

文件操作选项

--create

<file name>

创建包含 fat 二进制的文件

需指定文件名

--embedded-fatbin

<file name>

指定 C include文件的名称,该文件定义了嵌入式 fatbinary 描述符,用于保存所有"内部"镜像

需指定文件名
注意:不使用此选项时,所有"内部"镜像将被忽略,且不会生成嵌入式 fatbinary 文件

代码镜像指定选项

--image

<image spec>,...

指定带有编译配置文件的镜像列表
允许的关键字: file, profile

用于单 SM 架构

--image2

<image spec>,...

指定带有类型和编译器配置的镜像列表(允许多个 SM 在一个文件中,例如主机对象、库)
允许的关键字: file, kind

用于多 SM 架构

--image3

<image spec>,...

指定带有类型和编译它的 SM 的镜像列表
允许的关键字: file, kind, sm

用于详细 SM 规格

--no-asm

指定输出 fatbin 不应使用汇编

注意:当前版本未支持

压缩选项

--compress-all

压缩 fatbinary 中的所有镜像

默认压缩算法:ZSTD

--compress

<value>

压缩 fatbinary 中的IRELF镜像

默认值: 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
资源已释放。