hglink&hgJitLink使用指南(v2.1)

更新时间:
复制为 MD 格式

概述

在 PPU 工具链中,hglinkhgJitlink 都是处理设备代码链接的关键工具,但它们的应用场景和工作阶段不同:

  • hglink是编译时静态编译链接工具

    • 主要负责在静态编译阶段将多个设备代码模块(如 cubin)链接为单一的设备代码镜像(如 .cubin 或库文件.a/.so),同时可在链接时执行跨文件优化,通过解析设备函数/全局变量的跨模块引用,执行代码布局优化等链接时优化。

    • 通常在编译器启用-rdc=true编译多个.cu文件后被自动调用。

  • hgJitlink是运行时动态编译链接工具

    • 主要负责在程序执行阶段动态地链接设备代码,支持加载由HGRTC(Runtime Compilation)编译的代码片段,实现运行时扩展。

    • 通常在用户代码中通过api调用。

SDK工具链实现中,hglinkhgJitlink使用同一套底层实现,并分别封装为面向静态编译的可执行工具、面向动态编译的库(通过API提供给用户调用)。需要注意的是,hglinkhgJitlink 暂时不支持PTX文件作为输入。

hglink使用介绍

hglink是通过SDK中的可执行命令行工具提供给用户使用的,其使用方式是:

  • hglink [options] <objects>

其中<objects>是用户需要执行链接的文件,[options]是可选择的命令行选项,它支持如下命令行选项:

options

alias

Desctiption

--arch

Specify the 'ppu' name of the target architecture. Allowed values for this option: 'ppu001', 'ppu0015', 'ppu0017'. Default value: 'ppu001'.

--emit-hgvm

Emit hgvm file if LTO is used.

--help

-h

Print this help information on this tool.

--hgvm-file

Specify name and location of the output hgvm file.

--library-path

-L

,... Specify library search paths.

--library ,...

--library=, -l

Specify libraries to be used in the linking stage. The libraries are searched for on the library search paths that have been specified using option '-L'.

--link-time-opt

-lto, --dlto

Do link-time optimization.

--output-file

-o

Specify name and location of the output file.

--register-link-binaries=

Specify name and location of output file that will contain names of hggcRegister routines for each linked file.

--register-link-binaries

Specify name and location of output file that will contain names of hggcRegister routines for each linked file.

--verbose

-v

Enable verbose mode which prints code generation statistics.

--version

-V

Print version information on this tool.

--Xhgvm

Hgvm options (only used with LTO).

--XLinker

link options to lld

--options-file

Include command line options from specified file

hgJitLink使用介绍

hgJitLink通过API的形式提供给用户使用,具体的API定义及释义如下表:

函数定义

概述

参数含义

返回值

hgJitLinkCreate(hgJitLinkHandle* handle, unsigned int numOptions, const char** options)

创建 JIT 链接器实例

- handle: 输出句柄指针 - numOptions: JIT 选项数量 - options: JIT 选项字符串数组

hgJitLinkResult (错误码)

hgJitLinkAddFile(hgJitLinkHandle handle, hgJitLinkInputType inputType, const char* fileName)

从文件添加设备代码

- handle: 链接器句柄 - inputType: 文件类型(PTX/CUBIN等) - fileName: 文件路径

hgJitLinkResult

hgJitLinkAddData(hgJitLinkHandle handle, hgJitLinkInputType inputType, const void* data, size_t size, const char* name)re

从内存添加设备代码

- handle: 链接器句柄 - inputType: 数据类型 - data: 代码指针 - size: 代码大小 - name: 模块标识名

hgJitLinkResult

hgJitLinkComplete(hgJitLinkHandle handle)

执行链接操作

- handle: 链接器句柄

hgJitLinkResult

hgJitLinkGetLinkedCubinSize(hgJitLinkHandle handle, size_t* size)

获取链接后 CUBIN 大小

- handle: 链接器句柄 - size: 输出大小值指针

hgJitLinkResult

hgJitLinkGetLinkedCubin(hgJitLinkHandle handle, void* cubin)

获取链接后 CUBIN 代码

- handle: 链接器句柄 - cubin: 输出缓冲区指针

hgJitLinkResult

hgJitLinkGetLinkedPtxSize(hgJitLinkHandle handle, size_t* size)

获取链接后 PTX 大小

- handle: 链接器句柄 - size: 输出大小值指针

hgJitLinkResult

hgJitLinkGetLinkedPtx(hgJitLinkHandle handle, char* ptx)

获取链接后 PTX 代码

- handle: 链接器句柄 - ptx: 输出缓冲区指针

hgJitLinkResult

hgJitLinkGetRegLinkBinSize(hgJitLinkHandle handle, size_t *size);

获取链接、注册后的二进制大小

- handle: 链接器句柄 - size: 输出大小值指针

hgJitLinkResult

hgJitLinkGetRegLinkBin(hgJitLinkHandle handle, void *linkBin);

获取链接、注册后的二进制文件

- handle: 链接器句柄 - linkBin: 输出缓冲区指针

hgJitLinkResult

hgJitLinkGetErrorLogSize(hgJitLinkHandle handle, size_t* size)

