評價此頁

LibTorch 穩定 ABI#

建立日期:2025年3月17日 | 最後更新日期:2025年8月19日

此筆記最終將包含更多關於如何在 torch/csrc/stable 中使用 API 的詳細資訊。目前,它包含了一個內部表示的表格

  1. 自定義擴充套件中的型別:使用者自定義庫中使用的型別。

  2. StableIValue 表示:型別到使用者模型與 libtorch.so 之間進行 ABI 穩定互動的穩定轉換。

  3. libtorch 中的型別:libtorch.so (或任何與 libtorch 二進位制連結的程式碼) 中使用的型別。

  4. 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,因此我們在此記錄一些不變性

  1. 棧是從左到右填充的。a. 例如,表示引數 arg0arg1arg2 的棧將在索引 0 處有 arg0,在索引 1 處有 arg1,在索引 2 處有 arg2。b. 返回值也是從左到右填充的,例如,ret0 將在索引 0 處,ret1 將在索引 1 處,依此類推。

  2. 棧始終擁有其持有的物件的擁有權。a. 呼叫基於棧的 API 時,您必須將擁有引用傳遞給呼叫棧,並從返回棧中竊取引用。b. 註冊您的函式以透過棧呼叫時,您必須從您的引數棧中竊取引用,並將新引用推入棧中。