Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support inplace operations #5204

Merged
merged 36 commits into from
Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8795a7b
support inplace forward
poohRui Jun 15, 2021
455e34c
support inplace backward
poohRui Jun 15, 2021
1d6d80c
add test case
poohRui Jun 15, 2021
15390c6
add test case for clone
poohRui Jun 15, 2021
d01d59e
inplace is not support for leaf nodes
poohRui Jun 16, 2021
6dcf506
refine clone
poohRui Jun 16, 2021
7844574
add checks
poohRui Jun 17, 2021
6abb45c
refine
poohRui Jun 17, 2021
530aa41
forbid clone with no grad
poohRui Jun 17, 2021
76605d9
Separate autograd meta to tensor (#5267)
poohRui Jun 23, 2021
4d74ea1
conflict
poohRui Jun 23, 2021
f55d807
inplace without clone
poohRui Jun 24, 2021
f583175
refine
poohRui Jun 24, 2021
77ea879
minor fix
poohRui Jun 24, 2021
dede4f6
remove maybe from constructor
poohRui Jun 25, 2021
25de718
change from create to set
poohRui Jun 28, 2021
45035a7
Merge remote-tracking branch 'origin/master' into dev_support_inplace
wyg1997 Jul 1, 2021
4405fd4
fix merge bugs
wyg1997 Jul 1, 2021
1622323
fix merge bug
wyg1997 Jul 1, 2021
da8e198
remove inplace flag in local_call_opkernel_phy_instr_operand
wyg1997 Jul 1, 2021
48a72e3
Merge remote-tracking branch 'origin/master' into dev_support_inplace
wyg1997 Jul 5, 2021
c09e936
remove out-date codes
wyg1997 Jul 5, 2021
06f9cc3
Merge branch 'master' into dev_support_inplace
wyg1997 Jul 6, 2021
ba40b2f
refine code
wyg1997 Jul 7, 2021
799bbfb
Merge branch 'master' into dev_support_inplace
hjchen2 Jul 7, 2021
e378fa9
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
6c56553
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
819c847
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
c140c13
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
a410b76
add JUST
wyg1997 Jul 7, 2021
3268162
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
5dd344c
fix merge master bug
wyg1997 Jul 7, 2021
794c23a
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
21364ca
revert autograd engine input_grad check
wyg1997 Jul 7, 2021
8462703
Merge branch 'master' into dev_support_inplace
oneflow-ci-bot Jul 7, 2021
adc8211
fix bug in tensor_hook
wyg1997 Jul 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion oneflow/api/python/framework/tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ void SpecializedDef(py::class_<MirroredTensor, Tensor, std::shared_ptr<MirroredT
api->def("zeros_", &ApiEagerMirroredTensorZeros);
api->def("_register_hook",
[](const std::shared_ptr<MirroredTensor>& self, const AutogradMeta::Hook& hook) -> void {
if (!self->grad_fn_node()) { CHECK_JUST(AddAccumulateFunctionNode(self)); }
self->mut_autograd_meta()->add_hook(hook);
});
}
Expand Down Expand Up @@ -256,9 +257,10 @@ void ExportTensor(py::module& m, const char* name) {
// Methods of pytorch
.def("retain_grad",
[](T& t) {
if (!t.is_leaf()) { t.set_retain_grad(true); }
if (!t.is_leaf()) { t.set_retain_grad(true).GetOrThrow(); }
})
.def("detach", [](const T& t) { return t.api_detach().GetPtrOrThrow(); })
.def("clone", [](const T& t) { return t.api_clone().GetPtrOrThrow(); })
// OneFlow tensor properties other than pytorch tensor
.def_property_readonly("is_lazy", &T::is_lazy)
.def_property_readonly("is_consistent", &T::is_consistent);
Expand Down
39 changes: 23 additions & 16 deletions oneflow/core/autograd/autograd_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,18 @@ StackFunctionNode::StackFunctionNode(
input_meta_datas_.resize(inputs.size());
next_functions_->reserve(inputs.size());
for (int i = 0; i < inputs.size(); ++i) {
input_meta_datas_.at(i) = inputs.at(i)->mut_autograd_meta();
if (input_meta_datas_.at(i)->requires_grad()) {
if (inputs.at(i)->requires_grad()) {
input_meta_datas_.at(i) = inputs.at(i)->mut_autograd_meta();
next_functions_->emplace_back(inputs.at(i)->mut_grad_fn_node());
}
}

output_meta_datas_.resize(outputs.size());
output_tensor_infos_.reserve(outputs.size());
for (int i = 0; i < outputs.size(); ++i) {
const auto& autograd_meta =
NewAutogradMeta(outputs.at(i)->requires_grad(), outputs.at(i)->is_leaf());
outputs.at(i)->set_autograd_meta(autograd_meta);
output_meta_datas_.at(i) = outputs.at(i)->mut_autograd_meta();
output_tensor_infos_.emplace_back(TensorInfo(*outputs.at(i)));
}
Expand Down Expand Up @@ -126,6 +129,7 @@ Maybe<bool> FunctionNode::Apply(bool create_graph) {
JUST((*backward_fn_)(output_grads, &input_grads, create_graph));
for (int i = 0; i < input_meta_datas_.size(); ++i) {
if (input_grads.at(i)) {
CHECK_NOTNULL_OR_RETURN(input_meta_datas_.at(i));
hjchen2 marked this conversation as resolved.
Show resolved Hide resolved
JUST(input_meta_datas_.at(i)->now_grad_arg()->PushPartialTensor(input_grads.at(i)));
}
}
Expand All @@ -148,7 +152,7 @@ Maybe<void> StackAutogradEngine::RunBackwardAndSaveGrads4LeafTensor(const Tensor
bool create_graph) {
ClearReleasedFunctionNodes();
for (int i = 0; i < outputs.size(); ++i) {
JUST(outputs.at(i)->now_grad_arg()->PushPartialTensor(out_grads.at(i)));
JUST(JUST(outputs.at(i)->now_grad_arg())->PushPartialTensor(out_grads.at(i)));
}
// Runs each FunctionNode
for (const auto& weak_func_node : node_list_) {
Expand All @@ -173,10 +177,10 @@ Maybe<TensorTuple> StackAutogradEngine::RunBackwardAndReturnInputsTensorGrad(
std::vector<bool> ori_retain_grad(inputs.size());
for (int i = 0; i < inputs.size(); ++i) {
ori_retain_grad.at(i) = inputs.at(i)->retain_grad();
inputs.at(i)->set_retain_grad(true);
JUST(inputs.at(i)->set_retain_grad(true));
}
for (int i = 0; i < outputs.size(); ++i) {
JUST(outputs.at(i)->now_grad_arg()->PushPartialTensor(out_grads.at(i)));
JUST(JUST(outputs.at(i)->now_grad_arg())->PushPartialTensor(out_grads.at(i)));
}
// Runs each FunctionNode
for (const auto& weak_func_node : node_list_) {
Expand All @@ -190,10 +194,10 @@ Maybe<TensorTuple> StackAutogradEngine::RunBackwardAndReturnInputsTensorGrad(
}
// Gets input grads and resume retain_grad
for (int i = 0; i < inputs.size(); ++i) {
input_now_grads->at(i) = inputs.at(i)->acc_grad();
input_now_grads->at(i) = JUST(inputs.at(i)->acc_grad());
if (!ori_retain_grad.at(i)) {
inputs.at(i)->set_acc_grad(nullptr);
inputs.at(i)->set_retain_grad(false);
JUST(inputs.at(i)->set_acc_grad(nullptr));
JUST(inputs.at(i)->set_retain_grad(false));
}
}
if (!retain_graph) { ClearEngine(); }
Expand Down Expand Up @@ -241,15 +245,18 @@ GraphFunctionNode::GraphFunctionNode(
input_meta_datas_.resize(inputs.size());
next_functions_->reserve(inputs.size());
for (int i = 0; i < inputs.size(); ++i) {
input_meta_datas_.at(i) = inputs.at(i)->mut_autograd_meta();
if (input_meta_datas_.at(i)->requires_grad()) {
if (inputs.at(i)->requires_grad()) {
input_meta_datas_.at(i) = inputs.at(i)->mut_autograd_meta();
next_functions_->emplace_back(inputs.at(i)->mut_grad_fn_node());
}
}

output_meta_datas_.resize(outputs.size());
output_tensor_infos_.reserve(outputs.size());
for (int i = 0; i < outputs.size(); ++i) {
const auto& autograd_meta =
NewAutogradMeta(outputs.at(i)->requires_grad(), outputs.at(i)->is_leaf());
outputs.at(i)->set_autograd_meta(autograd_meta);
output_meta_datas_.at(i) = outputs.at(i)->mut_autograd_meta();
output_tensor_infos_.emplace_back(TensorInfo(*outputs.at(i)));
}
Expand Down Expand Up @@ -373,7 +380,7 @@ Maybe<void> GraphAutogradEngine::RunBackwardAndSaveGrads4LeafTensor(const Tensor
bool retain_graph,
bool create_graph) {
for (int i = 0; i < outputs.size(); ++i) {
JUST(outputs.at(i)->now_grad_arg()->PushPartialTensor(out_grads.at(i)));
JUST(JUST(outputs.at(i)->now_grad_arg())->PushPartialTensor(out_grads.at(i)));
}
GraphTask graph_task(outputs, retain_graph, create_graph);
JUST(graph_task.ComputeDependencies());
Expand All @@ -389,21 +396,21 @@ Maybe<TensorTuple> GraphAutogradEngine::RunBackwardAndReturnInputsTensorGrad(
std::vector<bool> ori_retain_grad(inputs.size());
for (int i = 0; i < inputs.size(); ++i) {
ori_retain_grad.at(i) = inputs.at(i)->retain_grad();
inputs.at(i)->set_retain_grad(true);
JUST(inputs.at(i)->set_retain_grad(true));
}
for (int i = 0; i < outputs.size(); ++i) {
JUST(outputs.at(i)->now_grad_arg()->PushPartialTensor(out_grads.at(i)));
JUST(JUST(outputs.at(i)->now_grad_arg())->PushPartialTensor(out_grads.at(i)));
wyg1997 marked this conversation as resolved.
Show resolved Hide resolved
}

JUST(graph_task.ComputeDependenciesAndPruneNode(inputs));
JUST(graph_task.Apply(/*save_grad_for_leaf=*/false));

// Gets input grads and resume retain_grad
for (int i = 0; i < inputs.size(); ++i) {
input_now_grads->at(i) = inputs.at(i)->acc_grad();
input_now_grads->at(i) = JUST(inputs.at(i)->acc_grad());
if (!ori_retain_grad.at(i)) {
inputs.at(i)->set_acc_grad(nullptr);
inputs.at(i)->set_retain_grad(false);
JUST(inputs.at(i)->set_acc_grad(nullptr));
JUST(inputs.at(i)->set_retain_grad(false));
}
}
return input_now_grads;
Expand Down
2 changes: 1 addition & 1 deletion oneflow/core/eager/opkernel_instruction_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ struct LocalCallOpKernelUtil final {
static inline Maybe<void> InitOutputBlobs(LocalCallOpKernelPhyInstrOperand* operand) {
JUST(operand->ForEachOutputTensor([&](vm::EagerBlobObject* blob_object) -> Maybe<void> {
CHECK_OR_RETURN(static_cast<bool>(blob_object));
JUST(blob_object->InitBlob());
JUST(blob_object->TryInitBlob());
return Maybe<void>::Ok();
}));
return Maybe<void>::Ok();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,17 @@ Maybe<void> NaiveInterpret(const UserOpExpr& user_op_expr, const TensorTuple& in
}
input_eager_blob_objects->at(i) = JUST(inputs.at(i)->eager_blob_object());
}
std::shared_ptr<EagerBlobObjectList> output_eager_blob_objects =
std::make_shared<EagerBlobObjectList>(outputs->size());
for (int i = 0; i < outputs->size(); i++) {
if (!outputs->at(i)) {
outputs->at(i) =
std::make_shared<MirroredTensor>(std::make_shared<EagerMirroredTensorImpl>());
}
if (JUST(outputs->at(i)->has_eager_blob_object())) {
output_eager_blob_objects->at(i) = JUST(outputs->at(i)->eager_blob_object());
}
}
std::shared_ptr<EagerBlobObjectList> output_eager_blob_objects =
std::make_shared<EagerBlobObjectList>(outputs->size());
Symbol<Device> op_device;
std::shared_ptr<const ParallelDesc> op_parallel_desc;
bool need_check_mem_case = true;
Expand Down Expand Up @@ -102,9 +105,11 @@ Maybe<void> NaiveInterpret(const UserOpExpr& user_op_expr, const TensorTuple& in
}));

for (int i = 0; i < output_eager_blob_objects->size(); i++) {
auto* tensor_impl = JUST(TensorImpl4Tensor(outputs->at(i)));
JUST(tensor_impl->InitEagerBlobObject(JUST(outputs->at(i)->device())->mem_case()));
output_eager_blob_objects->at(i) = JUST(tensor_impl->eager_blob_object());
if (!output_eager_blob_objects->at(i)) {
auto* tensor_impl = JUST(TensorImpl4Tensor(outputs->at(i)));
JUST(tensor_impl->InitEagerBlobObject(JUST(outputs->at(i)->device())->mem_case()));
output_eager_blob_objects->at(i) = JUST(tensor_impl->eager_blob_object());
}
}

const auto& kernel = JUST(user_op_expr.MutKernel4Device(*op_device));
Expand Down
21 changes: 19 additions & 2 deletions oneflow/core/framework/tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ limitations under the License.
#include "oneflow/core/framework/tensor_tuple.h"
#include "oneflow/core/autograd/autograd_engine.h"
#include "oneflow/core/framework/op_interpreter/eager_mirrored_op_interpreter.h"
#include "oneflow/core/framework/op_interpreter/op_interpreter_util.h"
#include "oneflow/core/framework/op_builder.h"
#include "oneflow/core/framework/op_expr.h"

namespace oneflow {

Expand Down Expand Up @@ -51,8 +54,7 @@ namespace one {
const auto& blob_desc = eager_blob_object->blob_desc();
const auto& tensor_meta =
std::make_shared<MirroredTensorMeta>(blob_desc.shape_ptr(), blob_desc.data_type(), device);
const auto& autograd_meta = std::make_shared<AutogradMeta>(requires_grad, is_leaf);
auto* tensor_impl = new EagerMirroredTensorImpl(tensor_meta, autograd_meta);
auto* tensor_impl = new EagerMirroredTensorImpl(tensor_meta, requires_grad, is_leaf);
JUST(tensor_impl->InitEagerBlobObjectAndTensorStorage(eager_blob_object, tensor_storage));
return std::make_shared<MirroredTensor>(std::shared_ptr<MirroredTensorImpl>(tensor_impl));
}
Expand All @@ -74,6 +76,21 @@ Maybe<MirroredTensor> MirroredTensor::api_detach() const {
return std::make_shared<MirroredTensor>(JUST(impl_->detach()));
}

Maybe<Tensor> MirroredTensor::clone() const {
const auto& device_type = JUST(this->device())->type();
int64_t device_id = JUST(this->device())->device_id();
std::shared_ptr<OpExpr> copy_op_ = JUST(one::OpBuilder("copy")
poohRui marked this conversation as resolved.
Show resolved Hide resolved
hjchen2 marked this conversation as resolved.
Show resolved Hide resolved
.Input("in", 1)
.Attr("device_type", device_type)
.Attr("device_id", device_id)
.Output("out", 1)
.Build());
wyg1997 marked this conversation as resolved.
Show resolved Hide resolved
std::shared_ptr<MirroredTensor> input =
std::const_pointer_cast<MirroredTensor>(shared_from_this());
const auto& output = JUST(OpInterpUtil::Dispatch<Tensor>(*copy_op_, {input}));
return output;
}

Maybe<ConsistentTensor> ConsistentTensor::MakeTensor(
const std::shared_ptr<const Shape>& shape, DataType dtype,
Symbol<cfg::ParallelDistribution> parallel_distribution, Symbol<ParallelDesc> parallel_desc,
Expand Down
Loading