MaybeOwned<Tensor>¶
MaybeOwned<Tensor>
是一个 C++ 智能指针类,它动态地编码张量是 *拥有* 还是 *借用*。它用于某些性能敏感的情况,以避免不必要地增加张量的引用计数(以少量额外的间接寻址开销为代价)。
警告
MaybeOwned 必须非常小心地使用。对(非)所有权的声明不会进行静态检查,错误会导致引用计数不足和使用后释放崩溃。
由于缺乏安全保障,我们不鼓励在已知高度性能敏感的代码路径之外使用 MaybeOwned。但是,如果您在要修改的代码中遇到现有 MaybeOwned 的使用,则必须了解如何正确使用它。
MaybeOwned<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));
}
}
使用生命周期的词汇表,借用的基本安全要求是借用的张量必须比对它的任何借用引用存活更长时间。例如,在这里,我们可以安全地借用 *this
,但 __dispatch_contiguous()
返回的张量是新创建的,借用引用实际上会使其成为无主状态。
因此,一般经验法则
如有疑问,请完全不要使用
MaybeOwned<Tensor>
- 特别是,最好避免在尚未使用它的代码中使用它。只有在出现关键(且可证明的)性能提升时,才应引入新用法。在修改或调用已使用
MaybeOwned<Tensor>
的代码时,请记住,通过调用MaybeOwned<Tensor>::owned()
,从现有的张量中生成MaybeOwned<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> 中找到。