[GNA] Fix memory leak in insert_copy_layer.cpp (#19266)
* Added cleanup transformation for inert copy layer transforamtions
This commit is contained in:
parent
59d58b2296
commit
25e89a754d
@ -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::HandleMultiConnectedLayerToConcatAndMemory>();
|
||||
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},
|
||||
{ov::element::u64, ov::element::i32},
|
||||
{ov::element::u32, ov::element::i32}});
|
||||
|
@ -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<ngraph::opset8::Result>(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<bool>())
|
||||
if (!rt_info.count(kNonCompProperty) || !rt_info[kNonCompProperty].as<bool>()) {
|
||||
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<ngraph::ResultVector>().empty()) {
|
||||
for (auto&& res : rt_info[result_prop].as<ngraph::ResultVector>()) {
|
||||
input_rti[result_prop].as<ngraph::ResultVector>().push_back(res);
|
||||
input_rti[kNonCompProperty] = true;
|
||||
if (input_rti.count(kResultProperty) && !input_rti[kResultProperty].as<ngraph::ResultVector>().empty()) {
|
||||
for (auto&& res : rt_info[kResultProperty].as<ngraph::ResultVector>()) {
|
||||
input_rti[kResultProperty].as<ngraph::ResultVector>().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<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) {
|
||||
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<ngraph::opset8::Constant>(copy_in) &&
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(noncompute_op, matcher_name);
|
||||
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;
|
||||
}
|
||||
|
@ -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 intel_gna
|
||||
} // namespace ov
|
||||
|
Loading…
Reference in New Issue
Block a user