MaybeOwned<Tensor>¶
MaybeOwned<Tensor>
是一個 C++ 智慧型指標類別,動態編碼 Tensor 是擁有還是借用。它用於某些對效能敏感的情況,以避免不必要地增加 Tensor 的參考計數(但會因額外的間接定址而產生少量額外負擔)。
警告
必須極其謹慎地使用 MaybeOwned。 (非) 擁有權的聲明未經過靜態檢查,錯誤可能會導致參考計數不足和釋放後使用崩潰。
由於缺乏安全網,我們不鼓勵在已知對效能高度敏感的程式碼路徑之外使用 MaybeOwned。但是,如果您在想要修改的程式碼中遇到先前已存在的 MaybeOwned 用法,則了解如何正確使用它至關重要。
MaybeOwned<Tensor>
的主要用例是一個函式或方法,它動態地選擇傳回其參數之一(通常來自直通或「無運算」程式碼路徑)還是傳回新建立的 Tensor。這樣的函式在兩種情況下都會傳回 MaybeOwned<Tensor>
,前者透過呼叫 MaybeOwned<Tensor>::borrowed()
以「借用」狀態傳回,後者透過呼叫 MaybeOwned<Tensor>::owned()
以「擁有」狀態傳回。
典型的範例是 Tensor
的 expect_contiguous
方法,當已經是連續的時,它會捷徑並傳回借用的自我參考
inline c10::MaybeOwned<Tensor> Tensor::expect_contiguous(MemoryFormat memory_format) const & {
if (is_contiguous(memory_format)) {
return c10::MaybeOwned<Tensor>::borrowed(*this);
} else {
return c10::MaybeOwned<Tensor>::owned(__dispatch_contiguous(memory_format));
}
}
使用生命週期的詞彙,借用的基本安全要求是,借用的 Tensor 必須比任何借用它的參考更長壽。例如,在這裡,我們可以安全地借用 *this
,但是由 __dispatch_contiguous()
傳回的 Tensor 是新建立的,而借用參考實際上會使其變成無所有者。
因此,一般經驗法則
當有疑問時,完全不要使用
MaybeOwned<Tensor>
- 特別是,盡量避免在尚未使用的程式碼中使用它。只有在產生關鍵(且可證明的)效能提升時,才應引入新的用法。當修改或呼叫已經使用
MaybeOwned<Tensor>
的程式碼時,請記住,透過呼叫MaybeOwned<Tensor>::owned()
,從手邊的 Tensor 產生MaybeOwned<Tensor>
始終是安全的。這可能會導致不必要的參考計數,但絕不會導致行為不當 - 因此,除非您要包裝的 Tensor 的生命週期非常清楚,否則這始終是更安全的選擇。
更多詳細資訊和實作程式碼可以在 <https://github.com/pytorch/pytorch/blob/main/c10/util/MaybeOwned.h> 和 <https://github.com/pytorch/pytorch/blob/main/aten/src/ATen/templates/TensorBody.h> 中找到。