bool allow_tensor_metadata_change,
Edge gradient_edge);
- /// Creates a `Variable` from the given `Tensor`. `requires_grad` should be
+ /// Creates a `Variable` from the given `Tensor`, copying its underlying `TensorImpl`.
+ /// `requires_grad` should be
/// set only for leaves, and determines whether the `Variable` will accumulate
/// gradients. NOTE: `data` must *not* be a `Variable` already. Its dynamic
/// type *must* be `Tensor`.
bool requires_grad,
bool allow_tensor_metadata_change);
+ /// Creates a `Variable` from the given `Tensor`, consuming its underlying `TensorImpl`.
+ /// This is intended to be used from functions that immediately create a `Tensor`,
+ /// convert it to a `Variable`, and then free it; it has been found to
+ /// decrease the overhead of those operations, in some situations.
+ /// The comments about `requires_grad` and `data` on the above version also apply to this one.
+ friend Variable make_variable_consuming(
+ at::Tensor data,
+ bool requires_grad,
+ bool allow_tensor_metadata_change);
+
/// Creates a `Variable` from the given `Tensor` and specify a
/// `gradient_edge`, i.e. a (function, input_nr) pair specifying the function
/// in the autograd graph, and what particular input of that function, this
return Variable();
}
+inline Variable make_variable_consuming(
+ at::Tensor data,
+ bool requires_grad = false,
+ bool allow_tensor_metadata_change = true) {
+ AT_CHECK(
+ !data.is_variable(),
+ "Must not create a new variable from a variable, use its .data()");
+ if (data.defined()) {
+ AT_ASSERT(data.getIntrusivePtr().use_count() == 1);
+ data.unsafeGetTensorImpl()->set_allow_tensor_metadata_change(allow_tensor_metadata_change);
+ auto autograd_meta = c10::guts::make_unique<Variable::AutogradMeta>();
+ return Variable(c10::make_intrusive<Variable::Impl>(std::move(data), std::move(autograd_meta), requires_grad));
+ }
+ return Variable();
+}
+
inline Variable make_variable(
at::Tensor data,
Edge gradient_edge,