LibTorch 稳定 ABI#
创建日期:2025 年 3 月 17 日 | 最后更新日期:2025 年 6 月 17 日
本文档最终将包含有关如何使用 torch/csrc/stable 中 API 的更多详细信息。目前,它包含一个内部表示表。
自定义扩展中的类型:最终用户自定义库中使用的类型。
StableIValue 表示:将类型稳定转换为用户模型与 libtorch.so 之间进行 ABI 稳定联络的方式。
libtorch 中的类型:libtorch.so(或任何与 libtorch 二进制锁定的代码)中使用的类型。
Schema 类型:由 Schema 描述的类型,我们将其视为 native_functions.yaml 中 ATen 操作和通过 TORCH_LIBRARY 或 torch.library 注册到调度器的用户定义自定义操作的真相来源。
自定义扩展中的类型 |
StableIValue 表示 |
libtorch 中的类型 |
Schema 类型 |
---|---|---|---|
std::optional<S> |
如果存在值,则将原始位复制到指向代表 S 的新 StableIValue 的 uint64_t 前导字节中。如果不存在值,则为 nullptr。 |
std::optional<T> |
Type? |
RAIIATH |
将底层 AtenTensorHandle 的原始位复制到 uint64_t 的前导字节中 |
at::Tensor |
张量 |
int32_t |
将原始位复制到 uint64_t 的前导字节中 |
at::ScalarType |
ScalarType |
int32_t |
将原始位复制到 uint64_t 的前导字节中 |
at::Layout |
Layout |
int32_t |
将原始位复制到 uint64_t 的前导字节中 |
at::MemoryFormat |
MemoryFormat |
布尔值 |
将原始位复制到 uint64_t 的前导字节中 |
布尔值 |
布尔值 |
int64_t |
将原始位复制到 uint64_t 的前导字节中 |
int64_t |
int |
double |
将原始位复制到 uint64_t 的前导字节中 |
double |
浮点数 |
? |
? |
c10::Device |
设备 |
? |
? |
c10::Stream |
流 |
? |
? |
c10::complex |
complex |
? |
? |
at::Scalar |
Scalar |
? |
? |
std::string/const char*/ivalue::ConstantString |
str |
? |
? |
at::Storage |
Storage |
? |
? |
at::Generator |
生成器 |
? |
? |
c10::List<T> |
Type[] |
? |
? |
ivalue::Tuple<T> |
(Type, …) |
? |
? |
c10::SymInt |
SymInt |
? |
? |
c10::SymFloat |
SymFloat |
? |
? |
c10::SymBool |
SymBool |
? |
? |
at::QScheme |
QScheme |
我们自信支持的类型是表格中已完成行的类型。您可以依赖此子集实现适当的 ABI 稳定性。
对于有限的一组用例,我们还隐式支持任何可表示为 64 位的字面类型作为 StableIValues,因为默认的 reinterpret_cast 将成功。这些类型目前在尽力而为的基础上是 ABI 稳定的,但将来可能会中断,因此应仅用于短期测试。
即使自定义扩展中没有标准的设备表示,您也可以通过不内省 StableIValue 来在自定义内核中使用 StableIValue 抽象,例如 c10::Device。例如,自定义操作符可以将 StableIValue device 作为参数,并使用 aoti_torch_call_dispatcher
将其直接传递给 aten 操作符。
如何使用基于堆栈的 API#
aoti_torch_call_dispatcher
是我们认为的基于堆栈的 API,因为它接受 StableIValues 堆栈作为输入。与调度器一起工作可能会让您接触到基于堆栈的 API,因此我们在此记录一些不变性
堆栈从左到右填充。a. 例如,表示参数
arg0
、arg1
和arg2
的堆栈将把arg0
放在索引 0,arg1
放在索引 1,arg2
放在索引 2。b. 返回值也从左到右填充,例如,ret0
将在索引 0,ret1
将在索引 1,以此类推。堆栈始终拥有其所持有的对象。a. 调用基于堆栈的 API 时,您必须将拥有引用提供给调用堆栈,并从返回堆栈中窃取引用。b. 将您的函数注册为通过堆栈调用时,您必须从您的参数堆栈中窃取引用,并将新引用推送到堆栈上。