Skip to content

Commit

Permalink
[GNA] Fix memory leak in insert_copy_layer.cpp (openvinotoolkit#19266)
Browse files Browse the repository at this point in the history
* Added cleanup transformation for inert copy layer transforamtions
  • Loading branch information
marcinkusm authored and dood-apo committed Aug 24, 2023
1 parent f1a45e2 commit b7a2b7a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/gna_transformations_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}});
Expand Down
47 changes: 31 additions & 16 deletions src/transformations/insert_copy_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions src/transformations/insert_copy_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ class HandleNonFunctionalSubgraphs : public ngraph::pass::BackwardGraphRewrite {
}
};

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

0 comments on commit b7a2b7a

Please sign in to comment.