Deformable Convolution v8: transformations (#6533)
* add DeformableConv8to1 transformation * update deformable conv v8 to v1 transformation * Update inference-engine/src/transformations/src/transformations/op_conversions/convert_deformable_conv_v8_to_v1.cpp Co-authored-by: Gleb Kazantaev <gleb.nnstu@gmail.com> Co-authored-by: Gleb Kazantaev <gleb.nnstu@gmail.com>
This commit is contained in:
co-authored by
Gleb Kazantaev
parent
79f26cea7a
commit
85a5e9beb0
@@ -61,6 +61,7 @@
|
||||
#include <transformations/op_conversions/convert_nms_to_nms_ie_internal.hpp>
|
||||
#include <transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp>
|
||||
#include <transformations/op_conversions/convert_gather_0d.hpp>
|
||||
#include <transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp>
|
||||
#include <transformations/op_conversions/simplify_ctc_greedy_decoder_seq_len.hpp>
|
||||
#include <transformations/convert_precision.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
@@ -191,6 +192,7 @@ InferenceEngine::CNNNetwork clDNNEngine::CloneAndTransformNetwork(const Inferenc
|
||||
manager.register_pass<ngraph::pass::ConvertNMS4ToNMS5>();
|
||||
manager.register_pass<ngraph::pass::ConvertNMSToNMSIEInternal>();
|
||||
manager.register_pass<ngraph::pass::ConvertGather0D>();
|
||||
manager.register_pass<ngraph::pass::ConvertDeformableConv8To1>();
|
||||
|
||||
static const precisions_array convert_precision_list {
|
||||
{ngraph::element::i64, ngraph::element::i32},
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <transformations_visibility.hpp>
|
||||
|
||||
#include <ngraph/pass/graph_rewrite.hpp>
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API ConvertDeformableConv8To1;
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ngraph
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief ConvertDeformableConv8To1 converts v8::DeformableConvolution into v1::DeformableConvolution.
|
||||
*/
|
||||
class ngraph::pass::ConvertDeformableConv8To1 : public ngraph::pass::MatcherPass {
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
ConvertDeformableConv8To1();
|
||||
};
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp"
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
#include <ngraph/rt_info.hpp>
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
|
||||
#include "itt.hpp"
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(ngraph::pass::ConvertDeformableConv8To1, "ConvertDeformableConv8To1", 0);
|
||||
|
||||
ngraph::pass::ConvertDeformableConv8To1::ConvertDeformableConv8To1() {
|
||||
MATCHER_SCOPE(ConvertDeformableConv8To1);
|
||||
|
||||
auto deformable_conv_v8 = pattern::wrap_type<ngraph::opset8::DeformableConvolution>();
|
||||
|
||||
ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||
auto deformable_conv_v8_node = std::dynamic_pointer_cast<ngraph::opset8::DeformableConvolution>(m.get_match_root());
|
||||
if (!deformable_conv_v8_node)
|
||||
return false;
|
||||
|
||||
if (deformable_conv_v8_node->get_input_size() != 3
|
||||
|| deformable_conv_v8_node->get_bilinear_interpolation_pad())
|
||||
return false;
|
||||
|
||||
auto arg = deformable_conv_v8_node->input_value(0);
|
||||
auto offsets = deformable_conv_v8_node->input_value(1);
|
||||
auto filters = deformable_conv_v8_node->input_value(2);
|
||||
|
||||
auto deformable_conv_v1 =
|
||||
std::make_shared<ngraph::opset1::DeformableConvolution>(arg,
|
||||
offsets,
|
||||
filters,
|
||||
deformable_conv_v8_node->get_strides(),
|
||||
deformable_conv_v8_node->get_pads_begin(),
|
||||
deformable_conv_v8_node->get_pads_end(),
|
||||
deformable_conv_v8_node->get_dilations(),
|
||||
deformable_conv_v8_node->get_auto_pad(),
|
||||
deformable_conv_v8_node->get_group(),
|
||||
deformable_conv_v8_node->get_deformable_group());
|
||||
deformable_conv_v1->set_friendly_name(deformable_conv_v8_node->get_friendly_name());
|
||||
ngraph::copy_runtime_info(deformable_conv_v8_node, deformable_conv_v1);
|
||||
ngraph::replace_node(deformable_conv_v8_node, deformable_conv_v1);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<pattern::Matcher>(deformable_conv_v8, matcher_name);
|
||||
register_matcher(m, callback);
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST(TransformationTests, ConvertDeformableConv8to1) {
|
||||
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||
{
|
||||
const Strides strides{1, 1};
|
||||
const CoordinateDiff padding{0, 0};
|
||||
const Strides dilations{1, 1};
|
||||
|
||||
const Shape input_shape{1, 1, 4, 4};
|
||||
const Shape filter_shape{1, 1, 2, 2};
|
||||
const Shape offsets_shape{1, 8, 3, 3};
|
||||
|
||||
auto data = std::make_shared<opset8::Parameter>(element::f32, input_shape);
|
||||
auto filter = std::make_shared<opset8::Parameter>(element::f32, filter_shape);
|
||||
auto offsets = std::make_shared<opset8::Parameter>(element::f32, offsets_shape);
|
||||
|
||||
auto deformable_conv = std::make_shared<opset8::DeformableConvolution>(data,
|
||||
offsets,
|
||||
filter,
|
||||
strides,
|
||||
padding,
|
||||
padding,
|
||||
dilations);
|
||||
|
||||
f = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter, offsets});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::InitNodeInfo>();
|
||||
manager.register_pass<pass::ConvertDeformableConv8To1>();
|
||||
manager.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
|
||||
{
|
||||
const Strides strides{1, 1};
|
||||
const CoordinateDiff padding{0, 0};
|
||||
const Strides dilations{1, 1};
|
||||
|
||||
const Shape input_shape{1, 1, 4, 4};
|
||||
const Shape filter_shape{1, 1, 2, 2};
|
||||
const Shape offsets_shape{1, 8, 3, 3};
|
||||
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, input_shape);
|
||||
auto filter = std::make_shared<opset1::Parameter>(element::f32, filter_shape);
|
||||
auto offsets = std::make_shared<opset1::Parameter>(element::f32, offsets_shape);
|
||||
|
||||
auto deformable_conv = std::make_shared<opset1::DeformableConvolution>(data,
|
||||
offsets,
|
||||
filter,
|
||||
strides,
|
||||
padding,
|
||||
padding,
|
||||
dilations);
|
||||
|
||||
f_ref = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter, offsets});
|
||||
}
|
||||
|
||||
auto res = compare_functions(f, f_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, ConvertDeformableConv8to1_mask) {
|
||||
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||
{
|
||||
const Strides strides{1, 1};
|
||||
const CoordinateDiff padding{0, 0};
|
||||
const Strides dilations{1, 1};
|
||||
|
||||
const Shape input_shape{1, 1, 4, 4};
|
||||
const Shape filter_shape{1, 1, 2, 2};
|
||||
const Shape offsets_shape{1, 8, 3, 3};
|
||||
const Shape mask_shape{1, 4, 3, 3};
|
||||
|
||||
auto data = std::make_shared<opset8::Parameter>(element::f32, input_shape);
|
||||
auto filter = std::make_shared<opset8::Parameter>(element::f32, filter_shape);
|
||||
auto offsets = std::make_shared<opset8::Parameter>(element::f32, offsets_shape);
|
||||
auto mask = std::make_shared<opset8::Parameter>(element::f32, mask_shape);
|
||||
|
||||
auto deformable_conv = std::make_shared<opset8::DeformableConvolution>(data,
|
||||
offsets,
|
||||
filter,
|
||||
mask,
|
||||
strides,
|
||||
padding,
|
||||
padding,
|
||||
dilations);
|
||||
|
||||
f = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter,
|
||||
mask, offsets});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::InitNodeInfo>();
|
||||
manager.register_pass<pass::ConvertDeformableConv8To1>();
|
||||
manager.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
// mask input is provided, DeformableConvolution-8 must remain
|
||||
ASSERT_EQ(count_ops_of_type<opset1::DeformableConvolution>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<opset8::DeformableConvolution>(f), 1);
|
||||
}
|
||||
|
||||
TEST(TransformationTests, ConvertDeformableConv8to1_bilinear_interpolation_padding) {
|
||||
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||
{
|
||||
const Strides strides{1, 1};
|
||||
const CoordinateDiff padding{0, 0};
|
||||
const Strides dilations{1, 1};
|
||||
|
||||
const Shape input_shape{1, 1, 4, 4};
|
||||
const Shape filter_shape{1, 1, 2, 2};
|
||||
const Shape offsets_shape{1, 8, 3, 3};
|
||||
|
||||
auto data = std::make_shared<opset8::Parameter>(element::f32, input_shape);
|
||||
auto filter = std::make_shared<opset8::Parameter>(element::f32, filter_shape);
|
||||
auto offsets = std::make_shared<opset8::Parameter>(element::f32, offsets_shape);
|
||||
|
||||
auto deformable_conv = std::make_shared<opset8::DeformableConvolution>(data,
|
||||
offsets,
|
||||
filter,
|
||||
strides,
|
||||
padding,
|
||||
padding,
|
||||
dilations,
|
||||
op::PadType::EXPLICIT,
|
||||
1,
|
||||
1,
|
||||
true);
|
||||
|
||||
f = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter, offsets});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::InitNodeInfo>();
|
||||
manager.register_pass<pass::ConvertDeformableConv8To1>();
|
||||
manager.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
// use_bilinear_interpolation_padding is true, DeformableConvolution-8 must remain
|
||||
ASSERT_EQ(count_ops_of_type<opset1::DeformableConvolution>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<opset8::DeformableConvolution>(f), 1);
|
||||
}
|
||||
Reference in New Issue
Block a user