From 9333dcf10ea21b09e7e13a7033089cfc72ee44a8 Mon Sep 17 00:00:00 2001 From: mbencer Date: Wed, 22 Jul 2020 13:52:56 +0200 Subject: [PATCH 1/2] Extend dynamic shape support for ops in auto padding mode --- ngraph/src/ngraph/op/avg_pool.cpp | 56 ++++--- ngraph/src/ngraph/op/binary_convolution.cpp | 39 ++++- .../src/ngraph/op/deformable_convolution.cpp | 115 +++++++------ ngraph/test/CMakeLists.txt | 3 + ngraph/test/type_prop/avg_pool.cpp | 105 ++++++++++++ ngraph/test/type_prop/binary_convolution.cpp | 115 +++++++++++++ .../test/type_prop/deformable_convolution.cpp | 157 ++++++++++++++++++ 7 files changed, 513 insertions(+), 77 deletions(-) create mode 100644 ngraph/test/type_prop/avg_pool.cpp create mode 100644 ngraph/test/type_prop/binary_convolution.cpp create mode 100644 ngraph/test/type_prop/deformable_convolution.cpp diff --git a/ngraph/src/ngraph/op/avg_pool.cpp b/ngraph/src/ngraph/op/avg_pool.cpp index 44abfb91460800..41f2d961d33f92 100644 --- a/ngraph/src/ngraph/op/avg_pool.cpp +++ b/ngraph/src/ngraph/op/avg_pool.cpp @@ -93,24 +93,36 @@ void op::v1::AvgPool::validate_and_infer_types() } const PartialShape& arg_shape = get_input_partial_shape(0); - - if (m_auto_pad == PadType::SAME_UPPER || m_auto_pad == PadType::SAME_LOWER) + auto output_shape = PartialShape::dynamic(); + if (arg_shape.rank().is_static()) { - if (arg_shape.is_static()) + output_shape = std::vector(arg_shape.rank().get_length(), Dimension::dynamic()); + if (arg_shape.rank().get_length() > 1) + { + output_shape[0] = arg_shape[0]; // batch size + } + if (arg_shape.rank().get_length() > 2) { - CoordinateDiff pads_end, pads_begin; - infer_auto_padding(arg_shape.to_shape(), - m_kernel, - m_strides, - Strides(m_kernel.size(), 1), // No dilation - m_auto_pad, - pads_end, - pads_begin); - m_pads_end = Shape(pads_end.begin(), pads_end.end()); - m_pads_begin = Shape(pads_begin.begin(), pads_begin.end()); + output_shape[1] = arg_shape[1]; // channel size } } + bool update_auto_padding_succeed = true; + if (m_auto_pad == PadType::SAME_UPPER || m_auto_pad == PadType::SAME_LOWER) + { + CoordinateDiff pads_end, pads_begin; + update_auto_padding_succeed = + try_apply_auto_padding(arg_shape, + m_kernel, + m_strides, + Strides(m_kernel.size(), 1), // No dilation + m_auto_pad, + pads_end, + pads_begin); + m_pads_end = Shape(pads_end.begin(), pads_end.end()); + m_pads_begin = Shape(pads_begin.begin(), pads_begin.end()); + } + // infer_batched_forward_pooling wants CoordinateDiffs for these, while the pooling ops for // now still take Shape (no negative padding). CoordinateDiff pads_begin(m_pads_begin.begin(), m_pads_begin.end()); @@ -118,14 +130,16 @@ void op::v1::AvgPool::validate_and_infer_types() set_output_type(0, get_input_element_type(0), - infer_batched_pooling_forward(this, - arg_shape, - pads_begin, - pads_end, - m_kernel, - m_strides, - !m_exclude_pad, - m_rounding_type == op::RoundingType::CEIL)); + update_auto_padding_succeed + ? infer_batched_pooling_forward(this, + arg_shape, + pads_begin, + pads_end, + m_kernel, + m_strides, + !m_exclude_pad, + m_rounding_type == op::RoundingType::CEIL) + : output_shape); } const Shape& op::v1::AvgPool::get_kernel() const diff --git a/ngraph/src/ngraph/op/binary_convolution.cpp b/ngraph/src/ngraph/op/binary_convolution.cpp index 66607b817d50f3..df8973e37be49f 100644 --- a/ngraph/src/ngraph/op/binary_convolution.cpp +++ b/ngraph/src/ngraph/op/binary_convolution.cpp @@ -77,6 +77,22 @@ void op::v1::BinaryConvolution::validate_and_infer_types() const PartialShape& filters_shape = get_input_partial_shape(1); element::Type filters_et = get_input_element_type(1); + PartialShape result_shape = PartialShape::dynamic(); + if (data_batch_shape.rank().is_static()) + { + result_shape = + std::vector(data_batch_shape.rank().get_length(), Dimension::dynamic()); + + if (data_batch_shape.rank().get_length() > 1) + { + result_shape[0] = data_batch_shape[0]; // batch size + } + } + if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) + { + result_shape[1] = filters_shape[0]; // filter channel size + } + if (m_strides.size() == 0) { m_strides = conv_default_strides(this, data_batch_shape, filters_shape); @@ -99,23 +115,28 @@ void op::v1::BinaryConvolution::validate_and_infer_types() if (m_auto_pad == PadType::SAME_UPPER || m_auto_pad == PadType::SAME_LOWER) { - if (data_batch_shape.is_static() && filters_shape.is_static()) + bool auto_padding_applied = false; + if (filters_shape.is_static()) { m_pads_begin.clear(); m_pads_end.clear(); auto filter_shape = filters_shape.to_shape(); filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I} - infer_auto_padding(data_batch_shape.to_shape(), - filter_shape, - m_strides, - m_dilations, - m_auto_pad, - m_pads_end, - m_pads_begin); + auto_padding_applied = try_apply_auto_padding(data_batch_shape, + filter_shape, + m_strides, + m_dilations, + m_auto_pad, + m_pads_end, + m_pads_begin); + } + if (!auto_padding_applied) + { + set_output_type(0, data_batch_et, result_shape); + return; } } - PartialShape result_shape; result_shape = infer_convolution_forward(this, data_batch_shape, Strides(data_batch_shape.rank().get_length() - 2, 1), diff --git a/ngraph/src/ngraph/op/deformable_convolution.cpp b/ngraph/src/ngraph/op/deformable_convolution.cpp index 50497dc33cba0c..82c30f2d26c84d 100644 --- a/ngraph/src/ngraph/op/deformable_convolution.cpp +++ b/ngraph/src/ngraph/op/deformable_convolution.cpp @@ -71,44 +71,6 @@ void op::v1::DeformableConvolution::validate_and_infer_types() element::Type deformable_values_et = get_input_element_type(1); element::Type filters_et = get_input_element_type(2); - if (m_strides.size() == 0) - { - m_strides = conv_default_strides(this, data_batch_shape, filters_shape); - } - - if (m_dilations.size() == 0) - { - m_dilations = conv_default_strides(this, data_batch_shape, filters_shape); - } - - if (m_pads_begin.size() == 0) - { - m_pads_begin = conv_default_padding(this, data_batch_shape, filters_shape); - } - - if (m_pads_end.size() == 0) - { - m_pads_end = conv_default_padding(this, data_batch_shape, filters_shape); - } - - if (m_auto_pad == PadType::SAME_UPPER || m_auto_pad == PadType::SAME_LOWER) - { - if (data_batch_shape.is_static() && filters_shape.is_static()) - { - m_pads_begin.clear(); - m_pads_end.clear(); - auto filter_shape = filters_shape.to_shape(); - filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I} - infer_auto_padding(data_batch_shape.to_shape(), - filter_shape, - m_strides, - m_dilations, - m_auto_pad, - m_pads_end, - m_pads_begin); - } - } - if (deformable_values_shape.rank().is_static()) { NODE_VALIDATION_CHECK( @@ -160,15 +122,74 @@ void op::v1::DeformableConvolution::validate_and_infer_types() filters_et, ")."); - const PartialShape result_shape = - infer_convolution_forward(this, - data_batch_shape, - Strides(m_strides.size(), 1), // dummy data dilations - m_pads_begin, - m_pads_end, - filters_shape, - m_strides, - m_dilations); + PartialShape result_shape = PartialShape::dynamic(); + if (data_batch_shape.rank().is_static()) + { + result_shape = + std::vector(data_batch_shape.rank().get_length(), Dimension::dynamic()); + + if (data_batch_shape.rank().get_length() > 1) + { + result_shape[0] = data_batch_shape[0]; // batch size + } + } + if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) + { + result_shape[1] = filters_shape[0]; // filter channel size + } + + if (m_strides.size() == 0) + { + m_strides = conv_default_strides(this, data_batch_shape, filters_shape); + } + + if (m_dilations.size() == 0) + { + m_dilations = conv_default_strides(this, data_batch_shape, filters_shape); + } + + if (m_pads_begin.size() == 0) + { + m_pads_begin = conv_default_padding(this, data_batch_shape, filters_shape); + } + + if (m_pads_end.size() == 0) + { + m_pads_end = conv_default_padding(this, data_batch_shape, filters_shape); + } + + if (m_auto_pad == PadType::SAME_UPPER || m_auto_pad == PadType::SAME_LOWER) + { + bool auto_padding_applied = false; + if (filters_shape.is_static()) + { + m_pads_begin.clear(); + m_pads_end.clear(); + auto filter_shape = filters_shape.to_shape(); + filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I} + auto_padding_applied = try_apply_auto_padding(data_batch_shape, + filter_shape, + m_strides, + m_dilations, + m_auto_pad, + m_pads_end, + m_pads_begin); + } + if (!auto_padding_applied) + { + set_output_type(0, data_batch_et, result_shape); + return; + } + } + + result_shape = infer_convolution_forward(this, + data_batch_shape, + Strides(m_strides.size(), 1), // dummy data dilations + m_pads_begin, + m_pads_end, + filters_shape, + m_strides, + m_dilations); set_output_type(0, result_et, result_shape); } diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index 59521922a3449d..f92b50b8610f3e 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -111,8 +111,10 @@ set(SRC tensor.cpp type_prop/any.cpp type_prop/assign.cpp + type_prop/avg_pool.cpp type_prop/batch_norm.cpp type_prop/batch_to_space.cpp + type_prop/binary_convolution.cpp type_prop/binary_elementwise.cpp type_prop/broadcast.cpp type_prop/bucketize.cpp @@ -123,6 +125,7 @@ set(SRC type_prop/convolution.cpp type_prop/crop_and_resize.cpp type_prop/ctc_loss.cpp + type_prop/deformable_convolution.cpp type_prop/deformable_psroi_pooling.cpp type_prop/depth_to_space.cpp type_prop/dequantize.cpp diff --git a/ngraph/test/type_prop/avg_pool.cpp b/ngraph/test/type_prop/avg_pool.cpp new file mode 100644 index 00000000000000..427e1ba5b20bac --- /dev/null +++ b/ngraph/test/type_prop/avg_pool.cpp @@ -0,0 +1,105 @@ +//***************************************************************************** +// Copyright 2017-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//***************************************************************************** + +#include "gtest/gtest.h" +#include "ngraph/ngraph.hpp" +#include "util/type_prop.hpp" + +using namespace std; +using namespace ngraph; + +TEST(type_prop, avg_pool_auto_padding) +{ + const PartialShape arg_shape{1, 3, 32, 32}; + const Strides strides{1, 1}; + const Shape pads_begin{0, 0}; + const Shape pads_end{0, 0}; + const Shape kernel_shape{2, 2}; + const bool exclude_pad = false; + const auto rounding_mode = op::RoundingType::FLOOR; + const auto auto_pad = op::PadType::SAME_LOWER; + + auto arg = make_shared(element::f32, arg_shape); + auto mp = make_shared( + arg, strides, pads_begin, pads_end, kernel_shape, exclude_pad, rounding_mode, auto_pad); + + ASSERT_TRUE(mp->get_output_partial_shape(0).same_scheme({1, 3, 32, 32})); + ASSERT_EQ(mp->get_pads_begin(), (Shape{1, 1})); + ASSERT_EQ(mp->get_pads_end(), (Shape{0, 0})); +} + +TEST(type_prop, avg_pool_auto_padding_nc_dims_dynamic_same_lower) +{ + const PartialShape arg_shape{Dimension::dynamic(), Dimension::dynamic(), 32, 32}; + const Strides strides{1, 1}; + const Shape pads_begin{0, 0}; + const Shape pads_end{0, 0}; + const Shape kernel_shape{2, 2}; + const bool exclude_pad = true; + const auto rounding_mode = op::RoundingType::FLOOR; + const auto auto_pad = op::PadType::SAME_LOWER; + + auto arg = make_shared(element::f32, arg_shape); + auto mp = make_shared( + arg, strides, pads_begin, pads_end, kernel_shape, exclude_pad, rounding_mode, auto_pad); + + ASSERT_TRUE(mp->get_output_partial_shape(0).same_scheme( + {Dimension::dynamic(), Dimension::dynamic(), 32, 32})); + ASSERT_EQ(mp->get_pads_begin(), (Shape{1, 1})); + ASSERT_EQ(mp->get_pads_end(), (Shape{0, 0})); +} + +TEST(type_prop, avg_pool_auto_padding_nc_dims_dynamic_same_upper) +{ + const PartialShape arg_shape{Dimension::dynamic(), Dimension::dynamic(), 32, 32}; + const Strides strides{1, 1}; + const Shape pads_begin{0, 0}; + const Shape pads_end{0, 0}; + const Shape kernel_shape{2, 2}; + const bool exclude_pad = false; + const auto rounding_mode = op::RoundingType::FLOOR; + const auto auto_pad = op::PadType::SAME_UPPER; + + auto arg = make_shared(element::f32, arg_shape); + auto mp = make_shared( + arg, strides, pads_begin, pads_end, kernel_shape, exclude_pad, rounding_mode, auto_pad); + + ASSERT_TRUE(mp->get_output_partial_shape(0).same_scheme( + {Dimension::dynamic(), Dimension::dynamic(), 32, 32})); + ASSERT_EQ(mp->get_pads_begin(), (Shape{0, 0})); + ASSERT_EQ(mp->get_pads_end(), (Shape{1, 1})); +} + +TEST(type_prop, avg_pool_auto_padding_spatial_dims_dynamic) +{ + const PartialShape arg_shape{1, 3, 32, Dimension::dynamic()}; + const Strides strides{1, 1}; + const Shape pads_begin{0, 0}; + const Shape pads_end{0, 0}; + const Shape kernel_shape{2, 2}; + const bool exclude_pad = true; + const auto rounding_mode = op::RoundingType::FLOOR; + const auto auto_pad = op::PadType::SAME_LOWER; + + auto arg = make_shared(element::f32, arg_shape); + auto mp = make_shared( + arg, strides, pads_begin, pads_end, kernel_shape, exclude_pad, rounding_mode, auto_pad); + + ASSERT_TRUE(mp->get_output_partial_shape(0).same_scheme( + {1, 3, Dimension::dynamic(), Dimension::dynamic()})); + ASSERT_EQ(mp->get_pads_begin(), (Shape{})); + ASSERT_EQ(mp->get_pads_end(), (Shape{})); +} diff --git a/ngraph/test/type_prop/binary_convolution.cpp b/ngraph/test/type_prop/binary_convolution.cpp new file mode 100644 index 00000000000000..2c62adff237e1d --- /dev/null +++ b/ngraph/test/type_prop/binary_convolution.cpp @@ -0,0 +1,115 @@ +//***************************************************************************** +// Copyright 2017-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//***************************************************************************** + +#include "gtest/gtest.h" +#include "ngraph/ngraph.hpp" +#include "util/type_prop.hpp" + +using namespace std; +using namespace ngraph; + +TEST(type_prop, binary_conv_v1_partial_auto_padding_same) +{ + const PartialShape data_batch_shape{1, 1, 5, 5}; + const PartialShape filters_shape{1, 1, 3, 3}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto mode = op::v1::BinaryConvolution::BinaryConvolutionMode::XNOR_POPCOUNT; + const float pad_value = 1.0f; + const auto auto_pad = op::PadType::SAME_LOWER; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto conv = make_shared( + data_batch, filters, strides, pads_begin, pads_end, dilations, mode, pad_value, auto_pad); + + ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape{1, 1, 5, 5})); + ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{1, 1})); + ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{1, 1})); +} + +TEST(type_prop, binary_conv_v1_partial_auto_padding_same_nc_dims_dynamic_same_lower) +{ + const PartialShape data_batch_shape{Dimension::dynamic(), Dimension::dynamic(), 5, 5}; + const PartialShape filters_shape{1, 1, 3, 3}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto mode = op::v1::BinaryConvolution::BinaryConvolutionMode::XNOR_POPCOUNT; + const float pad_value = 1.0f; + const auto auto_pad = op::PadType::SAME_LOWER; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto conv = make_shared( + data_batch, filters, strides, pads_begin, pads_end, dilations, mode, pad_value, auto_pad); + + ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme({Dimension::dynamic(), 1, 5, 5})); + ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{1, 1})); + ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{1, 1})); +} + +TEST(type_prop, binary_conv_v1_partial_auto_padding_same_nc_dims_dynamic_same_upper) +{ + const PartialShape data_batch_shape{Dimension::dynamic(), Dimension::dynamic(), 5, 5}; + const PartialShape filters_shape{1, 1, 2, 2}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto mode = op::v1::BinaryConvolution::BinaryConvolutionMode::XNOR_POPCOUNT; + const float pad_value = 1.0f; + const auto auto_pad = op::PadType::SAME_UPPER; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto conv = make_shared( + data_batch, filters, strides, pads_begin, pads_end, dilations, mode, pad_value, auto_pad); + + ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme({Dimension::dynamic(), 1, 5, 5})); + ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{0, 0})); + ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{1, 1})); +} + +TEST(type_prop, binary_conv_v1_partial_auto_padding_same_spatial_dims_dynamic) +{ + const PartialShape data_batch_shape{1, 1, Dimension::dynamic(), 5}; + const PartialShape filters_shape{1, 1, 3, 3}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto mode = op::v1::BinaryConvolution::BinaryConvolutionMode::XNOR_POPCOUNT; + const float pad_value = 1.0f; + const auto auto_pad = op::PadType::SAME_LOWER; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto conv = make_shared( + data_batch, filters, strides, pads_begin, pads_end, dilations, mode, pad_value, auto_pad); + + ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( + {1, 1, Dimension::dynamic(), Dimension::dynamic()})); + ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{})); + ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{})); +} diff --git a/ngraph/test/type_prop/deformable_convolution.cpp b/ngraph/test/type_prop/deformable_convolution.cpp new file mode 100644 index 00000000000000..508ce147176c91 --- /dev/null +++ b/ngraph/test/type_prop/deformable_convolution.cpp @@ -0,0 +1,157 @@ +//***************************************************************************** +// Copyright 2017-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//***************************************************************************** + +#include "gtest/gtest.h" +#include "ngraph/ngraph.hpp" +#include "util/type_prop.hpp" + +using namespace std; +using namespace ngraph; + +TEST(type_prop, deformable_conv_v1_partial_auto_padding_same) +{ + const PartialShape data_batch_shape{1, 4, 5, 5}; + const PartialShape deformable_shape{1, 4, 3, 3}; + const PartialShape filters_shape{4, 4, 3, 3}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto auto_pad = op::PadType::SAME_LOWER; + const int64_t group = 4; + const int64_t deformable_group = 2; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto deformable_values = make_shared(element::f32, deformable_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto deformable_conv = make_shared(data_batch, + deformable_values, + filters, + strides, + pads_begin, + pads_end, + dilations, + auto_pad, + group, + deformable_group); + + ASSERT_TRUE(deformable_conv->get_output_partial_shape(0).same_scheme(PartialShape{1, 4, 5, 5})); + ASSERT_EQ(deformable_conv->get_pads_begin(), (CoordinateDiff{1, 1})); + ASSERT_EQ(deformable_conv->get_pads_end(), (CoordinateDiff{1, 1})); +} + +TEST(type_prop, deformable_conv_v1_partial_auto_padding_same_nc_dims_dynamic_same_lower) +{ + const PartialShape data_batch_shape{Dimension::dynamic(), Dimension::dynamic(), 5, 5}; + const PartialShape deformable_shape{1, 4, 3, 3}; + const PartialShape filters_shape{4, 4, 3, 3}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto auto_pad = op::PadType::SAME_LOWER; + const int64_t group = 4; + const int64_t deformable_group = 2; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto deformable_values = make_shared(element::f32, deformable_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto deformable_conv = make_shared(data_batch, + deformable_values, + filters, + strides, + pads_begin, + pads_end, + dilations, + auto_pad, + group, + deformable_group); + + ASSERT_TRUE(deformable_conv->get_output_partial_shape(0).same_scheme( + PartialShape{Dimension::dynamic(), 4, 5, 5})); + ASSERT_EQ(deformable_conv->get_pads_begin(), (CoordinateDiff{1, 1})); + ASSERT_EQ(deformable_conv->get_pads_end(), (CoordinateDiff{1, 1})); +} + +TEST(type_prop, deformable_conv_v1_partial_auto_padding_same_nc_dims_dynamic_same_upper) +{ + const PartialShape data_batch_shape{Dimension::dynamic(), Dimension::dynamic(), 5, 5}; + const PartialShape deformable_shape{1, 4, 2, 2}; + const PartialShape filters_shape{4, 4, 2, 2}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto auto_pad = op::PadType::SAME_UPPER; + const int64_t group = 4; + const int64_t deformable_group = 2; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto deformable_values = make_shared(element::f32, deformable_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto deformable_conv = make_shared(data_batch, + deformable_values, + filters, + strides, + pads_begin, + pads_end, + dilations, + auto_pad, + group, + deformable_group); + + ASSERT_TRUE(deformable_conv->get_output_partial_shape(0).same_scheme( + PartialShape{Dimension::dynamic(), 4, 5, 5})); + ASSERT_EQ(deformable_conv->get_pads_begin(), (CoordinateDiff{0, 0})); + ASSERT_EQ(deformable_conv->get_pads_end(), (CoordinateDiff{1, 1})); +} + +TEST(type_prop, deformable_conv_v1_partial_auto_padding_same_spatial_dims_dynamic) +{ + const PartialShape data_batch_shape{1, 4, Dimension::dynamic(), 5}; + const PartialShape deformable_shape{1, 4, 3, 3}; + const PartialShape filters_shape{4, 4, 3, 3}; + Strides strides{1, 1}; + CoordinateDiff pads_begin{0, 0}; + CoordinateDiff pads_end{0, 0}; + Strides dilations{1, 1}; + const auto auto_pad = op::PadType::SAME_LOWER; + const int64_t group = 4; + const int64_t deformable_group = 2; + + auto data_batch = make_shared(element::f32, data_batch_shape); + auto deformable_values = make_shared(element::f32, deformable_shape); + auto filters = make_shared(element::f32, filters_shape); + + auto deformable_conv = make_shared(data_batch, + deformable_values, + filters, + strides, + pads_begin, + pads_end, + dilations, + auto_pad, + group, + deformable_group); + + ASSERT_TRUE(deformable_conv->get_output_partial_shape(0).same_scheme( + {1, 4, Dimension::dynamic(), Dimension::dynamic()})); + ASSERT_EQ(deformable_conv->get_pads_begin(), (CoordinateDiff{})); + ASSERT_EQ(deformable_conv->get_pads_end(), (CoordinateDiff{})); +} From 67e8349beb3b4526731214bc5c23f5f16c8b2ed4 Mon Sep 17 00:00:00 2001 From: mbencer Date: Wed, 29 Jul 2020 09:56:30 +0200 Subject: [PATCH 2/2] fix after code review --- ngraph/src/ngraph/op/binary_convolution.cpp | 9 +++++---- ngraph/src/ngraph/op/convolution.cpp | 9 +++++---- ngraph/src/ngraph/op/deformable_convolution.cpp | 9 +++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ngraph/src/ngraph/op/binary_convolution.cpp b/ngraph/src/ngraph/op/binary_convolution.cpp index df8973e37be49f..40fded3b786041 100644 --- a/ngraph/src/ngraph/op/binary_convolution.cpp +++ b/ngraph/src/ngraph/op/binary_convolution.cpp @@ -87,10 +87,11 @@ void op::v1::BinaryConvolution::validate_and_infer_types() { result_shape[0] = data_batch_shape[0]; // batch size } - } - if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) - { - result_shape[1] = filters_shape[0]; // filter channel size + + if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) + { + result_shape[1] = filters_shape[0]; // filter channel size + } } if (m_strides.size() == 0) diff --git a/ngraph/src/ngraph/op/convolution.cpp b/ngraph/src/ngraph/op/convolution.cpp index b88668529a1497..7cc68649098972 100644 --- a/ngraph/src/ngraph/op/convolution.cpp +++ b/ngraph/src/ngraph/op/convolution.cpp @@ -72,10 +72,11 @@ void op::v1::Convolution::validate_and_infer_types() { result_shape[0] = data_batch_shape[0]; // batch size } - } - if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) - { - result_shape[1] = filters_shape[0]; // filter channel size + + if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) + { + result_shape[1] = filters_shape[0]; // filter channel size + } } element::Type result_et; diff --git a/ngraph/src/ngraph/op/deformable_convolution.cpp b/ngraph/src/ngraph/op/deformable_convolution.cpp index 82c30f2d26c84d..781c7f778f8cfb 100644 --- a/ngraph/src/ngraph/op/deformable_convolution.cpp +++ b/ngraph/src/ngraph/op/deformable_convolution.cpp @@ -132,10 +132,11 @@ void op::v1::DeformableConvolution::validate_and_infer_types() { result_shape[0] = data_batch_shape[0]; // batch size } - } - if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) - { - result_shape[1] = filters_shape[0]; // filter channel size + + if (filters_shape.rank().is_static() && filters_shape.rank().get_length() > 1) + { + result_shape[1] = filters_shape[0]; // filter channel size + } } if (m_strides.size() == 0)