From 272dabd70403b0d3fc01f2841224fd390023d06f Mon Sep 17 00:00:00 2001 From: 0x45f Date: Tue, 1 Aug 2023 07:23:10 +0000 Subject: [PATCH] Fix scope error --- .../eager/to_static/run_program_op_func.h | 54 ++++++++++++++----- .../eager/to_static/run_program_op_node.h | 9 ++-- paddle/fluid/framework/operator.h | 2 + paddle/fluid/operators/run_program_op.h | 5 +- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/paddle/fluid/eager/to_static/run_program_op_func.h b/paddle/fluid/eager/to_static/run_program_op_func.h index 08fd6ad18e5..10677589b2b 100644 --- a/paddle/fluid/eager/to_static/run_program_op_func.h +++ b/paddle/fluid/eager/to_static/run_program_op_func.h @@ -20,6 +20,7 @@ #include "paddle/fluid/eager/eager_tensor.h" #include "paddle/fluid/eager/to_static/run_program_op_node.h" #include "paddle/fluid/eager/utils.h" +#include "paddle/fluid/memory/allocation/allocator.h" // Filter params without grads in global block. In this case, we will // tag its AutogradMeta with stop_gradient = True to avoid fault from @@ -53,6 +54,41 @@ static void clear_no_grad_edges_with_partial_block( } } +static void clear_unused_out_var_in_backward( + const std::vector& out, + const paddle::framework::BlockDesc* backward_block, + paddle::framework::Scope* scope) { + std::deque>* garbages = + new std::deque>(); + for (auto* out_tensor : out) { + if (!backward_block->HasVar(out_tensor->name())) { + auto var = scope->FindVar(out_tensor->name()); + if (var == nullptr) { + continue; + } + if (var->IsType()) { + garbages->emplace_back( + var->GetMutable()->MoveMemoryHolder()); + } + } + } + delete garbages; +} + +static std::vector filte_unused_input_var_in_backward( + const std::vector& x, + const paddle::framework::BlockDesc* backward_block) { + auto filter_x = std::vector(x); + for (size_t i = 0; i < x.size(); i++) { + if (!backward_block->HasVar(x[i].name())) { + auto fake = paddle::Tensor(std::make_shared()); + fake.set_name(paddle::framework::kFakeVarName); + filter_x[i] = fake; + } + } + return filter_x; +} + inline void run_program_ad_func( const std::vector& x, const std::vector& params, @@ -93,21 +129,11 @@ inline void run_program_ad_func( auto* backward_global_block = PADDLE_GET_CONST( paddle::framework::BlockDesc*, attrs.at("backward_global_block")); // Clear unused x vars - auto temp_x = std::vector(x); - for (size_t i = 0; i < x.size(); i++) { - if (!backward_global_block->HasVar(x[i].name())) { - auto fake = paddle::Tensor(std::make_shared()); - fake.set_name("Fake_var"); - temp_x[i] = fake; - } - } - grad_node->SetFwdX(temp_x); + auto filter_x = + filte_unused_input_var_in_backward(x, backward_global_block); + grad_node->SetFwdX(filter_x); // Clear unused out vars - for (size_t i = 0; i < out.size(); i++) { - if (!backward_global_block->HasVar(out[i]->name())) { - step_scope[0]->EraseVars({out[i]->name()}); - } - } + clear_unused_out_var_in_backward(out, backward_global_block, step_scope[0]); grad_node->SetFwdParams(params); grad_node->SetStepScope(step_scope); diff --git a/paddle/fluid/eager/to_static/run_program_op_node.h b/paddle/fluid/eager/to_static/run_program_op_node.h index c34bcb18a4c..46fc7b414d5 100644 --- a/paddle/fluid/eager/to_static/run_program_op_node.h +++ b/paddle/fluid/eager/to_static/run_program_op_node.h @@ -130,7 +130,7 @@ static void ShareTensorsIntoScope(const std::vector &tensors, paddle::framework::Scope *scope) { for (size_t i = 0; i < tensors.size(); ++i) { auto name = tensors[i].name(); - if (name == "Fake_var") { + if (name == paddle::framework::kFakeVarName) { continue; } auto *var = scope->Var(name); @@ -159,8 +159,8 @@ static void ShareTensorsFromScope( // because we can't find them in scope. So we skip sharing these vars or // var@GRAD if they don't appear in global block. auto &name = tensors[i]->name(); - if (name == paddle::framework::kEmptyVarName || name == "Fake_var" || - !global_block.HasVar(name)) { + if (name == paddle::framework::kEmptyVarName || + name == paddle::framework::kFakeVarName || !global_block.HasVar(name)) { VLOG(2) << "find tensor name is " << name << ", skip it!"; continue; } @@ -197,7 +197,8 @@ static void ShareTensorsFromScopeWithPartialBlock( paddle::framework::Scope *scope) { for (size_t i = 0; i < tensors.size(); ++i) { auto &name = tensors[i]->name(); - if (name == paddle::framework::kEmptyVarName || name == "Fake_var" || + if (name == paddle::framework::kEmptyVarName || + name == paddle::framework::kFakeVarName || (!forward_global_block.HasVar(name) && !backward_global_block.HasVar(name))) { VLOG(2) << "find tensor name is " << name << ", skip it!"; diff --git a/paddle/fluid/framework/operator.h b/paddle/fluid/framework/operator.h index e6a2058107b..1560dc82107 100644 --- a/paddle/fluid/framework/operator.h +++ b/paddle/fluid/framework/operator.h @@ -65,6 +65,8 @@ PHI_DECLARE_int32(inner_op_parallelism); namespace paddle { namespace framework { +constexpr char kFakeVarName[] = "Fake_var"; + /// If a variable is a empty variable, that name will be used. constexpr char kEmptyVarName[] = "@EMPTY@"; diff --git a/paddle/fluid/operators/run_program_op.h b/paddle/fluid/operators/run_program_op.h index ff6f6ceac54..e2675db6b78 100644 --- a/paddle/fluid/operators/run_program_op.h +++ b/paddle/fluid/operators/run_program_op.h @@ -143,7 +143,7 @@ static void ShareVarsIntoScope(const std::vector &vars, const std::vector &var_names, framework::Scope *scope) { for (size_t i = 0; i < vars.size(); ++i) { - if (var_names[i] == "Fake_var") { + if (var_names[i] == framework::kFakeVarName) { continue; } auto *var = scope->Var(var_names[i]); @@ -162,7 +162,8 @@ static void ShareVarsFromScope(const std::vector &vars, // because we can't findthem in scope. So we skip sharing these vars or // var@GRAD if they don't appear in global block. if (var_names[i] == framework::kEmptyVarName || - var_names[i] == "Fake_var" || !global_block.HasVar(var_names[i])) { + var_names[i] == framework::kFakeVarName || + !global_block.HasVar(var_names[i])) { VLOG(2) << "find variable name is " << var_names[i] << ", skip it!"; continue; } -- GitLab