From 25e89a754da6fc32a3715453ecb83af0c7463f66 Mon Sep 17 00:00:00 2001 From: Marcin Kusmierski Date: Wed, 23 Aug 2023 14:11:16 +0200 Subject: [PATCH] [GNA] Fix memory leak in insert_copy_layer.cpp (#19266) * Added cleanup transformation for inert copy layer transforamtions --- .../src/gna_transformations_pipeline.cpp | 2 + .../src/transformations/insert_copy_layer.cpp | 47 ++++++++++++------- .../src/transformations/insert_copy_layer.hpp | 6 +++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/plugins/intel_gna/src/gna_transformations_pipeline.cpp b/src/plugins/intel_gna/src/gna_transformations_pipeline.cpp index 22ce84967ed..eabb6e77196 100644 --- a/src/plugins/intel_gna/src/gna_transformations_pipeline.cpp +++ b/src/plugins/intel_gna/src/gna_transformations_pipeline.cpp @@ -192,6 +192,8 @@ void TransformationsPipeline::apply(const std::shared_ptr& model, manager.register_pass(); manager.register_pass(); manager.register_pass(); + manager.register_pass(); + manager.register_pass(precisions_map{{ov::element::i64, ov::element::i32}, {ov::element::u64, ov::element::i32}, {ov::element::u32, ov::element::i32}}); diff --git a/src/plugins/intel_gna/src/transformations/insert_copy_layer.cpp b/src/plugins/intel_gna/src/transformations/insert_copy_layer.cpp index 285d58e8ef7..f08cc9f4e2e 100644 --- a/src/plugins/intel_gna/src/transformations/insert_copy_layer.cpp +++ b/src/plugins/intel_gna/src/transformations/insert_copy_layer.cpp @@ -20,6 +20,9 @@ using namespace ov::intel_gna::pass; using namespace ov::intel_gna::graph_utils; using namespace ov::opset9; +static const std::string kNonCompProperty("non_compute_node"); +static const std::string kResultProperty("result_vector"); + NGRAPH_RTTI_DEFINITION(InsertCopyBeforeAssignLayer, "InsertCopyBeforeAssignLayer"); NGRAPH_RTTI_DEFINITION(InsertCopyBeforeConcatLayer, "InsertCopyBeforeConcatLayer"); NGRAPH_RTTI_DEFINITION(HandleMultiConnectedLayerToConcatAndMemory, "HandleMultiConnectedLayerToConcatAndMemory"); @@ -341,54 +344,66 @@ MatchNonComputationalLayers::MatchNonComputationalLayers() { return false; } - std::string noncomp_prop("non_compute_node"); - std::string result_prop("result_vector"); - // Since we traverse graph in reverse order, the result should be one of the first nodes auto& rt_info = node->get_rt_info(); auto res_node = std::dynamic_pointer_cast(node); if (res_node) { - rt_info[noncomp_prop] = true; + rt_info[kNonCompProperty] = true; // We collect the results to the vector, because it possible to have // two different non-computational subgraphs with different results - rt_info[result_prop] = ngraph::ResultVector{res_node}; + rt_info[kResultProperty] = ngraph::ResultVector{res_node}; } - if (!rt_info.count(noncomp_prop) || !rt_info[noncomp_prop].as()) + if (!rt_info.count(kNonCompProperty) || !rt_info[kNonCompProperty].as()) { return false; + } // if current node is non-computational, pass the properties for each input for (size_t i = 0; i < node->get_input_size(); i++) { auto& input_rti = node->get_input_node_shared_ptr(i)->get_rt_info(); - input_rti[noncomp_prop] = true; - if (input_rti.count(result_prop) && !input_rti[result_prop].as().empty()) { - for (auto&& res : rt_info[result_prop].as()) { - input_rti[result_prop].as().push_back(res); + input_rti[kNonCompProperty] = true; + if (input_rti.count(kResultProperty) && !input_rti[kResultProperty].as().empty()) { + for (auto&& res : rt_info[kResultProperty].as()) { + input_rti[kResultProperty].as().push_back(res); } } else { - input_rti[result_prop] = rt_info[result_prop]; + input_rti[kResultProperty] = rt_info[kResultProperty]; } } - // Found parameter node with non-computational property, so we detected desired subgraph // Need to insert a copy op for each pre-result node, that runs out to this parameter if (std::dynamic_pointer_cast(node)) { - auto result_vec = rt_info[result_prop].as(); + auto result_vec = rt_info[kResultProperty].as(); for (auto&& result_node : result_vec) { auto copy_out = result_node->get_input_node_shared_ptr(0); for (size_t i = 0; i < copy_out->get_input_size(); i++) { auto copy_in = copy_out->get_input_node_shared_ptr(i); if (!std::dynamic_pointer_cast(copy_in) && // Copy already inserted from different result - !std::dynamic_pointer_cast(copy_in)) + !std::dynamic_pointer_cast(copy_in)) { insert_copy_layer_between(copy_in, copy_out, i); + } } } } - return true; }; auto m = std::make_shared(noncompute_op, matcher_name); this->register_matcher(m, callback); -} \ No newline at end of file +} + +bool HandleNonFunctionalSubgraphsCleanup::run_on_model(const std::shared_ptr& m) { + RUN_ON_MODEL_SCOPE(HandleNonFunctionalSubgraphsCleanup); + + std::vector properties{kNonCompProperty, kResultProperty}; + + for (const auto& node : m->get_ops()) { + auto& rt_info = node->get_rt_info(); + for (const auto& property : properties) { + rt_info.erase(property); + } + } + + return false; +} diff --git a/src/plugins/intel_gna/src/transformations/insert_copy_layer.hpp b/src/plugins/intel_gna/src/transformations/insert_copy_layer.hpp index 4ef76b9d687..1e9532bf19d 100644 --- a/src/plugins/intel_gna/src/transformations/insert_copy_layer.hpp +++ b/src/plugins/intel_gna/src/transformations/insert_copy_layer.hpp @@ -192,6 +192,12 @@ public: } }; +class HandleNonFunctionalSubgraphsCleanup : public ov::pass::ModelPass { +public: + OPENVINO_RTTI("HandleNonFunctionalSubgraphsCleanup", "0"); + bool run_on_model(const std::shared_ptr& m) override; +}; + } // namespace pass } // namespace intel_gna } // namespace ov