获取错误日志大小

- handle: 链接器句柄 - size: 输出日志大小指针

hgJitLinkResult

hgJitLinkGetErrorLog(hgJitLinkHandle handle, char* log)

获取错误日志内容

- handle: 链接器句柄 - log: 输出日志缓冲区

hgJitLinkResult

hgJitLinkGetInfoLogSize(hgJitLinkHandle handle, size_t* size)

获取信息日志大小

- handle: 链接器句柄 - size: 输出大小指针

hgJitLinkResult

hgJitLinkGetInfoLog(hgJitLinkHandle handle, char* log)

获取信息日志内容

- handle: 链接器句柄 - log: 输出日志缓冲区

hgJitLinkResult

hgJitLinkDestroy(hgJitLinkHandle* handle)

销毁链接器实例

- handle: 链接器句柄指针

hgJitLinkResult

hgJitLinkVersion(const char** version);

返回当前hgjitlink的版本

- version: 输出版本缓冲区

hgJitLinkResult


hgJitLink选项说明

options

alias

Desctiption

--arch

Specify the 'ppu' name of the target architecture. Allowed values for this option: 'ppu001', 'ppu0015', 'ppu0017'. Default value: 'ppu001'.

--link-time-opt

-lto, --dlto

Do link-time optimization.

--verbose

-v

Enable verbose mode which prints code generation statistics.

--time

-time

Print timing information to InfoLog

-g

Generate debug information

-ftz=

Flush to zero.

-prec-div=

Precise divide.

-prec-sqrt=

Precise square root.

-fma=

Fast multiply add.

-kernels-used=

Pass list of kernels that are used; any not in the list can be removed. This option can be specified multiple times.

-variables-used=

Pass list of variables that are used; any not in the list can be removed. This option can be specified multiple times.

-optimize-unused-variables

Normally device code optimization is limited by not knowing what the host code references. With this option it can assume that if a variable is not referenced in device code then it can be removed.

关键类型说明

  1. hgJitLinkHandle

    • 不透明void指针,表示 JIT 链接会话 (typedef void* hgJitLinkHandle)。

  2. hgJitLinkInputType (输入类型枚举)

typedef enum {
  hgJitLink_INPUT_NONE = 0,  // 错误文件类型
  hgJitLink_INPUT_CUBIN = 1, // CUBIN 二进制
  hgJitLink_INPUT_PTX,		 // PTX 文件
  hgJitLink_INPUT_LTOIR,	 // LTO 中间表示
  hgJitLink_INPUT_FATBIN,	 // 多架构 Fatbin文件
  hgJitLink_INPUT_OBJECT,	 // 对象文件
  hgJitLink_INPUT_LIBRARY,	 // 库文件
  hgJitLink_INPUT_ANY = 10   // 动态确定为上述类型之一
} hgJitLinkInputType;
  1. hgJitLinkResult (错误码枚举)

typedef enum {
  hgJitLink_SUCCESS = 0,				// 成功
  hgJitLink_ERROR_UNRECOGNIZED_OPTION,	// 无效选项
  hgJitLink_ERROR_MISSING_ARCH, 		// 未指定架构
  hgJitLink_ERROR_INVALID_INPUT,		// 无效输入
  hgJitLink_ERROR_PTX_COMPILE,			// PTX 编译失败
  hgJitLink_ERROR_HGVM_COMPILE,			// HGVM 编译失败
  hgJitLink_ERROR_INTERNAL,				// 内部错误
  hgJitLink_ERROR_THREADPOOL,			// 线程池错误
  hgJitLink_ERROR_UNRECOGNIZED_INPUT,	// 无法识别的输入
  hgJitLink_ERROR_NULL_INPUT,			// 空输入
  hgJitLink_ERROR_INCOMPATIBLE_OPTIONS,	// 不兼容的选项
  hgJitLink_ERROR_INCORRECT_INPUT_TYPE, // 不正确的输入类型
  hgJitLink_ERROR_ARCH_MISMATCH,		// 架构不匹配
  hgJitLink_ERROR_OUTDATED_LIBRARY,		// 过时的库错误
  hgJitLink_ERROR_MISSING_FATBIN		// fatbin缺失错误
} hgJitLinkResult;

典型工作流代码

hgJitLinkHandle handle;

const char* options[ ] = {"-arch=sm_80"};

hgJitLinkCreate(&handle, 1, options);  // Step 1: 创建实例

// Step 2: 添加设备代码 (例如 LTO_IR)
hgJitLinkAddData(handle, hgJitLink_INPUT_LTOIR, ltoir_code, ltoir_size, "my_kernel");

hgJitLinkComplete(handle);  // Step 3: 执行链接

// Step 4: 获取链接结果
size_t cubin_size;
hgJitLinkGetLinkedCubinSize(handle, &cubin_size);
void* cubin = malloc(cubin_size);
hgJitLinkGetLinkedCubin(handle, cubin);

// Step 5: 加载到 GPU
HGmodule module;
hgModuleLoadData(&module, cubin);

hgJitLinkDestroy(&handle);  // Step 6: 清理资源