From f1b49907a34c94ca91fad643e8949d2ae38b2f44 Mon Sep 17 00:00:00 2001 From: Mikhail Ryzhov Date: Fri, 17 Mar 2023 15:44:24 +0100 Subject: [PATCH] Removed unnecessary transposes --- .../gather_sinking_transpose_reshape.cpp | 14 ++++++++ .../remove_pre_post_processing.cpp | 33 +++---------------- .../utils/transformation_helper.cpp | 27 ++++++++++++++- .../utils/transformation_helper.hpp | 14 ++++++++ 4 files changed, 58 insertions(+), 30 deletions(-) diff --git a/src/plugins/intel_gna/src/transformations/gather_sinking_transpose_reshape.cpp b/src/plugins/intel_gna/src/transformations/gather_sinking_transpose_reshape.cpp index bc867f2a75a434..f5ff10ff8fc511 100644 --- a/src/plugins/intel_gna/src/transformations/gather_sinking_transpose_reshape.cpp +++ b/src/plugins/intel_gna/src/transformations/gather_sinking_transpose_reshape.cpp @@ -194,6 +194,13 @@ GatherSinkingTransposeReshapeForward::GatherSinkingTransposeReshapeForward() { auto transpose_const = as_type_ptr(pattern_to_output.at(transpose_const_label).get_node_shared_ptr()); auto reshape = pattern_to_output.at(reshape_label).get_node_shared_ptr(); + const ov::Shape reshape_shape = pass::helper::SqueezeShape(reshape->get_shape()); + const ov::Shape transpose_shape = pass::helper::SqueezeShape(transpose->get_shape()); + if (reshape_shape == transpose_shape) { + pass::helper::RemoveSingleInputNodeFromFunction(transpose); + return true; + } + const NodePair new_nodes = SinkForward(transpose, transpose_const, reshape); register_new_node(new_nodes.first); @@ -220,6 +227,13 @@ GatherSinkingTransposeReshapeBackward::GatherSinkingTransposeReshapeBackward() { auto transpose_const = as_type_ptr(pattern_to_output.at(transpose_const_label).get_node_shared_ptr()); auto reshape = pattern_to_output.at(reshape_label).get_node_shared_ptr(); + const ov::Shape reshape_shape = pass::helper::SqueezeShape(reshape->get_shape()); + const ov::Shape transpose_shape = pass::helper::SqueezeShape(transpose->get_shape()); + if (reshape_shape == transpose_shape) { + pass::helper::RemoveSingleInputNodeFromFunction(transpose); + return true; + } + const NodePair new_nodes = SinkBackward(transpose, transpose_const, reshape); register_new_node(new_nodes.first); register_new_node(new_nodes.second); diff --git a/src/plugins/intel_gna/src/transformations/remove_pre_post_processing.cpp b/src/plugins/intel_gna/src/transformations/remove_pre_post_processing.cpp index c5be594be7476b..79775f29acc4d3 100644 --- a/src/plugins/intel_gna/src/transformations/remove_pre_post_processing.cpp +++ b/src/plugins/intel_gna/src/transformations/remove_pre_post_processing.cpp @@ -3,6 +3,7 @@ // #include "transformations/remove_pre_post_processing.hpp" +#include "transformations/utils/transformation_helper.hpp" #include #include @@ -19,14 +20,6 @@ using namespace ov::intel_gna::pass; namespace { -ov::Shape SqueezeShape(const ov::Shape& shape) { - ov::Shape squeezed_shape; - std::copy_if(shape.begin(), shape.end(), std::back_inserter(squeezed_shape), [](size_t x) { - return x != 1; - }); - return squeezed_shape; -} - bool IsPreprocessingLayerSuppported(std::shared_ptr& layer) { // Gather layers are not supported by GNA and have to be executed on CPU if (std::dynamic_pointer_cast(layer) || @@ -37,7 +30,7 @@ bool IsPreprocessingLayerSuppported(std::shared_ptr& layer) { // 2-d Transposes layers can be executed on GNA if (std::dynamic_pointer_cast(layer)) { - const ov::Shape squeezed_shape = SqueezeShape(layer->get_shape()); + const ov::Shape squeezed_shape = pass::helper::SqueezeShape(layer->get_shape()); const size_t min_input_dim = std::min(squeezed_shape[0], squeezed_shape[1]); const size_t max_input_dim = std::max(squeezed_shape[0], squeezed_shape[1]); @@ -56,24 +49,6 @@ bool IsPreprocessingLayerSuppported(std::shared_ptr& layer) { return false; } - -/* - works only if we have one date input and one output - */ -void RemoveSingleInputNodeFromFunction(std::shared_ptr node) { - const ov::Shape input_node_shape = node->get_input_shape(0); - const ov::Shape output_node_shape = node->get_output_shape(0); - - std::shared_ptr node_parent = node->get_input_node_shared_ptr(0); - if (!std::equal(input_node_shape.begin(), input_node_shape.end(), output_node_shape.begin())) { - auto reshape_const_node = - std::make_shared(ov::element::i64, ov::Shape{output_node_shape.size()}, output_node_shape); - node_parent = std::make_shared(node_parent, reshape_const_node, false); - } - - ov::replace_output_update_name(node->output(0), node_parent->output(0)); -} - /* Support only one data node as 0 input */ @@ -110,7 +85,7 @@ bool RemoveInputsProcessing::run_on_model(const std::shared_ptr& mode m_subgraph_cpu_map->emplace(param_node.get_node_shared_ptr()->get_friendly_name(), CopySingleInputNodeFromFunction(target_node)); } - RemoveSingleInputNodeFromFunction(target_node); + pass::helper::RemoveSingleInputNodeFromFunction(target_node); result = true; } } @@ -130,7 +105,7 @@ bool RemoveOutputsProcessing::run_on_model(const std::shared_ptr& mod m_subgraph_cpu_map->emplace(r_input_node->get_friendly_name(), CopySingleInputNodeFromFunction(r_input_node)); } - RemoveSingleInputNodeFromFunction(r_input_node); + pass::helper::RemoveSingleInputNodeFromFunction(r_input_node); result = true; } } diff --git a/src/plugins/intel_gna/src/transformations/utils/transformation_helper.cpp b/src/plugins/intel_gna/src/transformations/utils/transformation_helper.cpp index dea1b0181f451f..2a85956cdd6dd3 100644 --- a/src/plugins/intel_gna/src/transformations/utils/transformation_helper.cpp +++ b/src/plugins/intel_gna/src/transformations/utils/transformation_helper.cpp @@ -4,12 +4,14 @@ #include "transformation_helper.hpp" -#include +#include "openvino/opsets/opset7.hpp" #include #include #include "ops/gna_convolution.hpp" #include "ops/gna_max_pool.hpp" +using namespace ov::opset7; + namespace ov { namespace intel_gna { namespace pass { @@ -105,6 +107,29 @@ std::shared_ptr InsertFQLayer(const std::shared_ptr node) { + const ov::Shape input_node_shape = node->get_input_shape(0); + const ov::Shape output_node_shape = node->get_output_shape(0); + + std::shared_ptr node_parent = node->get_input_node_shared_ptr(0); + if (!std::equal(input_node_shape.begin(), input_node_shape.end(), output_node_shape.begin())) { + auto reshape_const_node = + std::make_shared(ov::element::i64, ov::Shape{output_node_shape.size()}, output_node_shape); + node_parent = std::make_shared(node_parent, reshape_const_node, false); + } + + ov::replace_output_update_name(node->output(0), node_parent->output(0)); +} + +ov::Shape SqueezeShape(const ov::Shape& shape) { + ov::Shape squeezed_shape; + std::copy_if(shape.begin(), shape.end(), std::back_inserter(squeezed_shape), [](size_t x) { + return x != 1; + }); + return squeezed_shape; +} + } // namespace helper } // namespace pass } // namespace intel_gna diff --git a/src/plugins/intel_gna/src/transformations/utils/transformation_helper.hpp b/src/plugins/intel_gna/src/transformations/utils/transformation_helper.hpp index 7baf3eaf81f678..f3fd42052a36dd 100644 --- a/src/plugins/intel_gna/src/transformations/utils/transformation_helper.hpp +++ b/src/plugins/intel_gna/src/transformations/utils/transformation_helper.hpp @@ -110,6 +110,20 @@ std::shared_ptr VerifyBiasGetConst(std::shared_ptr c std::shared_ptr InsertFQLayer(const std::shared_ptr fq_layer, std::shared_ptr last_node); +/** + * @brief removes single node from the function and insert Reshape if input and outpur shapes are different + * @param node the node to be deleted + * @return void + */ +void RemoveSingleInputNodeFromFunction(std::shared_ptr node); + +/** + * @brief remove all 1 dimentions from the shape vector + * @param shape original tensor shape + * @return shape without 1 dimentions + */ +ov::Shape SqueezeShape(const ov::Shape& shape); + } // namespace helper } // namespace pass } // namespace intel_gna