Rate this Page

MaybeOwned<Tensor>#

MaybeOwned<Tensor> is a C++ smart pointer class that dynamicallyencodes whether a Tensor isowned orborrowed. It is used incertain performance-sensitive situations to avoid unnecessarilyincrementing a Tensor’s reference count (at a small cost inoverhead from the extra indirection).

Warning

MaybeOwned must be used withextreme care. Claims of (non-)ownershipare not statically checked, and mistakes can cause reference undercountingand use-after-free crashes.

Due to this lack of safety net, we discourage the use of MaybeOwnedoutside code paths that are known to be highly performance sensitive.However, if you encounter pre-existing uses of MaybeOwned in code thatyou want to modify, it’s critical to understand how to use it correctly.

The primary use case forMaybeOwned<Tensor> is a function or method thatdynamically chooses between returning one of its arguments (typicallyfrom a passthrough or “no-op” code path) and returning a freshly constructedTensor. Such a function would return aMaybeOwned<Tensor> in both cases,the former in a “borrowed” state via a call toMaybeOwned<Tensor>::borrowed(),and the latter in an “owned” state via a call toMaybeOwned<Tensor>::owned().

The canonical example isTensor’sexpect_contiguous method, which shortcutsand returns a borrowed self-reference when already contiguous:

inlinec10::MaybeOwned<Tensor>Tensor::expect_contiguous(MemoryFormatmemory_format)const&{if(is_contiguous(memory_format)){returnc10::MaybeOwned<Tensor>::borrowed(*this);}else{returnc10::MaybeOwned<Tensor>::owned(__dispatch_contiguous(memory_format));}}

Using the vocabulary of lifetimes, the essential safety requirement for borrowingis that a borrowed Tensor must outlive any borrowing references to it. Here, forexample, we can safely borrow*this, but the Tensor returned by__dispatch_contiguous() is freshly created, and borrowing a reference wouldeffectively leave it ownerless.

So, general rules of thumb:

  • When in doubt, don’t useMaybeOwned<Tensor> at all - in particular, preferavoiding using it in code that doesn’t use it already. New usage should only beintroduced when critical (and demonstrable) performance gains result.

  • When modifying or calling code that already usesMaybeOwned<Tensor>, rememberthat it’s always safe to produce aMaybeOwned<Tensor> from a Tensor in handvia a call toMaybeOwned<Tensor>::owned(). This may result in an unnecessaryreference count, but never in misbehavior - so it’s always the safer bet, unlessthe lifetime of the Tensor you’re looking to wrap is crystal clear.

More details and implementation code can be found at <pytorch/pytorch> and<pytorch/pytorch>.