DO detachment (#10577)

This commit is contained in:
Evgenya Stepyreva
2022-02-22 12:05:18 +03:00
committed by GitHub
parent 4075f8ed51
commit 4afd8667cf
4 changed files with 95 additions and 14 deletions
@@ -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<ov::Model>& 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<std::shared_ptr<ov::opset1::Parameter>, ov::PartialShape>& parameter_to_shape, bool leave_batch_dynamic = true);
bool check_batch_tracks_through_all_the_nodes(const std::shared_ptr<ov::Model>& m);
P2Btype find_batch(const std::shared_ptr<ov::Model> &m);
bool detach_detection_output(const std::shared_ptr<ov::Model>& f);
} // namespace batch_util
} // namespace ov
@@ -8,6 +8,7 @@
#include <ngraph/rt_info.hpp>
#include <openvino/opsets/opset1.hpp>
#include <openvino/opsets/opset3.hpp>
#include <openvino/opsets/opset8.hpp>
#include <vector>
#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<ov::Model>& 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<opset1::Convert>(do_node)) // cases with do->convert->result
do_node = do_node->get_input_node_shared_ptr(0);
if (ov::is_type<opset1::DetectionOutput>(do_node) || ov::is_type<opset8::DetectionOutput>(do_node)) {
for (auto& new_result_src : do_node->input_values()) {
auto new_result = std::make_shared<opset1::Result>(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<ov::Model>& m) {
auto te = std::make_shared<ov::TableOfEquivalence>();
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<std::shared_ptr<ov::opset1::Parameter>, 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;
}
+1 -4
View File
@@ -775,10 +775,7 @@ InferenceEngine::IExecutableNetworkInternal::Ptr AutoBatchInferencePlugin::LoadN
// find the batch dim
ov::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
if (check_dims)
m.register_pass<ov::pass::FindBatch>();
else
m.register_pass<ov::pass::FindBatchDontTrack>();
m.register_pass<ov::pass::FindBatch>(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)
@@ -224,7 +224,7 @@ TEST(TransformationTests, AutoBatch_FindBatch_NegativeTracking) {
ov::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<ov::pass::FindBatchDontTrack>();
m.register_pass<ov::pass::FindBatch>(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::opset1::Parameter>(ov::element::f32, ov::Shape{1, 4, 10, 10});
const auto& constant_0 = std::make_shared<ov::opset1::Constant>(ov::element::f32, ov::Shape{1, 1, 1, 1});
const auto& mul_0 = std::make_shared<ov::opset1::Multiply>(data, constant_0);
const auto& filters = std::make_shared<ov::opset1::Constant>(ov::element::f32, ov::Shape{1, 4, 1, 1});
const auto& conv = std::make_shared<ov::opset1::Convolution>(
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::opset1::Constant>(
ov::element::i64, ov::Shape{2}, std::vector<int64_t>{0, -1});
const auto& box_logits = std::make_shared<ov::opset1::Reshape>(conv, box_logits_reshape, true);
const auto& four_times = std::make_shared<ov::opset1::Tile>(box_logits, std::make_shared<ov::opset1::Constant>(
ov::element::i64, ov::Shape{2}, std::vector<int64_t>{1, 4}));
const auto& third_input_reshape = std::make_shared<ov::opset1::Constant>(
ov::element::i64, ov::Shape{3}, std::vector<int64_t>{0, 1, -1});
const auto& third_input = std::make_shared<ov::opset1::Reshape>(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<ov::opset1::DetectionOutput>(four_times, four_times, third_input, attr);
const auto& convert = std::make_shared<ov::opset1::Convert>(detection, ov::element::f32);
const auto& f = std::make_shared<ov::Model>(ov::NodeVector{convert}, ov::ParameterVector{data});
ov::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<ov::pass::FindBatch>(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);