From 0ae925730c3eafe29fa614437e18276368f59882 Mon Sep 17 00:00:00 2001 From: yuanlehome Date: Tue, 11 Jul 2023 11:48:51 +0000 Subject: [PATCH] fix ut --- .../framework/ir/identity_op_clean_pass.cc | 39 +++--- test/ir/inference/test_identity_clean_pass.py | 115 ++++++++++++++++-- 2 files changed, 128 insertions(+), 26 deletions(-) diff --git a/paddle/fluid/framework/ir/identity_op_clean_pass.cc b/paddle/fluid/framework/ir/identity_op_clean_pass.cc index 5acfe422f57ac..0d6c444878d10 100644 --- a/paddle/fluid/framework/ir/identity_op_clean_pass.cc +++ b/paddle/fluid/framework/ir/identity_op_clean_pass.cc @@ -40,7 +40,19 @@ FindUselessOpPattern::FindUselessOpPattern(PDPattern* pattern, : PatternBase(pattern, name_scope, name_scope) { auto* useless_op_in = pattern->NewNode(useless_op_in_repr()) ->assert_is_var() - ->assert_var_not_persistable(); + ->assert_var_not_persistable() + ->assert_has_n_outputs(1) + ->assert_more([](Node* x) { + for (auto* op : x->inputs) { + CHECK_EQ(op->IsOp(), true); + const auto& op_type = op->Op()->Type(); + if (op_type == "conditional_block" || + op_type == "while" || op_type == "feed") { + return false; + } + } + return true; + }); // This useless_op must have only one input and one output! auto* useless_op = @@ -72,18 +84,7 @@ FindUselessOpPattern::FindUselessOpPattern(PDPattern* pattern, }); auto* useless_op_out = - pattern->NewNode(useless_op_out_repr()) - ->assert_is_var() - ->assert_more([](Node* x) { - for (auto* op : x->outputs) { - CHECK_EQ(op->IsOp(), true); - const auto& op_type = op->Op()->Type(); - if (op_type == "conditional_block" || op_type == "while") { - return false; - } - } - return true; - }); + pattern->NewNode(useless_op_out_repr())->assert_is_var(); useless_op->LinksFrom({useless_op_in}).LinksTo({useless_op_out}); } @@ -106,14 +107,14 @@ void IdentityOpCleanPass::ApplyImpl(ir::Graph* graph) const { CHECK_EQ(useless_op_out->IsVar(), true); CHECK_EQ(useless_op->IsOp(), true); - for (auto* next_op : useless_op_out->outputs) { - CHECK_EQ(next_op->IsOp(), true); - next_op->Op()->RenameInput(useless_op_out->Var()->Name(), - useless_op_in->Var()->Name()); - IR_NODE_LINK_TO(useless_op_in, next_op); + for (auto* prev_op : useless_op_in->inputs) { + CHECK_EQ(prev_op->IsOp(), true); + prev_op->Op()->RenameOutput(useless_op_in->Var()->Name(), + useless_op_out->Var()->Name()); + IR_NODE_LINK_TO(prev_op, useless_op_out); } - GraphSafeRemoveNodes(graph, {useless_op, useless_op_out}); + GraphSafeRemoveNodes(graph, {useless_op_in, useless_op}); found_count++; }; diff --git a/test/ir/inference/test_identity_clean_pass.py b/test/ir/inference/test_identity_clean_pass.py index 5a39aad833e81..dbab616410ae9 100644 --- a/test/ir/inference/test_identity_clean_pass.py +++ b/test/ir/inference/test_identity_clean_pass.py @@ -20,6 +20,54 @@ class TestIdentityScaleCleanPass(PassAutoScanTest): + def sample_predictor_configs(self, program_config): + config = self.create_inference_config(use_gpu=True) + yield config, ['relu', 'relu', 'scale'], (1e-5, 1e-5) + + def sample_program_config(self, draw): + bias_after_scale = draw(st.booleans()) + n = draw(st.integers(min_value=1, max_value=4)) + c = draw(st.integers(min_value=1, max_value=20)) + h = draw(st.integers(min_value=1, max_value=20)) + w = draw(st.integers(min_value=1, max_value=20)) + + relu_op1 = OpConfig( + "relu", inputs={"X": ["relu_x"]}, outputs={"Out": ["relu_op1_out"]} + ) + scale_op1 = OpConfig( + "scale", + inputs={"X": ["relu_op1_out"]}, + outputs={"Out": ["scale_op1_out"]}, + bias=0.0, + scale=1.0, + bias_after_scale=True, + ) + scale_op2 = OpConfig( + "scale", + inputs={"X": ["scale_op1_out"]}, + outputs={"Out": ["scale_op2_out"]}, + bias=0.0, + scale=1.0, + bias_after_scale=True, + ) + relu_op2 = OpConfig( + "relu", + inputs={"X": ["relu_op1_out"]}, + outputs={"Out": ["relu_op2_out"]}, + ) + program_config = ProgramConfig( + ops=[relu_op1, relu_op2, scale_op1, scale_op2], + weights={}, + inputs={"relu_x": TensorConfig(shape=[n, c, h, w])}, + outputs=["scale_op2_out", "relu_op2_out"], + ) + return program_config + + def test(self): + self.run_and_statis(max_examples=25, passes=["identity_op_clean_pass"]) + + +class TestIdentityScaleCleanPass_V1(PassAutoScanTest): def sample_predictor_configs(self, program_config): config = self.create_inference_config(use_gpu=True) yield config, ['relu'], (1e-5, 1e-5) @@ -31,22 +79,75 @@ def sample_program_config(self, draw): h = draw(st.integers(min_value=1, max_value=20)) w = draw(st.integers(min_value=1, max_value=20)) - relu_op = OpConfig( - "relu", inputs={"X": ["relu_x"]}, outputs={"Out": ["relu_out"]} + relu_op1 = OpConfig( + "relu", inputs={"X": ["relu_x"]}, outputs={"Out": ["relu_op1_out"]} ) - scale_op = OpConfig( + scale_op1 = OpConfig( "scale", - inputs={"X": ["relu_out"]}, - outputs={"Out": ["scale_out"]}, + inputs={"X": ["relu_op1_out"]}, + outputs={"Out": ["scale_op1_out"]}, + bias=0.0, + scale=1.0, + bias_after_scale=True, + ) + scale_op2 = OpConfig( + "scale", + inputs={"X": ["scale_op1_out"]}, + outputs={"Out": ["scale_op2_out"]}, bias=0.0, scale=1.0, bias_after_scale=True, ) program_config = ProgramConfig( - ops=[relu_op, scale_op], + ops=[relu_op1, scale_op1, scale_op2], weights={}, inputs={"relu_x": TensorConfig(shape=[n, c, h, w])}, - outputs=["scale_out"], + outputs=["scale_op2_out"], + ) + return program_config + + def test(self): + self.run_and_statis(max_examples=25, passes=["identity_op_clean_pass"]) + + +class TestIdentityScaleCleanPass_V2(PassAutoScanTest): + def sample_predictor_configs(self, program_config): + config = self.create_inference_config(use_gpu=True) + yield config, ['scale', 'relu'], (1e-5, 1e-5) + + def sample_program_config(self, draw): + bias_after_scale = draw(st.booleans()) + n = draw(st.integers(min_value=1, max_value=4)) + c = draw(st.integers(min_value=1, max_value=20)) + h = draw(st.integers(min_value=1, max_value=20)) + w = draw(st.integers(min_value=1, max_value=20)) + + scale_op1 = OpConfig( + "scale", + inputs={"X": ["scale_op1_in"]}, + outputs={"Out": ["scale_op1_out"]}, + bias=0.0, + scale=1.0, + bias_after_scale=True, + ) + scale_op2 = OpConfig( + "scale", + inputs={"X": ["scale_op1_out"]}, + outputs={"Out": ["scale_op2_out"]}, + bias=0.0, + scale=1.0, + bias_after_scale=True, + ) + relu_op1 = OpConfig( + "relu", + inputs={"X": ["scale_op2_out"]}, + outputs={"Out": ["relu_op1_out"]}, + ) + program_config = ProgramConfig( + ops=[scale_op1, scale_op2, relu_op1], + weights={}, + inputs={"scale_op1_in": TensorConfig(shape=[n, c, h, w])}, + outputs=["relu_op1_out"], ) return program_config