From 4afd8667cfd41cbee3dfcc72d4fd3763fcc8e194 Mon Sep 17 00:00:00 2001 From: Evgenya Stepyreva Date: Tue, 22 Feb 2022 12:05:18 +0300 Subject: [PATCH] DO detachment (#10577) --- .../dimension_tracking.hpp | 11 +--- .../dimension_tracking.cpp | 28 +++++++- src/plugins/auto_batch/auto_batch.cpp | 5 +- .../dimension_tracking.cpp | 65 ++++++++++++++++++- 4 files changed, 95 insertions(+), 14 deletions(-) diff --git a/src/common/transformations/include/transformations/common_optimizations/dimension_tracking.hpp b/src/common/transformations/include/transformations/common_optimizations/dimension_tracking.hpp index 123bf121f8e..a1137a70233 100644 --- a/src/common/transformations/include/transformations/common_optimizations/dimension_tracking.hpp +++ b/src/common/transformations/include/transformations/common_optimizations/dimension_tracking.hpp @@ -17,7 +17,6 @@ namespace ov { namespace pass { class TRANSFORMATIONS_API FindBatch; -class TRANSFORMATIONS_API FindBatchDontTrack; } // namespace pass } // namespace ov @@ -25,15 +24,10 @@ class TRANSFORMATIONS_API FindBatchDontTrack; class ov::pass::FindBatch: public ov::pass::ModelPass { public: OPENVINO_RTTI("FindBatch"); - FindBatch(bool track = true) : track(track) {} + FindBatch(bool detach_detection_output = false, bool track = true) : track(track), detach_do(detach_detection_output) {} bool run_on_model(const std::shared_ptr& m) override; protected: - bool track = true; -}; - -class ov::pass::FindBatchDontTrack: public ov::pass::FindBatch { -public: - FindBatchDontTrack() : FindBatch(false) {} + bool track = true, detach_do = false; }; namespace ov { @@ -48,5 +42,6 @@ namespace batch_util { const std::map, ov::PartialShape>& parameter_to_shape, bool leave_batch_dynamic = true); bool check_batch_tracks_through_all_the_nodes(const std::shared_ptr& m); P2Btype find_batch(const std::shared_ptr &m); + bool detach_detection_output(const std::shared_ptr& f); } // namespace batch_util } // namespace ov diff --git a/src/common/transformations/src/transformations/common_optimizations/dimension_tracking.cpp b/src/common/transformations/src/transformations/common_optimizations/dimension_tracking.cpp index edf96b55df1..197f7e38ecf 100644 --- a/src/common/transformations/src/transformations/common_optimizations/dimension_tracking.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/dimension_tracking.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "dimension_tracker.hpp" @@ -221,16 +222,41 @@ bool ov::batch_util::check_batch_tracks_through_all_the_nodes(const std::shared_ return failed_to_propagate_batch; } +bool ov::batch_util::detach_detection_output(const std::shared_ptr& f) { + ResultVector new_outputs, outputs_to_delete; + for (auto& result_node : f->get_results()) { + auto do_node = result_node->input_value(0).get_node_shared_ptr(); + if (ov::is_type(do_node)) // cases with do->convert->result + do_node = do_node->get_input_node_shared_ptr(0); + if (ov::is_type(do_node) || ov::is_type(do_node)) { + for (auto& new_result_src : do_node->input_values()) { + auto new_result = std::make_shared(new_result_src); + ngraph::copy_runtime_info(result_node, new_result); + new_outputs.push_back(new_result); + } + outputs_to_delete.push_back(result_node); + } + } + for (auto& result : outputs_to_delete) + f->remove_result(result); + f->add_results(new_outputs); + return !new_outputs.empty() || !outputs_to_delete.empty(); +} + bool ov::pass::FindBatch::run_on_model(const std::shared_ptr& m) { auto te = std::make_shared(); ov::DimensionTracker dt(te); + bool model_has_changed = false; + if (detach_do) + model_has_changed |= batch_util::detach_detection_output(m); + const auto& parameters = m->get_parameters(); std::map, PartialShape> parameter_to_shape; for (const auto& parameter : parameters) { auto shape = parameter->get_partial_shape(); if (shape.rank().is_dynamic()) - return false; + return model_has_changed; parameter_to_shape[parameter] = shape; } diff --git a/src/plugins/auto_batch/auto_batch.cpp b/src/plugins/auto_batch/auto_batch.cpp index b5b2665442b..872d0e3bb17 100644 --- a/src/plugins/auto_batch/auto_batch.cpp +++ b/src/plugins/auto_batch/auto_batch.cpp @@ -775,10 +775,7 @@ InferenceEngine::IExecutableNetworkInternal::Ptr AutoBatchInferencePlugin::LoadN // find the batch dim ov::pass::Manager m; m.register_pass(); - if (check_dims) - m.register_pass(); - else - m.register_pass(); + m.register_pass(true, check_dims); m.run_passes(function); // do not reshape/re-batch originally batched networks and when there are no inputs with the N* layouts // input(s) should have the batch dim as the first dim or none (current limitation of the auto-batching impl) diff --git a/src/tests/functional/inference_engine/transformations/common_optimizations/dimension_tracking.cpp b/src/tests/functional/inference_engine/transformations/common_optimizations/dimension_tracking.cpp index df5b6343c1b..ca65499ef84 100644 --- a/src/tests/functional/inference_engine/transformations/common_optimizations/dimension_tracking.cpp +++ b/src/tests/functional/inference_engine/transformations/common_optimizations/dimension_tracking.cpp @@ -224,7 +224,7 @@ TEST(TransformationTests, AutoBatch_FindBatch_NegativeTracking) { ov::pass::Manager m; m.register_pass(); - m.register_pass(); + m.register_pass(false, false); m.run_passes(f); ASSERT_NO_THROW(check_rt_info(f)); @@ -238,6 +238,69 @@ TEST(TransformationTests, AutoBatch_FindBatch_NegativeTracking) { ASSERT_TRUE(!ov::DimensionTracker::get_label(out_shape[0])) << out_shape; } +TEST(TransformationTests, AutoBatch_FindBatch_AutoBatch_LabelPropagation_DO_detachment) { + const auto& data = std::make_shared(ov::element::f32, ov::Shape{1, 4, 10, 10}); + + const auto& constant_0 = std::make_shared(ov::element::f32, ov::Shape{1, 1, 1, 1}); + const auto& mul_0 = std::make_shared(data, constant_0); + + const auto& filters = std::make_shared(ov::element::f32, ov::Shape{1, 4, 1, 1}); + const auto& conv = std::make_shared( + mul_0, filters, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0}, ov::Strides{1, 1}); + + const auto& box_logits_reshape = std::make_shared( + ov::element::i64, ov::Shape{2}, std::vector{0, -1}); + const auto& box_logits = std::make_shared(conv, box_logits_reshape, true); + + const auto& four_times = std::make_shared(box_logits, std::make_shared( + ov::element::i64, ov::Shape{2}, std::vector{1, 4})); + + const auto& third_input_reshape = std::make_shared( + ov::element::i64, ov::Shape{3}, std::vector{0, 1, -1}); + const auto& third_input = std::make_shared(four_times, third_input_reshape, true); + + ngraph::op::DetectionOutput::Attributes attr; + attr.num_classes = 4; + attr.background_label_id = 0; + attr.top_k = 75; + attr.variance_encoded_in_target = true; + attr.keep_top_k = {50}; + attr.code_type = std::string{"caffe.PriorBoxParameter.CORNER"}; + attr.share_location = true; + attr.nms_threshold = 0.5f; + attr.confidence_threshold = 0.5f; + attr.clip_after_nms = false; + attr.clip_before_nms = false; + attr.decrease_label_id = false; + attr.normalized = true; + attr.input_height = 1; + attr.input_width = 1; + attr.objectness_score = 0.4f; + + const auto& detection = std::make_shared(four_times, four_times, third_input, attr); + const auto& convert = std::make_shared(detection, ov::element::f32); + + const auto& f = std::make_shared(ov::NodeVector{convert}, ov::ParameterVector{data}); + + ov::pass::Manager m; + m.register_pass(); + m.register_pass(true); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + + const auto& shape = data->get_partial_shape(); + ASSERT_TRUE(ov::DimensionTracker::get_label(shape[0])) << shape; + ASSERT_TRUE(!ov::DimensionTracker::get_label(shape[1])) << shape; + ASSERT_TRUE(!ov::DimensionTracker::get_label(shape[2])) << shape; + ASSERT_TRUE(!ov::DimensionTracker::get_label(shape[3])) << shape; + ASSERT_EQ(f->get_results().size(), 3); + for (const auto& result : f->get_results()) { + const auto& out_shape = result->get_output_partial_shape(0); + ASSERT_TRUE(ov::DimensionTracker::get_label(out_shape[0])) << out_shape; + ASSERT_TRUE(!ov::DimensionTracker::get_label(out_shape[1])) << out_shape; + } +} + TEST(partial_shape, cout_with_label) { ov::Dimension a = 5; ov::DimensionTracker::set_label(a, 100500);