[GNA] Fix memory leak in insert_copy_layer.cpp (#19266)

* Added cleanup transformation for inert copy layer transforamtions
This commit is contained in:
Marcin Kusmierski 2023-08-23 14:11:16 +02:00 committed by GitHub
parent 59d58b2296
commit 25e89a754d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 16 deletions

View File

@ -192,6 +192,8 @@ void TransformationsPipeline::apply(const std::shared_ptr<ov::Model>& model,
manager.register_pass<ov::intel_gna::pass::InsertCopyBeforeConcatLayer>(); manager.register_pass<ov::intel_gna::pass::InsertCopyBeforeConcatLayer>();
manager.register_pass<ov::intel_gna::pass::HandleMultiConnectedLayerToConcatAndMemory>(); manager.register_pass<ov::intel_gna::pass::HandleMultiConnectedLayerToConcatAndMemory>();
manager.register_pass<ov::intel_gna::pass::HandleNonFunctionalSubgraphs>(); manager.register_pass<ov::intel_gna::pass::HandleNonFunctionalSubgraphs>();
manager.register_pass<ov::intel_gna::pass::HandleNonFunctionalSubgraphsCleanup>();
manager.register_pass<ov::pass::ConvertPrecision>(precisions_map{{ov::element::i64, ov::element::i32}, manager.register_pass<ov::pass::ConvertPrecision>(precisions_map{{ov::element::i64, ov::element::i32},
{ov::element::u64, ov::element::i32}, {ov::element::u64, ov::element::i32},
{ov::element::u32, ov::element::i32}}); {ov::element::u32, ov::element::i32}});

View File

@ -20,6 +20,9 @@ using namespace ov::intel_gna::pass;
using namespace ov::intel_gna::graph_utils; using namespace ov::intel_gna::graph_utils;
using namespace ov::opset9; 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(InsertCopyBeforeAssignLayer, "InsertCopyBeforeAssignLayer");
NGRAPH_RTTI_DEFINITION(InsertCopyBeforeConcatLayer, "InsertCopyBeforeConcatLayer"); NGRAPH_RTTI_DEFINITION(InsertCopyBeforeConcatLayer, "InsertCopyBeforeConcatLayer");
NGRAPH_RTTI_DEFINITION(HandleMultiConnectedLayerToConcatAndMemory, "HandleMultiConnectedLayerToConcatAndMemory"); NGRAPH_RTTI_DEFINITION(HandleMultiConnectedLayerToConcatAndMemory, "HandleMultiConnectedLayerToConcatAndMemory");
@ -341,54 +344,66 @@ MatchNonComputationalLayers::MatchNonComputationalLayers() {
return false; 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 // Since we traverse graph in reverse order, the result should be one of the first nodes
auto& rt_info = node->get_rt_info(); auto& rt_info = node->get_rt_info();
auto res_node = std::dynamic_pointer_cast<ngraph::opset8::Result>(node); auto res_node = std::dynamic_pointer_cast<ngraph::opset8::Result>(node);
if (res_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 // We collect the results to the vector, because it possible to have
// two different non-computational subgraphs with different results // 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<bool>()) if (!rt_info.count(kNonCompProperty) || !rt_info[kNonCompProperty].as<bool>()) {
return false; return false;
}
// if current node is non-computational, pass the properties for each input // if current node is non-computational, pass the properties for each input
for (size_t i = 0; i < node->get_input_size(); i++) { for (size_t i = 0; i < node->get_input_size(); i++) {
auto& input_rti = node->get_input_node_shared_ptr(i)->get_rt_info(); auto& input_rti = node->get_input_node_shared_ptr(i)->get_rt_info();
input_rti[noncomp_prop] = true; input_rti[kNonCompProperty] = true;
if (input_rti.count(result_prop) && !input_rti[result_prop].as<ngraph::ResultVector>().empty()) { if (input_rti.count(kResultProperty) && !input_rti[kResultProperty].as<ngraph::ResultVector>().empty()) {
for (auto&& res : rt_info[result_prop].as<ngraph::ResultVector>()) { for (auto&& res : rt_info[kResultProperty].as<ngraph::ResultVector>()) {
input_rti[result_prop].as<ngraph::ResultVector>().push_back(res); input_rti[kResultProperty].as<ngraph::ResultVector>().push_back(res);
} }
} else { } 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 // 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 // Need to insert a copy op for each pre-result node, that runs out to this parameter
if (std::dynamic_pointer_cast<ngraph::opset8::Parameter>(node)) { if (std::dynamic_pointer_cast<ngraph::opset8::Parameter>(node)) {
auto result_vec = rt_info[result_prop].as<ngraph::ResultVector>(); auto result_vec = rt_info[kResultProperty].as<ngraph::ResultVector>();
for (auto&& result_node : result_vec) { for (auto&& result_node : result_vec) {
auto copy_out = result_node->get_input_node_shared_ptr(0); auto copy_out = result_node->get_input_node_shared_ptr(0);
for (size_t i = 0; i < copy_out->get_input_size(); i++) { for (size_t i = 0; i < copy_out->get_input_size(); i++) {
auto copy_in = copy_out->get_input_node_shared_ptr(i); auto copy_in = copy_out->get_input_node_shared_ptr(i);
if (!std::dynamic_pointer_cast<ngraph::opset8::Constant>(copy_in) && if (!std::dynamic_pointer_cast<ngraph::opset8::Constant>(copy_in) &&
// Copy already inserted from different result // Copy already inserted from different result
!std::dynamic_pointer_cast<ov::intel_gna::op::Copy>(copy_in)) !std::dynamic_pointer_cast<ov::intel_gna::op::Copy>(copy_in)) {
insert_copy_layer_between(copy_in, copy_out, i); insert_copy_layer_between(copy_in, copy_out, i);
}
} }
} }
} }
return true; return true;
}; };
auto m = std::make_shared<ngraph::pattern::Matcher>(noncompute_op, matcher_name); auto m = std::make_shared<ngraph::pattern::Matcher>(noncompute_op, matcher_name);
this->register_matcher(m, callback); this->register_matcher(m, callback);
} }
bool HandleNonFunctionalSubgraphsCleanup::run_on_model(const std::shared_ptr<ov::Model>& m) {
RUN_ON_MODEL_SCOPE(HandleNonFunctionalSubgraphsCleanup);
std::vector<std::string> 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;
}

View File

@ -192,6 +192,12 @@ public:
} }
}; };
class HandleNonFunctionalSubgraphsCleanup : public ov::pass::ModelPass {
public:
OPENVINO_RTTI("HandleNonFunctionalSubgraphsCleanup", "0");
bool run_on_model(const std::shared_ptr<ov::Model>& m) override;
};
} // namespace pass } // namespace pass
} // namespace intel_gna } // namespace intel_gna
} // namespace ov } // namespace ov