C++ API 参考

头文件与命名空间

#include <lacinfer/lacinfer.hpp>

除数据类型枚举 lacinfer_shape_datatype_t 外,本章 API 均位于 lacinfer 命名空间。C++ API 将底层句柄封装为对象,并自动管理其创建、复制、移动和销毁;用户通常不需要手动释放相关资源。

数据类型

lacinfer_shape_datatype_t

张量元素类型枚举。

枚举值 含义
lacinfer_shape_tuple_type 元组形状,不表示普通数值张量
lacinfer_shape_fp4x2_type 两个打包的 4 位浮点值 [实验性]
lacinfer_shape_bool_type 布尔值
lacinfer_shape_half_type IEEE FP16 [实验性]
lacinfer_shape_float_type IEEE FP32
lacinfer_shape_double_type IEEE FP64
lacinfer_shape_uint8_type 无符号 8 位整数
lacinfer_shape_int8_type 有符号 8 位整数
lacinfer_shape_uint16_type 无符号 16 位整数
lacinfer_shape_int16_type 有符号 16 位整数
lacinfer_shape_int32_type 有符号 32 位整数
lacinfer_shape_int64_type 有符号 64 位整数
lacinfer_shape_uint32_type 无符号 32 位整数
lacinfer_shape_uint64_type 无符号 64 位整数
lacinfer_shape_fp8e4m3fnuz_type FP8 E4M3 FNUZ1 [实验性]
lacinfer_shape_fp8e4m3fn_type FP8 E4M3 FN [实验性]
lacinfer_shape_fp8e5m2_type FP8 E5M2 [实验性]
lacinfer_shape_bf16_type BF16 [实验性]
lacinfer_shape_fp8e5m2fnuz_type FP8 E5M2 FNUZ [实验性]

上述 FP4、FP8、FP16 和 BF16 类型在当前版本中属于 [实验性] 类型,其兼容性和行为可能在后续版本中调整。

动态维度 [实验性]

lacinfer::optimals

保存动态维度的优选取值。

explicit optimals(std::initializer_list<size_t> values);

优选值用于提示编译器重点优化的实际维度。每个值应位于动态维度的 [min, max] 范围内。

lacinfer::dynamic_dimension

dynamic_dimension(size_t min, size_t max);
dynamic_dimension(size_t min, size_t max, const optimals& opts);
bool is_fixed() const;
bool operator==(const dynamic_dimension&, const dynamic_dimension&);
bool operator!=(const dynamic_dimension&, const dynamic_dimension&);
成员 说明
min 允许运行时维度的下界
max 允许运行时维度的上界
opts 可选的优选维度集合
is_fixed() 当最小值与最大值相同时返回 true

lacinfer::dynamic_dimensions

动态维度容器,用于构造动态 shape。

template<class... Ts>
dynamic_dimensions(const Ts&... dimensions);

size_t size() const;
dynamic_dimension operator[](size_t index) const;

调用 operator[] 前,应确保 index < size();该接口不保证对越界索引进行检查。

张量形状(lacinfer::shape)

描述张量的数据类型、维度和步长。

构造函数

shape();
explicit shape(lacinfer_shape_datatype_t type);
shape(lacinfer_shape_datatype_t type, std::vector<size_t> lengths);
shape(lacinfer_shape_datatype_t type,
      std::initializer_list<size_t> lengths);
shape(lacinfer_shape_datatype_t type,
      std::vector<size_t> lengths,
      std::vector<size_t> strides);
shape(lacinfer_shape_datatype_t type,
      const dynamic_dimensions& dyn_dims);
  • 只传 type 时构造标量形状。

  • 传 lengths 时自动计算紧凑布局步长。

  • 显式步长构造函数可描述转置、广播或非紧凑布局;lengths 与 strides 的元素个数必须一致。

  • 动态形状使用接受 dynamic_dimensions 的构造函数;静态形状使用接受 lengths 的构造函数。两种构造方式不能混用。

  • 默认构造对象不表示可用张量,调用查询成员函数前应先赋入有效形状。

查询成员函数

