I am in the process of doing some deep embedding of libtorch into a larger application. This involves, for example, creating wrappers around datasets so they can be persistent; this contrasts with the usual behavior evident in tutorials in which datasets are created on the fly (e.g. in main()), processed, and then destructed when the example ends.
In browsing the source code using KDevelop, there are a huge number of invocations of std::move(X), where X is a Tensor, or a collection of Tensors. For example, when initializing an optimizer, the first argument is usually something like ‘module->parameters()’. When you look at the constructor for the optimizer, a std::move is usually invoked on this argument.
I have been trying to unravel the semantics of these operations, given that caffe2::Tensor carries an intrusive_ptr to TensorImpl, which itself inherits from torch::intrusive_ptr_target. Tensor is described as “moveable”, having ‘default’ move-constructor and move-assignment, but “delete” copy-constructor and copy-assignment.
What I am trying to be certain of is whether, for example, parameter Tensors maintained by a Module retain their state after being used to construct another object. I know that the parameters() method actually constructs a vector of Tensors from the named_parameters member, and I am guessing that this construction effectively just increments a refcount_ on existing data. (Or does it? A vector.push_back(Tensor) can’t copy it, because the copy constructor is disabled–or am I missing something?)
I apologize that I am still getting up to speed on all the C++11/14 culture, having found C++98 adequate for my needs for the last couple of decades. The Pytorch C++ frontend strikes me as very deep and elegant under the hood, but ferreting out details is a bit challenging.
Thanks,
Eric