評價此頁

MaybeOwned<Tensor>#

MaybeOwned<Tensor> 是一個 C++ 智慧指標類,它動態地編碼 Tensor 是擁有的還是借用的。它用於某些效能敏感的場景,以避免不必要地增加 Tensor 的引用計數(儘管額外的間接訪問會帶來少量開銷)。

警告

必須極其謹慎地使用 MaybeOwned。所有權(或非所有權)的宣告不是靜態檢查的,錯誤可能導致引用計數不足和使用後釋放(use-after-free)崩潰。

由於缺乏這種安全保障,我們不鼓勵在已知效能高度敏感的程式碼路徑之外使用 MaybeOwned。但是,如果您在要修改的程式碼中遇到預先存在的 MaybeOwned 用法,理解如何正確使用它至關重要。

MaybeOwned<Tensor> 的主要用例是函式或方法,它動態地在返回其引數之一(通常來自 passthrough 或“無操作”程式碼路徑)和返回新構造的 Tensor 之間進行選擇。這樣的函式將在兩種情況下都返回一個 MaybeOwned<Tensor>,前者透過呼叫 MaybeOwned<Tensor>::borrowed() 以“借用”狀態返回,後者透過呼叫 MaybeOwned<Tensor>::owned() 以“擁有”狀態返回。

典型的例子是 Tensorexpect_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 必須比任何指向它的借用引用更長壽。在這裡,例如,我們可以安全地借用 *this,但由 __dispatch_contiguous() 返回的 Tensor 是新建立的,借用一個引用將有效地使其失去所有者。

因此,一般經驗法則:

  • 如有疑問,請完全不要使用 MaybeOwned<Tensor> — 特別是,儘量避免在尚未使用它的程式碼中使用它。只有在關鍵的(且可證明的)效能提升時,才應引入新的用法。

  • 當修改或呼叫已經使用 MaybeOwned<Tensor> 的程式碼時,請記住,透過呼叫 MaybeOwned<Tensor>::owned() 從手中持有的 Tensor 產生一個 MaybeOwned<Tensor> 總是安全的。這可能會導致不必要的引用計數增加,但絕不會導致行為錯誤 — 所以這總是更安全的選擇,除非您要包裝的 Tensor 的生命週期非常明確。

更多詳細資訊和實現程式碼可以在 <pytorch/pytorch> 和 <pytorch/pytorch> 中找到。