Fixed negative paddings for convolution backprop data (#3117)
authorIlya Churaev <ilya.churaev@intel.com>
Mon, 16 Nov 2020 12:30:18 +0000 (15:30 +0300)
committerGitHub <noreply@github.com>
Mon, 16 Nov 2020 12:30:18 +0000 (15:30 +0300)
* Fixed negative paddings for convolution backprop data

* Fixed code style

* Fixed comments

ngraph/core/src/validation_util.cpp
ngraph/test/type_prop/convolution.cpp

index aa266c0..0b5db85 100644 (file)
@@ -954,9 +954,10 @@ void ngraph::opset1::infer_conv_backprop_auto_padding(const Shape& input_data_sh
 
     for (uint64_t i = 0; i < num_spatial_dims; ++i)
     {
-        int total_padding = strides[i] * (input_data_shape[i] - 1) +
-                            dilations[i] * (filters_shape[i] - 1) + 1 - output_shape[i] +
-                            output_padding[i];
+        int total_padding = std::max<int>(strides[i] * (input_data_shape[i] - 1) +
+                                              dilations[i] * (filters_shape[i] - 1) + 1 -
+                                              output_shape[i] + output_padding[i],
+                                          0);
         if (auto_pad_type != op::PadType::SAME_UPPER)
         {
             pads_begin[i] = total_padding / 2;
index a0d5b56..b298f0a 100644 (file)
@@ -2665,6 +2665,56 @@ TEST(type_prop, conv_v1_partial_data_shape_dynamic)
     ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{}));
 }
 
+TEST(type_prop, conv_bprop_v1_partial_auto_padding_upper)
+{
+    const Shape shape1{1, 512, 1, 37};
+    const Shape shape2{512, 256, 1, 1};
+    const Shape shape3{2};
+    Strides strides{1, 2};
+    CoordinateDiff pads_begin{0, 0};
+    CoordinateDiff pads_end{0, 0};
+    Strides dilations{1, 1};
+    const auto auto_pad = op::PadType::SAME_UPPER;
+
+    auto in1 = make_shared<op::Parameter>(element::f32, shape1);
+    auto in2 = make_shared<op::Parameter>(element::f32, shape2);
+    std::vector<int64_t> data = {1, 74};
+    element::Type type = element::i64;
+    auto in3 = make_shared<op::Constant>(type, shape3, data);
+
+    auto conv = make_shared<op::v1::ConvolutionBackpropData>(
+        in1, in2, in3, strides, pads_begin, pads_end, dilations, auto_pad);
+    conv->validate_and_infer_types();
+
+    ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{0, 0}));
+    ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{0, 0}));
+}
+
+TEST(type_prop, conv_bprop_v1_partial_auto_padding_lower)
+{
+    const Shape shape1{1, 512, 1, 37};
+    const Shape shape2{512, 256, 1, 1};
+    const Shape shape3{2};
+    Strides strides{1, 2};
+    CoordinateDiff pads_begin{0, 0};
+    CoordinateDiff pads_end{0, 0};
+    Strides dilations{1, 1};
+    const auto auto_pad = op::PadType::SAME_LOWER;
+
+    auto in1 = make_shared<op::Parameter>(element::f32, shape1);
+    auto in2 = make_shared<op::Parameter>(element::f32, shape2);
+    std::vector<int64_t> data = {1, 74};
+    element::Type type = element::i64;
+    auto in3 = make_shared<op::Constant>(type, shape3, data);
+
+    auto conv = make_shared<op::v1::ConvolutionBackpropData>(
+        in1, in2, in3, strides, pads_begin, pads_end, dilations, auto_pad);
+    conv->validate_and_infer_types();
+
+    ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{0, 0}));
+    ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{0, 0}));
+}
+
 TEST(type_prop, deformable_conv_incorrect_group)
 {
     const PartialShape data_batch_shape{1, 3, 96, 96};