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() 以“拥有”状态返回。
典型的例子是 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 必须比任何指向它的借用引用更长寿。在这里,例如,我们可以安全地借用 *this,但由 __dispatch_contiguous() 返回的 Tensor 是新创建的,借用一个引用将有效地使其失去所有者。
因此,一般经验法则:
如有疑问,请完全不要使用
MaybeOwned<Tensor>— 特别是,尽量避免在尚未使用它的代码中使用它。只有在关键的(且可证明的)性能提升时,才应引入新的用法。当修改或调用已经使用
MaybeOwned<Tensor>的代码时,请记住,通过调用MaybeOwned<Tensor>::owned()从手中持有的 Tensor 产生一个MaybeOwned<Tensor>总是安全的。这可能会导致不必要的引用计数增加,但绝不会导致行为错误 — 所以这总是更安全的选择,除非您要包装的 Tensor 的生命周期非常明确。
更多详细信息和实现代码可以在 <pytorch/pytorch> 和 <pytorch/pytorch> 中找到。