MaybeOwned<Tensor>#
MaybeOwned<Tensor> 是一個 C++ 智慧指標類,它動態編碼一個 Tensor 是自有 (owned) 還是借用 (borrowed) 的。它在某些對效能敏感的情況下使用,以避免不必要地增加 Tensor 的引用計數(額外的間接訪問會帶來少量開銷)。
警告
使用 MaybeOwned 務必極其謹慎。關於(非)所有權的宣告不會進行靜態檢查,錯誤可能導致引用計數不足 (reference undercounting) 和釋放後使用 (use-after-free) 崩潰。
由於缺乏安全保障,我們不鼓勵在已知非高度效能敏感的程式碼路徑之外使用 MaybeOwned。但是,如果您在想要修改的程式碼中遇到 MaybeOwned 的現有用法,理解如何正確使用它至關重要。
MaybeOwned<Tensor> 的主要用例是函式或方法動態地選擇返回其某個引數(通常來自直通 (passthrough) 或“無操作 (no-op)”程式碼路徑)或返回一個新構造的 Tensor。在這種情況下,此類函式會返回一個 MaybeOwned<Tensor>,前者透過呼叫 MaybeOwned<Tensor>::borrowed() 以“借用 (borrowed)”狀態返回,後者透過呼叫 MaybeOwned<Tensor>::owned() 以“自有 (owned)”狀態返回。
典型的例子是 Tensor 的 expect_contiguous 方法,當 Tensor 已經連續 (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));
}
}
使用生命週期 (lifetimes) 的術語,借用的基本安全要求是:一個借用的 Tensor 必須比任何引用它的借用引用 (borrowing references) 壽命更長。例如,在這裡我們可以安全地借用 *this,但 __dispatch_contiguous() 返回的 Tensor 是新建立的,借用一個引用實際上會使它處於無主 (ownerless) 狀態。
所以,一般經驗法則
如有疑問,完全不要使用
MaybeOwned<Tensor>- 特別是,在尚未使用它的程式碼中避免使用它。只有當帶來關鍵(且可證明)的效能提升時,才應引入新的用法。在修改或呼叫已使用
MaybeOwned<Tensor>的程式碼時,請記住透過呼叫MaybeOwned<Tensor>::owned()從現有 Tensor 生成一個MaybeOwned<Tensor>總是安全的。這可能會導致不必要的引用計數增加,但絕不會導致錯誤行為 (misbehavior) - 因此這總是更安全的做法,除非你想要包裝的 Tensor 的生命週期水晶般清晰 (crystal clear)。
更多詳細資訊和實現程式碼可在 <pytorch/pytorch> 和 <pytorch/pytorch> 中找到。