DO detachment (#10577)
This commit is contained in:
+3
-8
@@ -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
|
||||
|
||||
+27
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+64
-1
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user