From 5fadde62bac9e83de385bf802658630b9ce1be46 Mon Sep 17 00:00:00 2001 From: Ivan Tikhonov Date: Sat, 29 Jul 2023 05:29:31 +0000 Subject: [PATCH] Enable ResolveNamesCollisions transformation in MOC #2 (#18772) * ResolveNamesCollisions transformation refactoring; enable it in MOC * fix the description * call ResolveNamesCollisions transformation in the frontends; resolve review comments * Resolve review comments * fix EliminateUnsqueezeGather and AlignMixedTypes transformations --- .../resolve_names_collisions.hpp | 2 +- .../eliminate_unsqueeze_gather.cpp | 29 +++-- .../moc_transformations.cpp | 2 + .../align_mixed_fp32_fp16_types.cpp | 17 ++- .../resolve_names_collisions.cpp | 92 ++++++------- .../tests/resolve_names_collisions.cpp | 121 +++++++++++++----- .../openvino/op/util/multi_subgraph_base.hpp | 7 + .../include/openvino/frontend/ir/frontend.hpp | 4 + src/frontends/ir/src/frontend.cpp | 11 +- src/frontends/onnx/frontend/src/frontend.cpp | 11 +- .../openvino/frontend/paddle/frontend.hpp | 4 + src/frontends/paddle/src/frontend.cpp | 11 +- src/frontends/pytorch/src/frontend.cpp | 3 +- src/frontends/tensorflow/src/frontend.cpp | 2 + .../tensorflow_lite/src/frontend.cpp | 2 + 15 files changed, 210 insertions(+), 108 deletions(-) diff --git a/src/common/transformations/include/transformations/resolve_names_collisions.hpp b/src/common/transformations/include/transformations/resolve_names_collisions.hpp index bd2500c0060bab..b1445dec780cf1 100644 --- a/src/common/transformations/include/transformations/resolve_names_collisions.hpp +++ b/src/common/transformations/include/transformations/resolve_names_collisions.hpp @@ -13,7 +13,7 @@ namespace pass { /** * @ingroup ie_transformation_common_api * @brief ResolveNameCollisions transformation helps to fix names collisions - * if some internal nodes or nodes with autogenerated names have conflicts with other nodes from the original graph + * if nodes with autogenerated names have conflicts with other node names. * * Every transformation call can change the graph structure and create some additional operations, * autogenerated name is used if new operation doesn't have friendly name. diff --git a/src/common/transformations/src/transformations/common_optimizations/eliminate_unsqueeze_gather.cpp b/src/common/transformations/src/transformations/common_optimizations/eliminate_unsqueeze_gather.cpp index a16fa345868545..9342c9ba276b25 100644 --- a/src/common/transformations/src/transformations/common_optimizations/eliminate_unsqueeze_gather.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/eliminate_unsqueeze_gather.cpp @@ -65,23 +65,30 @@ ov::pass::EliminateUnsqueezeGather::EliminateUnsqueezeGather() { ov::pass::EliminateGatherUnsqueeze::EliminateGatherUnsqueeze() { MATCHER_SCOPE(EliminateGatherUnsqueeze); - + const auto are_all_outputs_unsqueezes = [](const Output& out) -> bool { + const auto& target_inputs = out.get_target_inputs(); + bool res = out.get_partial_shape().rank() == 0 && !target_inputs.empty(); + for (const auto& target_input : target_inputs) { + if (!res) { + break; + } + auto unsqueeze = ov::as_type(target_input.get_node()); + res = unsqueeze != nullptr && unsqueeze->output(0).get_partial_shape().rank() == 1; + } + return res; + }; const auto gather_indices_label = ngraph::pattern::wrap_type(pattern::rank_equals(0)); const auto gather_axis_label = ngraph::pattern::wrap_type(); const auto gather_label = ngraph::pattern::wrap_type( {pass::pattern::any_input(), gather_indices_label, gather_axis_label}, - pattern::rank_equals(0)); - - const auto unsqueeze_label = - ngraph::pattern::wrap_type({gather_label, pass::pattern::any_input()}, - pattern::rank_equals(1)); + are_all_outputs_unsqueezes); ov::matcher_pass_callback callback = [=](ngraph::pattern::Matcher& m) { auto pattern_nodes = m.get_pattern_map(); auto& gather_indices = pattern_nodes.at(gather_indices_label); auto& gather = pattern_nodes.at(gather_label); - auto& unsqueeze = pattern_nodes.at(unsqueeze_label); + const auto& target_unsqueezes = gather->output(0).get_target_inputs(); auto new_indices = ov::op::util::make_try_fold(gather_indices, @@ -90,11 +97,13 @@ ov::pass::EliminateGatherUnsqueeze::EliminateGatherUnsqueeze() { auto new_gather = gather->clone_with_new_inputs({gather->input_value(0), new_indices, gather->input_value(2)}); new_gather->set_friendly_name(gather->get_friendly_name()); - ngraph::copy_runtime_info({unsqueeze, gather}, {new_gather, new_indices}); - ngraph::replace_node(unsqueeze, new_gather); + ngraph::copy_runtime_info({gather}, {new_gather, new_indices}); + for (const auto& unsqueeze : target_unsqueezes) { + unsqueeze.get_node()->output(0).replace(new_gather); + } return true; }; - auto m = std::make_shared(unsqueeze_label, matcher_name); + auto m = std::make_shared(gather_label, matcher_name); register_matcher(m, callback); } diff --git a/src/common/transformations/src/transformations/common_optimizations/moc_transformations.cpp b/src/common/transformations/src/transformations/common_optimizations/moc_transformations.cpp index 0a97891b071cf9..e67fc4d4d62933 100644 --- a/src/common/transformations/src/transformations/common_optimizations/moc_transformations.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/moc_transformations.cpp @@ -84,6 +84,7 @@ #include #include "itt.hpp" +#include "transformations/resolve_names_collisions.hpp" bool ov::pass::MOCTransformations::run_on_model(const std::shared_ptr& f) { RUN_ON_FUNCTION_SCOPE(MOCTransformations); @@ -246,6 +247,7 @@ bool ov::pass::MOCTransformations::run_on_model(const std::shared_ptr& model) { RUN_ON_MODEL_SCOPE(AlignMixedFP32FP16Types); + std::unordered_set new_friendly_names; + + auto generate_uniq_name = [&new_friendly_names](const std::string& initial_name) { + int idx = 0; + auto cur_name = initial_name; + while (new_friendly_names.find(cur_name) != new_friendly_names.end()) { + cur_name = initial_name + ":" + std::to_string(idx++); + } + new_friendly_names.insert(cur_name); + return cur_name; + }; std::function&)> insert_converts_before_if_needed = [&](const std::shared_ptr& node) { @@ -32,7 +43,8 @@ bool ov::pass::AlignMixedFP32FP16Types::run_on_model(const std::shared_ptr(incoming_output, incoming_output.get_element_type()); - convert->set_friendly_name(incoming_node->get_friendly_name() + "_decompressed_to_f32"); + auto init_name = incoming_node->get_friendly_name() + "_decompressed_to_f32"; + convert->set_friendly_name(generate_uniq_name(init_name)); copy_runtime_info(incoming_node, convert); input.replace_source_output(convert); disable_fp16_compression(convert); @@ -61,7 +73,8 @@ bool ov::pass::AlignMixedFP32FP16Types::run_on_model(const std::shared_ptr f16). It's kept here f32 to keep ov::Model validatable auto convert = std::make_shared(output, out_inputs.get_element_type()); copy_runtime_info(node, convert); - convert->set_friendly_name(node->get_friendly_name() + "_compressed_to_f16"); + auto init_name = node->get_friendly_name() + "_compressed_to_f16"; + convert->set_friendly_name(generate_uniq_name(init_name)); out_inputs.replace_source_output(convert); pass::disable_constant_folding(convert); is_changed = true; diff --git a/src/common/transformations/src/transformations/resolve_names_collisions.cpp b/src/common/transformations/src/transformations/resolve_names_collisions.cpp index dde738db53df42..7b7c7693fb0fd9 100644 --- a/src/common/transformations/src/transformations/resolve_names_collisions.cpp +++ b/src/common/transformations/src/transformations/resolve_names_collisions.cpp @@ -6,12 +6,27 @@ #include #include -#include #include "itt.hpp" -#include "openvino/op/parameter.hpp" -#include "openvino/op/result.hpp" -#include "openvino/op/sink.hpp" +#include "openvino/op/util/multi_subgraph_base.hpp" + +namespace { + +void collect_name_collisions_map(const std::shared_ptr& model, + std::unordered_map>& name_collisions_map) { + for (const auto& node : model->get_ordered_ops()) { + // Collect a names collision map for all nodes in the graph + const auto& friendly_name = node->get_friendly_name(); + name_collisions_map[friendly_name].emplace_back(node.get()); + if (auto msn = ov::as_type_ptr(node)) { + for (const auto& body : msn->get_functions()) { + collect_name_collisions_map(body, name_collisions_map); + } + } + } +} + +} // namespace bool ov::pass::ResolveNameCollisions::run_on_model(const std::shared_ptr& model) { // Next containers are used to fix collisions in autogenerated names @@ -20,63 +35,28 @@ bool ov::pass::ResolveNameCollisions::run_on_model(const std::shared_ptr nodes_with_conflicts; std::unordered_map> visited_nodes; - for (const auto& node : model->get_ordered_ops()) { - // Detect names collisions only for nodes with autogenerated names - const auto& friendly_name = node->get_friendly_name(); - visited_nodes[friendly_name].emplace_back(node.get()); - } + collect_name_collisions_map(model, visited_nodes); - for (const auto& l_nodes : visited_nodes) { - if (l_nodes.second.size() == 1) + for (const auto& it : visited_nodes) { + const auto& same_named_ops = it.second; + if (same_named_ops.size() < 2) { continue; - const size_t nodes_size = l_nodes.second.size(); - bool has_public_node = false; // Parameter, Result ans Sinks - size_t i(0); - for (auto* node : l_nodes.second) { - i++; - // Skip the last node if we don't have public nodes with collisions - if (i == nodes_size && !has_public_node) - break; - if (dynamic_cast(node)) { - // Result is a service node + } + + int64_t cnt = 2; + for (const auto& op : same_named_ops) { + // check if op has OV autogenerated friendly name. unique and friendly names have to be equal. + bool is_autogenerated = op->m_friendly_name.empty(); + if (!is_autogenerated) { continue; } - if (dynamic_cast(node) || dynamic_cast(node)) { - // Resolve names for public ops with autogenerated name - if (node->m_friendly_name.empty()) - nodes_with_conflicts.emplace_back(node); - has_public_node = true; - continue; - } else { - // For result we need to avoid changes in previous operation - bool is_public = false; - for (const auto& output : node->outputs()) { - for (const auto input : output.get_target_inputs()) { - if (dynamic_cast(input.get_node())) { - has_public_node = true; - is_public = true; - break; - } - } - if (is_public) - break; - } - if (is_public) - continue; + // add a prefix "_counter" to the autogenerated name to make it unique. + auto new_name = op->get_friendly_name() + "_" + std::to_string(cnt++); + while (visited_nodes.find(new_name) != visited_nodes.end()) { + new_name = op->get_friendly_name() + "_" + std::to_string(cnt++); } - nodes_with_conflicts.emplace_back(node); + op->set_friendly_name(new_name); } } - - // Resolve names collisions - for (auto* node : nodes_with_conflicts) { - size_t idx = 2; - const auto friendly_name = node->get_friendly_name(); - while (visited_nodes.find(friendly_name + "_" + std::to_string(idx)) != visited_nodes.end()) - idx++; - const auto new_friendly_name = friendly_name + "_" + std::to_string(idx); - node->set_friendly_name(new_friendly_name); - visited_nodes[new_friendly_name].emplace_back(node); - } - return true; + return false; } diff --git a/src/common/transformations/tests/resolve_names_collisions.cpp b/src/common/transformations/tests/resolve_names_collisions.cpp index c85c9323e1a87f..1db80b6e0a970f 100644 --- a/src/common/transformations/tests/resolve_names_collisions.cpp +++ b/src/common/transformations/tests/resolve_names_collisions.cpp @@ -8,8 +8,11 @@ #include "openvino/opsets/opset8.hpp" #include "openvino/pass/manager.hpp" +using namespace ov; +using namespace ov::opset8; + TEST(ResolveNameCollisionsTest, FixGeneratedNames) { - auto arg0 = std::make_shared(ov::element::f32, ov::PartialShape{1, 3, 3, 3}); + auto arg0 = std::make_shared(ov::element::f32, ov::PartialShape{1, 3, 3, 3}); const auto gen_friendly_name = arg0->get_friendly_name(); std::string name = "Parameter_"; @@ -19,10 +22,10 @@ TEST(ResolveNameCollisionsTest, FixGeneratedNames) { arg0->set_friendly_name(name); - auto arg1 = std::make_shared(ov::element::f32, ov::PartialShape{1, 2, 3, 3}); + auto arg1 = std::make_shared(ov::element::f32, ov::PartialShape{1, 2, 3, 3}); - auto concat = std::make_shared(ov::NodeVector{arg0, arg1}, 1); - auto result1 = std::make_shared(concat); + auto concat = std::make_shared(ov::NodeVector{arg0, arg1}, 1); + auto result1 = std::make_shared(concat); auto model = std::make_shared(ov::ResultVector{result1}, ov::ParameterVector{arg0, arg1}); @@ -38,50 +41,102 @@ TEST(ResolveNameCollisionsTest, FixGeneratedNames) { EXPECT_EQ(arg1->get_friendly_name(), arg0->get_friendly_name() + "_2"); } -TEST(ResolveNameCollisionsTest, DoNotFixFriendlyNamesForParameters) { - auto arg0 = std::make_shared(ov::element::f32, ov::PartialShape{1, 3, 3, 3}); +TEST(ResolveNameCollisionsTest, FixFriendlyNamesForAutogeneratedNames) { + auto arg0 = std::make_shared(ov::element::f32, ov::PartialShape{1, 3, 3, 3}); const auto gen_friendly_name = arg0->get_friendly_name(); - arg0->set_friendly_name(gen_friendly_name); - - auto arg1 = std::make_shared(ov::element::f32, ov::PartialShape{1, 2, 3, 3}); + auto arg1 = std::make_shared(ov::element::f32, ov::PartialShape{1, 2, 3, 3}); + // set the same name as for the first Parameter arg1->set_friendly_name(gen_friendly_name); - auto concat = std::make_shared(ov::NodeVector{arg0, arg1}, 1); - auto result1 = std::make_shared(concat); + auto concat1 = std::make_shared(ov::NodeVector{arg0, arg1}, 1); + concat1->set_friendly_name("concat"); + auto concat = std::make_shared(ov::NodeVector{concat1, arg1}, 1); + concat->set_friendly_name("concat"); + + auto result1 = std::make_shared(concat); auto model = std::make_shared(ov::ResultVector{result1}, ov::ParameterVector{arg0, arg1}); - EXPECT_EQ(gen_friendly_name, arg0->get_friendly_name()); - EXPECT_EQ(arg1->get_friendly_name(), arg0->get_friendly_name()); - EXPECT_NE(arg1->get_friendly_name(), arg0->get_friendly_name() + "_2"); + EXPECT_EQ(concat->get_friendly_name(), concat1->get_friendly_name()); ov::pass::Manager pass_manager; pass_manager.register_pass(); pass_manager.run_passes(model); - EXPECT_EQ(gen_friendly_name, arg0->get_friendly_name()); - EXPECT_EQ(arg1->get_friendly_name(), arg0->get_friendly_name()); - EXPECT_NE(arg1->get_friendly_name(), arg0->get_friendly_name() + "_2"); -} - -TEST(ResolveNameCollisionsTest, FixFriendlyNamesForInternalOperations) { - auto arg0 = std::make_shared(ov::element::f32, ov::PartialShape{1, 3, 3, 3}); - const auto gen_friendly_name = arg0->get_friendly_name(); - - auto arg1 = std::make_shared(ov::element::f32, ov::PartialShape{1, 2, 3, 3}); - - auto concat1 = std::make_shared(ov::NodeVector{arg0, arg1}, 1); - concat1->set_friendly_name("concat"); - auto concat = std::make_shared(ov::NodeVector{concat1, arg1}, 1); - concat->set_friendly_name("concat"); - auto result1 = std::make_shared(concat); - - auto model = std::make_shared(ov::ResultVector{result1}, ov::ParameterVector{arg0, arg1}); + // these names weren't set automatically, and have to remain the same. EXPECT_EQ(concat->get_friendly_name(), concat1->get_friendly_name()); + // arg0's name was set automatically and matches with another name in the graph, + // so it have to be changed. + EXPECT_NE(arg0->get_friendly_name(), arg1->get_friendly_name()); + EXPECT_EQ(arg0->get_friendly_name(), arg1->get_friendly_name() + "_2"); +} + +TEST(ResolveNameCollisionsTest, FixFriendlyNamesForAutogeneratedNamesMultiSubgraphOp) { + // external params + auto X = std::make_shared(element::f32, Shape{4}); + auto Y = std::make_shared(element::f32, Shape{4}); + auto Z = std::make_shared(element::f32, Shape{8}); + + auto axis = std::make_shared(element::i32, Shape{}, 0); + auto external_split = std::make_shared(X, axis, 2); + + // internal params + auto Xt = std::make_shared(element::f32, PartialShape::dynamic()); + Xt->set_friendly_name(X->get_friendly_name()); + auto Yt = std::make_shared(element::f32, PartialShape::dynamic()); + Yt->set_friendly_name(Y->get_friendly_name()); + auto Ze = std::make_shared(element::f32, PartialShape::dynamic()); + + // then body + auto cond = std::make_shared(element::boolean, Shape{1}, true); + auto axis_then = std::make_shared(element::i32, Shape{}, 0); + auto split_y = std::make_shared(Yt, axis_then, 2); + split_y->set_friendly_name(external_split->get_friendly_name()); + auto then_op = std::make_shared(Xt, split_y->output(0)); + auto res0 = std::make_shared(then_op); + + // else body + auto axis_else = std::make_shared(element::i32, Shape{}, 0); + auto split_z = std::make_shared(Ze, axis_else, 4); + split_z->set_friendly_name(external_split->get_friendly_name()); + auto else_op = std::make_shared(split_z); + else_op->set_friendly_name(then_op->get_friendly_name()); + auto res1 = std::make_shared(else_op); + + // If set up + auto then_body = std::make_shared(OutputVector{res0}, ParameterVector{Yt, Xt}, "then_body"); + auto else_body = std::make_shared(OutputVector{res1}, ParameterVector{Ze}, "else_body"); + auto if_op = std::make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(external_split->output(0), Xt, nullptr); + if_op->set_input(Y, Yt, nullptr); + if_op->set_input(Z, nullptr, Ze); + auto result = if_op->set_output(res0, res1); + + auto res = std::make_shared(result); + auto model = std::make_shared(OutputVector{res}, ParameterVector{X, Y, Z}); + + EXPECT_EQ(external_split->get_friendly_name(), split_y->get_friendly_name()); + EXPECT_EQ(external_split->get_friendly_name(), split_z->get_friendly_name()); + + EXPECT_EQ(X->get_friendly_name(), Xt->get_friendly_name()); + EXPECT_EQ(Y->get_friendly_name(), Yt->get_friendly_name()); + + EXPECT_EQ(then_op->get_friendly_name(), else_op->get_friendly_name()); ov::pass::Manager pass_manager; pass_manager.register_pass(); pass_manager.run_passes(model); - EXPECT_NE(concat->get_friendly_name(), concat1->get_friendly_name()); + + EXPECT_EQ(external_split->get_friendly_name(), split_y->get_friendly_name() + "_2"); + + EXPECT_EQ(X->get_friendly_name(), Xt->get_friendly_name() + "_2"); + EXPECT_EQ(Y->get_friendly_name(), Yt->get_friendly_name() + "_2"); + + EXPECT_EQ(then_op->get_friendly_name(), else_op->get_friendly_name() + "_2"); + // remain the same, because they were set via "set_friendly_name" method + // and are not autogenerated. + EXPECT_EQ(split_y->get_friendly_name(), split_z->get_friendly_name()); } diff --git a/src/core/include/openvino/op/util/multi_subgraph_base.hpp b/src/core/include/openvino/op/util/multi_subgraph_base.hpp index 578ff258620cf7..dbdb7b7d724b67 100644 --- a/src/core/include/openvino/op/util/multi_subgraph_base.hpp +++ b/src/core/include/openvino/op/util/multi_subgraph_base.hpp @@ -198,6 +198,13 @@ class OPENVINO_API MultiSubGraphOp : public Op { virtual const std::shared_ptr& get_function(size_t index) const { return m_bodies[index]; }; + + /// \brief Gets internal sub-graphs + /// \return a vector of pointers to sub-graph Models + virtual const std::vector>& get_functions() const { + return m_bodies; + }; + /// \brief Adds sub-graph to MultiSubGraphOp /// /// \param index index of new sub-graph diff --git a/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp b/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp index 974a5eb4d8d967..b6719ab8a870e8 100644 --- a/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp +++ b/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp @@ -33,6 +33,10 @@ class IR_API FrontEnd : public ov::frontend::FrontEnd { /// \param extension base extension void add_extension(const ov::Extension::Ptr& extension) override; + /// \brief Runs normalization passes on Model that was loaded with partial conversion + /// \param Model partially converted OV Model + void normalize(const std::shared_ptr& model) const override; + protected: /// \brief Check if FrontEndIR can recognize model from given parts /// \param params Can be path to the model file or std::istream diff --git a/src/frontends/ir/src/frontend.cpp b/src/frontends/ir/src/frontend.cpp index b7a565ab6cdc9d..298253ff007d3a 100644 --- a/src/frontends/ir/src/frontend.cpp +++ b/src/frontends/ir/src/frontend.cpp @@ -14,6 +14,7 @@ #include "openvino/core/so_extension.hpp" #include "openvino/util/file_util.hpp" #include "openvino/util/mmap_object.hpp" +#include "transformations/resolve_names_collisions.hpp" #include "xml_parse_utils.h" using namespace ov; @@ -238,13 +239,21 @@ InputModel::Ptr FrontEnd::load_impl(const std::vector& variants) const std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const { auto ir_model = std::dynamic_pointer_cast(model); OPENVINO_ASSERT(ir_model != nullptr); - return ir_model->convert(); + const auto& converted_model = ir_model->convert(); + normalize(converted_model); + return converted_model; } std::string FrontEnd::get_name() const { return "ir"; } +void FrontEnd::normalize(const std::shared_ptr& model) const { + ov::pass::Manager manager; + manager.register_pass(); + manager.run_passes(model); +} + } // namespace ir } // namespace frontend } // namespace ov diff --git a/src/frontends/onnx/frontend/src/frontend.cpp b/src/frontends/onnx/frontend/src/frontend.cpp index 3ebbf861900661..0cbc4a0a2fa318 100644 --- a/src/frontends/onnx/frontend/src/frontend.cpp +++ b/src/frontends/onnx/frontend/src/frontend.cpp @@ -29,6 +29,7 @@ #include "openvino/core/so_extension.hpp" #include "openvino/frontend/extension/telemetry.hpp" #include "ops_bridge.hpp" +#include "transformations/resolve_names_collisions.hpp" #include "utils/common.hpp" using namespace ov; @@ -103,14 +104,17 @@ std::shared_ptr FrontEnd::convert_partially(const InputModel:: return function; } - return model_onnx->convert(); + const auto& converted_model = model_onnx->convert(); + normalize(converted_model); + return converted_model; } void FrontEnd::normalize(const std::shared_ptr& model) const { // Here, you can register transformations as a second step of importing process // In particular, you can operate on not supported ops (it allows to N:N ONNX->OV mapping). - // ov::pass::Manager manager; - // manager.run_passes(model); + ov::pass::Manager manager; + manager.register_pass(); + manager.run_passes(model); } std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const { @@ -126,6 +130,7 @@ std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model void FrontEnd::convert(const std::shared_ptr& partially_converted) const { ngraph::onnx_import::detail::convert_decoded_function(partially_converted); + normalize(partially_converted); } std::shared_ptr FrontEnd::decode(const InputModel::Ptr& model) const { diff --git a/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp index 6a804c2b24b012..a4bf013684e6a0 100644 --- a/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp +++ b/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp @@ -58,6 +58,10 @@ class PADDLE_API FrontEnd : public ov::frontend::FrontEnd { void add_extension(const std::shared_ptr& extension) override; + /// \brief Runs normalization passes on Model that was loaded with partial conversion + /// \param Model partially converted OV Model + void normalize(const std::shared_ptr& model) const override; + protected: /// \brief Check if FrontEnd can recognize model from given parts /// \param params Can be path to folder which contains __model__ file or path to diff --git a/src/frontends/paddle/src/frontend.cpp b/src/frontends/paddle/src/frontend.cpp index d94ef8e091cbf2..9582fccf6c447f 100644 --- a/src/frontends/paddle/src/frontend.cpp +++ b/src/frontends/paddle/src/frontend.cpp @@ -35,6 +35,7 @@ #include "paddle_fw_node.hpp" #include "paddle_utils.hpp" #include "place.hpp" +#include "transformations/resolve_names_collisions.hpp" using namespace ov::frontend::paddle::op::default_opset; using namespace ov; @@ -457,6 +458,7 @@ std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const fuse_fakequantize_ops(f); try_remove_internal_ops(f); + normalize(f[0]); return f[0]; } @@ -472,6 +474,7 @@ void FrontEnd::convert(const std::shared_ptr& partiallyConverted) con fuse_fakequantize_ops({partiallyConverted}); try_remove_internal_ops({partiallyConverted}); + normalize(partiallyConverted); } std::shared_ptr FrontEnd::convert_partially(const InputModel::Ptr& model) const { @@ -504,7 +507,7 @@ std::shared_ptr FrontEnd::convert_partially(const InputModel::Ptr& mo fuse_fakequantize_ops(f); try_remove_internal_ops(f); - + normalize(f[0]); return f[0]; } @@ -542,6 +545,12 @@ void FrontEnd::add_extension(const std::shared_ptr& extension) { } } +void FrontEnd::normalize(const std::shared_ptr& model) const { + ov::pass::Manager manager; + manager.register_pass(); + manager.run_passes(model); +} + } // namespace paddle } // namespace frontend } // namespace ov diff --git a/src/frontends/pytorch/src/frontend.cpp b/src/frontends/pytorch/src/frontend.cpp index f73f473d28a32f..a519a34eed7a33 100644 --- a/src/frontends/pytorch/src/frontend.cpp +++ b/src/frontends/pytorch/src/frontend.cpp @@ -18,6 +18,7 @@ #include "transformations/control_flow/unroll_if.hpp" #include "transformations/low_precision/mark_dequantization_subgraph.hpp" #include "transformations/op_conversions/convert_convertlike.hpp" +#include "transformations/resolve_names_collisions.hpp" #include "transforms.hpp" #include "transforms/append_list_unpack_replacer.hpp" #include "transforms/aten_cat_replacer.hpp" @@ -195,7 +196,7 @@ void FrontEnd::normalize(const std::shared_ptr& model) const { manager.register_pass(); manager.register_pass(); manager.register_pass(); - + manager.register_pass(); manager.run_passes(model); apply_pytorch_conversion_transforms(model); diff --git a/src/frontends/tensorflow/src/frontend.cpp b/src/frontends/tensorflow/src/frontend.cpp index af25b96641d4bc..d5c3c4e2bcbf59 100644 --- a/src/frontends/tensorflow/src/frontend.cpp +++ b/src/frontends/tensorflow/src/frontend.cpp @@ -28,6 +28,7 @@ #include "transformations/common_optimizations/remove_concat_zero_dim_input.hpp" #include "transformations/common_optimizations/reverse_shape_and_type_infer.hpp" #include "transformations/control_flow/unroll_if.hpp" +#include "transformations/resolve_names_collisions.hpp" #include "transformations/switch_merge_resolve.hpp" #include "transformations/transpose_sinking/ts_general.hpp" #include "translate_session.hpp" @@ -476,6 +477,7 @@ void FrontEnd::normalize(const std::shared_ptr& model) const { manager.register_pass(); manager.register_pass(); manager.register_pass(); + manager.register_pass(); manager.run_passes(model); } diff --git a/src/frontends/tensorflow_lite/src/frontend.cpp b/src/frontends/tensorflow_lite/src/frontend.cpp index 0c7544eaea0d9f..a1d9cf9ef7d7e1 100644 --- a/src/frontends/tensorflow_lite/src/frontend.cpp +++ b/src/frontends/tensorflow_lite/src/frontend.cpp @@ -16,6 +16,7 @@ #include "tflite_transformations/rfft2d_complex_abs.h" #include "tflite_transformations/tflite_quantize_resolver.hpp" #include "transformations/common_optimizations/transpose_sinking.hpp" +#include "transformations/resolve_names_collisions.hpp" #include "transformations/transpose_sinking/ts_general.hpp" using namespace ov; @@ -291,6 +292,7 @@ void FrontEnd::normalize(const std::shared_ptr& function) const { manager.register_pass(); manager.register_pass(); manager.register_pass(); + manager.register_pass(); manager.run_passes(function); }