LibTorch 稳定 ABI#
创建日期:2025年3月17日 | 最后更新日期:2025年8月19日
此笔记最终将包含更多关于如何在 torch/csrc/stable 中使用 API 的详细信息。目前,它包含了一个内部表示的表格
自定义扩展中的类型:用户自定义库中使用的类型。
StableIValue 表示:类型到用户模型与 libtorch.so 之间进行 ABI 稳定交互的稳定转换。
libtorch 中的类型:libtorch.so (或任何与 libtorch 二进制链接的代码) 中使用的类型。
Schema 类型:由 schema 描述的类型,我们将其视为 native_functions.yaml 中 ATen op 的事实来源,以及通过 TORCH_LIBRARY 或 torch.library 注册到 dispatch 的用户自定义运算符的来源。
自定义扩展中的类型 |
StableIValue 表示 |
libtorch 中的类型 |
Schema 类型 |
---|---|---|---|
std::optional<S> |
如果存在值,则将原始数据按位复制到 uint64_t 的前导字节中,表示 S 的新 StableIValue。如果不存在值,则为 nullptr。 |
std::optional<T> |
类型? |
torch::stable::Tensor |
将底层 AtenTensorHandle 的原始数据按位复制到 uint64_t 的前导字节中 |
at::Tensor |
张量 |
RAIIATH (过时) |
将底层 AtenTensorHandle 的原始数据按位复制到 uint64_t 的前导字节中 |
at::Tensor |
张量 |
torch::headeronly::ScalarType |
将翻译后的底层枚举按位复制到 uint64_t 的前导字节中 |
torch::headeronly::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 会成功。(例如:c10::Device。) 这些类型目前在尽最大努力的基础上是 ABI 稳定的,但将来可能会中断,因此只能用于短期测试。
您可以在自定义内核中始终使用 StableIValue 抽象来处理 c10::Device 等类型的操作,即使在自定义扩展中没有设备的标准定义表示,也可以通过不检查 StableIValue 来实现。例如,自定义运算符可以接受 StableIValue device 作为参数,并直接使用 aoti_torch_call_dispatcher
将其传递给 aten 运算符。
如何使用基于栈的 API#
aoti_torch_call_dispatcher
是我们认为的基于栈的 API,因为它接收 StableIValues 栈作为输入,这与 torch::jit::stack
的 IValues 相关。使用 dispatcher 可能会让您接触到基于栈的 API,因此我们在此记录一些不变性
栈是从左到右填充的。a. 例如,表示参数
arg0
、arg1
和arg2
的栈将在索引 0 处有arg0
,在索引 1 处有arg1
,在索引 2 处有arg2
。b. 返回值也是从左到右填充的,例如,ret0
将在索引 0 处,ret1
将在索引 1 处,依此类推。栈始终拥有其持有的对象的拥有权。a. 调用基于栈的 API 时,您必须将拥有引用传递给调用栈,并从返回栈中窃取引用。b. 注册您的函数以通过栈调用时,您必须从您的参数栈中窃取引用,并将新引用推入栈中。