std::vector<size_t> lengths() const;
std::vector<size_t> strides() const;
dynamic_dimensions dyn_dims() const;
lacinfer_shape_datatype_t type() const;
size_t elements() const;
size_t bytes() const;
bool standard() const;
bool dynamic() const;
size_t index(size_t linear_index) const;
成员 返回值
lengths() 各维静态长度
strides() 各维步长,以元素为单位
dyn_dims() 各维动态范围;仅对动态形状有意义
type() 元素类型枚举
elements() 逻辑元素总数
bytes() 形状所需字节数
standard() 是否为标准布局
dynamic() 是否包含动态维度
index(i) 将逻辑线性索引映射为缓冲区空间索引

形状支持 == 和 !=。比较包含类型及布局信息,而不仅是各维长度。

张量数据(lacinfer::argument)

argument 把 shape 与一段数据缓冲区关联。

构造与访问

argument();
explicit argument(shape s);
argument(shape s, void* buffer);

shape get_shape() const;
char* data() const;

template<typename T>
std::vector<T> as_vector() const;
  • argument(s) 创建与形状对应的空参数对象。

  • argument(s, buffer) 引用外部缓冲区,不接管 buffer 的生命周期。

  • data() 返回底层地址。

  • as_vector<T>() 按形状索引将数据复制到 std::vector<T>;T 必须与实际元素类型兼容。

参数序列化

static void save_argument(const argument& value,
                          const std::string& filename);
static argument load_argument(const std::string& filename);
static argument generate(shape s, size_t seed = 0);

save_argument 与 load_argument 使用参数序列化格式保存或恢复形状和数据。generate 使用指定种子生成测试数据;相同版本、形状和种子可用于构造可重复的测试输入,但不应把它用作安全随机源。

argument 支持 == 和 !=。

编译目标(lacinfer::target)

表示编译目标。

target();
explicit target(const char* name);

当前发布版本支持 "gpu" 和 "ref"。传入其他名称会导致异常。默认构造的对象必须先赋值为有效目标,才能用于编译。

程序输入与输出

lacinfer::program_parameter_shapes

程序输入名到形状的只读映射。

size_t size() const;
shape operator[](const char* name) const;
std::vector<const char*> names() const;

names() 返回的名称指针由底层对象拥有,不应释放;容器失效后不得继续使用这些指针。

lacinfer::program_parameters

程序输入名到参数值的映射。

program_parameters();
program_parameters(
    std::initializer_list<std::pair<std::string, argument>> values);
void add(const char* name, const argument& value) const;

名称必须与 program::get_parameter_shapes() 返回的参数名称一致。

lacinfer::arguments

程序输出参数序列。

size_t size() const;
argument operator[](size_t index) const;

该类型支持基于索引的访问以及由公共数组基类提供的迭代、empty() 等容器操作。

lacinfer::shapes

形状序列。

size_t size() const;
shape operator[](size_t index) const;

建图对象

lacinfer::operation

描述操作名称与属性。

template<class... Ts>
operation(const char* name,
          const char* json_attributes = nullptr,
          Ts... values);

std::string name();

json_attributes 是操作属性的 JSON 文本。属性集合由相应操作定义决定。

lacinfer::instruction

模块中指令的不透明引用。它主要作为 module 添加指令和返回值时的输入或结果使用。

lacinfer::instructions 与 lacinfer::modules

template<class... Ts>
instructions(const Ts&... instructions);

template<class... Ts>
modules(const Ts&... modules);

这两个辅助容器分别向 API 传递指令序列与子模块序列。

lacinfer::module

module 表示程序中的一个计算图模块。它引用所属 program 的内部数据;使用 module 对象期间,必须确保对应的 program 仍然有效。

void print() const;

instruction add_instruction(const operation& op,
                            const instructions& args);
instruction add_instruction(const operation& op,
                            const instructions& args,
                            const modules& module_args);

template<typename T>
instruction add_literal(const shape& s, T* buffer);

instruction add_parameter(const std::string& name, shape s);
instruction add_return(const instructions& args);
instruction add_allocation(const shape& s);

add_literal 会把给定数据加入图中;缓冲区必须至少包含 s.bytes() 字节。带 module_args 的 add_instruction 用于控制流等具有子模块参数的操作。

编译选项

lacinfer::compile_options

compile_options();
void set_offload_copy(bool value = true);
void set_fast_math(bool value = true);
void set_exhaustive_tune_flag(bool value = true);
选项 说明
offload_copy 为 GPU 等使用独立设备内存的目标,在编译时加入必要的数据复制:将输入从主机内存复制到设备内存,并将结果复制回主机内存
fast_math 使用更快的近似数学实现,可能产生轻微精度差异
exhaustive_tune 扩大内核搜索范围以寻找更快实现,增加首次编译时间

程序(lacinfer::program)

程序保存一个或多个模块,并提供编译和执行入口。

构造、编译与查询

program();

void compile(const target& t) const;
void compile(const target& t, const compile_options& options) const;
program_parameter_shapes get_parameter_shapes() const;
shapes get_output_shapes() const;

compile 原地修改程序。量化和图修改应在编译前完成;已为一个目标编译的程序不应直接当作另一个目标的未编译程序使用。

执行

arguments eval(const program_parameters& params) const;

template<class Stream>
arguments run_async(const program_parameters& params, Stream* stream) const;
  • eval 执行已编译程序并返回全部输出。

  • run_async 在调用方提供的原生流上提交工作。流类型名会传递给运行时,因此必须使用执行目标支持的流指针类型。

  • 输入名称、类型、形状和内存位置必须符合编译后的程序要求。

图与诊断

void print() const;
program sort();
module get_main_module();
module create_module(const std::string& name);

sort() 原地按拓扑关系整理程序并返回当前程序。print() 向标准输出打印程序文本。create_module() 创建命名子模块。

程序支持 == 和 !=。

ONNX 解析

lacinfer::onnx_options

onnx_options();
void set_input_parameter_shape(const std::string& name,
                               std::vector<size_t> dims);
void set_dyn_input_parameter_shape(const std::string& name,
                                   const dynamic_dimensions& dims);
void set_default_dim_value(unsigned int value);
void set_default_dyn_dim_value(const dynamic_dimension& dim);
void set_default_loop_iterations(int64_t value);
void set_limit_loop_iterations(int64_t value);
void set_external_data_path(const std::string& path);
成员 说明
set_input_parameter_shape 覆盖指定输入的静态维度
set_dyn_input_parameter_shape 覆盖指定输入的动态维度范围
set_default_dim_value 为未确定的维度使用固定默认值
set_default_dyn_dim_value 为未确定的维度使用默认动态范围
set_default_loop_iterations 当 Loop2 未提供迭代次数时采用的默认值
set_limit_loop_iterations Loop 允许的最大迭代上限
set_external_data_path ONNX 外部权重文件的绝对目录

同一个输入不要同时配置静态和动态覆盖。外部数据路径应指向文件所在目录,而不是单个权重文件。

文件解析

program parse_onnx(const char* filename);
program parse_onnx(const char* filename, const onnx_options& options);

内存解析

program parse_onnx_buffer(const void* data, size_t size);
program parse_onnx_buffer(const void* data,
                          size_t size,
                          const onnx_options& options);
program parse_onnx_buffer(const std::string& buffer);
program parse_onnx_buffer(const std::string& buffer,
                          const onnx_options& options);

缓冲区必须包含完整模型数据,并在函数返回前保持有效。解析成功后返回未编译的 program。

查询 ONNX 操作

std::vector<std::string> get_onnx_operators();

返回当前构建支持的 ONNX 操作名称。

量化

量化 API 原地修改程序,应在 program::compile() 之前调用。

INT8

struct quantize_int8_options
{
    quantize_int8_options();
    void add_op_name(const std::string& name);
    void add_calibration_data(const program_parameters& params);
    void set_force_i8_output(bool value);
    void set_save_quantized_lir_path(const std::string& path);
    void add_asymmetric_activation_op(const std::string& op_name);
    void add_per_channel_op(const std::string& op_name);
    void add_node_to_exclude(const std::string& node_name);
};

void quantize_int8(const program& p,
                   const target& t,
                   const quantize_int8_options& options);
配置 说明
add_op_name 增加需要量化的操作名
add_calibration_data 增加一组校准数据
set_force_i8_output 为可量化的浮点模型输出插入对称 INT8 量化 [实验性]
set_save_quantized_lir_path 非空时将量化后的程序以 LIR 格式保存到指定路径
add_asymmetric_activation_op 对指定操作名的激活输入启用非对称量化 [实验性]
add_per_channel_op 对指定操作启用逐通道量化
add_node_to_exclude 按源模型节点名排除量化;名称精确匹配 [实验性]

INT8 校准数据的参数名、类型与形状必须覆盖程序输入。目标用于执行校准过程。

add_op_name 接受 LACInfer 内部操作名,而不是源模型节点名。未调用该方法时,默认量化以下所有支持操作;调用后,只量化通过该方法加入的操作。

add_op_name 参数值 操作
dot 点积或矩阵乘法
convolution 正向卷积
convolution_backwards 反向卷积
pooling 仅支持平均池化(Average Pooling) [实验性]
add 加法
sdpa 缩放点积注意力

逐通道量化当前支持以下操作名:

add_per_channel_op 参数值 量化对象 通道轴
convolution 第 2 个输入,即权重 0
convolution_backwards 第 2 个输入,即权重 1

add_asymmetric_activation_op 当前支持以下操作名:

参数值 量化对象
convolution 第 1 个输入,即激活输入;权重仍采用对称量化

启用非对称激活量化会导致性能下降,当前版本不推荐使用;仅在对 mAP 有极高要求,并经实际模型精度与性能测试确认收益后考虑启用。

nodes_to_exclude 只对具有源模型节点名、且进入 INT8 量化候选的节点生效。名称必须精确匹配;未命名、名称未知或在量化前已被优化掉的节点不会被排除。

FP16 与 BF16 [实验性]

struct quantize_op_names
{
    quantize_op_names();
    void add(const std::string& name);
};

void quantize_fp16(const program& p);
void quantize_fp16(const program& p, const quantize_op_names& names);
void quantize_bf16(const program& p);
void quantize_bf16(const program& p, const quantize_op_names& names);

不传 names 时使用默认操作集合;传入集合时只转换指定操作类型。

FP8 [实验性]

struct quantize_fp8_options
{
    quantize_fp8_options();
    void add_calibration_data(const program_parameters& params);
};

void quantize_fp8(const program& p,
                  const target& t,
                  const quantize_fp8_options& options);

quantize_fp8() 使用校准数据将程序原地量化为 FP8。每组校准数据的参数名、类型和形状必须与程序输入匹配;目标 t 用于执行校准过程。

程序持久化

lacinfer::file_options

file_options();
void set_file_format(const char* format);

支持的格式为 "msgpack" 和 "json"。MsgPack 更紧凑,适合部署;JSON 便于检查和调试。

load

program load(const char* filename);
program load(const char* filename, const file_options& options);

加载已序列化的程序。文件是否包含可直接运行的已编译状态取决于保存内容和运行环境;部署时应保证目标和软件版本兼容。

save

void save(const program& p, const char* filename);
void save(const program& p,
          const char* filename,
          const file_options& options);

上下文与异步执行

context program::experimental_get_context();

返回由程序编译目标创建的执行上下文。该上下文保存目标相关的运行时状态;例如,在 GPU 目标下可用于等待任务完成或获取原生执行队列。此接口为 [实验性]。

void context::finish() const;

等待上下文中的工作完成。

template<class T>
T context::get_queue();

将原生队列地址转换为调用方指定类型,类型错误会导致未定义行为;仅在需要与外部运行时共享队列时使用。

1. E4 表示指数部分占 4 位(Exponent),M3 表示尾数部分占 3 位(Mantissa);FN 表示支持有限数和 NaN,但不支持无穷大(Finite and NaN);UZ 表示零不区分正负(Unsigned Zero)。 ↩
2. Loop 是 ONNX 的循环控制流操作,它根据最大迭代次数和循环条件重复执行循环体子图。 ↩
©龙芯开源社区 all right reserved,powered by Gitbook文档更新时间: 2026-09-30 13:16:32

results matching ""

    No results matching ""

    results matching ""

      No results matching ""