From 7a5c472ccc0fd60b9fe40fac3036ba3ea708f995 Mon Sep 17 00:00:00 2001 From: Katarzyna Mitrus Date: Thu, 6 Apr 2023 12:59:37 +0200 Subject: [PATCH] [ShapeInference] Fix Group Convolution shape infer - relax inputs size check (#16707) * Relax group conv inputs size check * Tests * Relax inputs size checks for Backprop Convs --- .../convolution_backprop_shape_inference.hpp | 4 ++-- ...volution_backprop_shape_inference_util.hpp | 2 +- ...p_convolution_backprop_shape_inference.hpp | 4 ++-- .../group_convolution_shape_inference.hpp | 2 +- ...inary_convolution_shape_inference_test.cpp | 19 +++++++++++++++ ...volution_backprop_shape_inference_test.cpp | 22 +++++++++++++++++ .../convolution_shape_inference_test.cpp | 19 +++++++++++++++ ...volution_backprop_shape_inference_test.cpp | 24 +++++++++++++++++++ ...group_convolution_shape_inference_test.cpp | 19 +++++++++++++++ 9 files changed, 109 insertions(+), 6 deletions(-) diff --git a/src/core/shape_inference/include/convolution_backprop_shape_inference.hpp b/src/core/shape_inference/include/convolution_backprop_shape_inference.hpp index a492a26b532..b4585434dc2 100644 --- a/src/core/shape_inference/include/convolution_backprop_shape_inference.hpp +++ b/src/core/shape_inference/include/convolution_backprop_shape_inference.hpp @@ -18,8 +18,8 @@ std::vector shape_infer(const ConvolutionBackpropData* op, CoordinateDiff& pads_end, const std::map& constant_data = {}) { const auto inputs_count = input_shapes.size(); - const auto has_spatial_shape = inputs_count == 3; - NODE_VALIDATION_CHECK(op, inputs_count == 2 || has_spatial_shape); + const auto has_spatial_shape = inputs_count >= 3; + NODE_VALIDATION_CHECK(op, inputs_count >= 2); using namespace ov::util; TShape out_spatial_shape; diff --git a/src/core/shape_inference/include/convolution_backprop_shape_inference_util.hpp b/src/core/shape_inference/include/convolution_backprop_shape_inference_util.hpp index 71447fe56a8..eaa8b86748a 100644 --- a/src/core/shape_inference/include/convolution_backprop_shape_inference_util.hpp +++ b/src/core/shape_inference/include/convolution_backprop_shape_inference_util.hpp @@ -129,7 +129,7 @@ void apply_padding(const util::ConvolutionBackPropBase* op, const auto& filters_shape = input_shapes[1]; // apply padding if required - if (input_shapes.size() == 3 && convolution::is_auto_pad(op) && data_shape.rank().is_static() && + if (input_shapes.size() >= 3 && convolution::is_auto_pad(op) && data_shape.rank().is_static() && filters_shape.rank().is_static()) { convolution::apply_auto_pad(op, data_shape, diff --git a/src/core/shape_inference/include/group_convolution_backprop_shape_inference.hpp b/src/core/shape_inference/include/group_convolution_backprop_shape_inference.hpp index 1f4673b95de..d0c4844c0cf 100644 --- a/src/core/shape_inference/include/group_convolution_backprop_shape_inference.hpp +++ b/src/core/shape_inference/include/group_convolution_backprop_shape_inference.hpp @@ -29,8 +29,8 @@ std::vector shape_infer(const GroupConvolutionBackpropData* op, CoordinateDiff& pads_end, const std::map& constant_data = {}) { const auto inputs_count = input_shapes.size(); - const auto has_spatial_shape = inputs_count == 3; - NODE_VALIDATION_CHECK(op, inputs_count == 2 || has_spatial_shape); + const auto has_spatial_shape = inputs_count >= 3; + NODE_VALIDATION_CHECK(op, inputs_count >= 2); using namespace ov::util; TShape out_spatial_shape; diff --git a/src/core/shape_inference/include/group_convolution_shape_inference.hpp b/src/core/shape_inference/include/group_convolution_shape_inference.hpp index ea91dc117a7..f8f5bfe690d 100644 --- a/src/core/shape_inference/include/group_convolution_shape_inference.hpp +++ b/src/core/shape_inference/include/group_convolution_shape_inference.hpp @@ -28,7 +28,7 @@ std::vector shape_infer(const GroupConvolution* op, CoordinateDiff& pads_begin, CoordinateDiff& pads_end, const std::map& constant_data = {}) { - NODE_VALIDATION_CHECK(op, input_shapes.size() == 2); + NODE_VALIDATION_CHECK(op, input_shapes.size() >= 2); using namespace ov::util; const auto num_spatial = convolution::calculate_num_spatial(op, input_shapes); diff --git a/src/plugins/intel_cpu/tests/unit/shape_inference_test/binary_convolution_shape_inference_test.cpp b/src/plugins/intel_cpu/tests/unit/shape_inference_test/binary_convolution_shape_inference_test.cpp index 5eaf1b72413..2ddf4b1e2df 100644 --- a/src/plugins/intel_cpu/tests/unit/shape_inference_test/binary_convolution_shape_inference_test.cpp +++ b/src/plugins/intel_cpu/tests/unit/shape_inference_test/binary_convolution_shape_inference_test.cpp @@ -40,6 +40,25 @@ TEST_F(BinaryConvolutionV1StaticShapeInferenceTest, default_ctor) { EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); } +TEST_F(BinaryConvolutionV1StaticShapeInferenceTest, default_ctor_three_input_shapes) { + op = make_op(); + op->set_strides({1, 1}); + op->set_dilations({1, 1}); + op->set_pads_begin({2, 2}); + op->set_pads_end({2, 1}); + op->set_auto_pad(op::PadType::VALID); + + // Third input shape (bias) can be provided, but is not used + input_shapes = ShapeVector{{1, 3, 10, 12}, {2, 3, 5, 5}, {2}}; + auto shape_infer = make_shape_inference(op); + output_shapes = shape_infer->infer(input_shapes, {}).shapes; + + EXPECT_EQ(output_shapes.size(), 1); + EXPECT_EQ(output_shapes.front(), StaticShape({1, 2, 6, 8})); + EXPECT_EQ(shape_infer->get_pads_begin(), CoordinateDiff({0, 0})); + EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); +} + TEST_F(BinaryConvolutionV1StaticShapeInferenceTest, auto_pads_same_lower_inputs_dynamic_rank) { const auto strides = Strides{1, 1}; const auto dilations = Strides{1, 1}; diff --git a/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_backprop_shape_inference_test.cpp b/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_backprop_shape_inference_test.cpp index 26976943bf7..89bbf468d41 100644 --- a/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_backprop_shape_inference_test.cpp +++ b/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_backprop_shape_inference_test.cpp @@ -84,6 +84,28 @@ TEST_F(ConvolutionBackpropDataV1StaticShapeInferenceTest, default_ctor) { EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); } +TEST_F(ConvolutionBackpropDataV1StaticShapeInferenceTest, default_ctor_more_inputs) { + const auto spatial_shape = PartialShape{500, 500}; + + op = make_op(); + op->set_strides({2, 2}); + op->set_dilations({1, 1}); + op->set_pads_begin({1, 1}); + op->set_pads_end({1, 1}); + op->set_output_padding({0, 0}); + op->set_auto_pad(op::PadType::EXPLICIT); + op->set_output_shape(spatial_shape.to_shape()); + + input_shapes = ShapeVector{{1, 20, 224, 224}, {20, 10, 3, 3}, {spatial_shape.size()}, {0}}; + auto shape_infer = make_shape_inference(op); + output_shapes = shape_infer->infer(input_shapes, {}).shapes; + + EXPECT_EQ(output_shapes.size(), 1); + EXPECT_EQ(output_shapes.front(), StaticShape({1, 10, 500, 500})); + EXPECT_EQ(shape_infer->get_pads_begin(), CoordinateDiff({1, 1})); + EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({1, 1})); +} + TEST_F(ConvolutionBackpropDataV1StaticShapeInferenceTest, 2d_inputs_dynamic_rank_no_spatial_shape) { const auto strides = Strides{1, 1}; const auto dilations = Strides{1, 1}; diff --git a/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_shape_inference_test.cpp b/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_shape_inference_test.cpp index 52a43290738..d95d9679f5d 100644 --- a/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_shape_inference_test.cpp +++ b/src/plugins/intel_cpu/tests/unit/shape_inference_test/convolution_shape_inference_test.cpp @@ -37,6 +37,25 @@ TEST_F(ConvolutionV1StaticShapeInferenceTest, default_ctor) { EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); } +TEST_F(ConvolutionV1StaticShapeInferenceTest, default_ctor_three_input_shapes) { + op = make_op(); + op->set_strides({1, 1}); + op->set_dilations({1, 1}); + op->set_pads_begin({2, 2}); + op->set_pads_end({2, 1}); + op->set_auto_pad(op::PadType::VALID); + + // Third input shape (bias) can be provided, but is not used + input_shapes = ShapeVector{{1, 3, 10, 12}, {2, 3, 5, 5}, {2}}; + auto shape_infer = make_shape_inference(op); + output_shapes = shape_infer->infer(input_shapes, {}).shapes; + + EXPECT_EQ(output_shapes.size(), 1); + EXPECT_EQ(output_shapes.front(), StaticShape({1, 2, 6, 8})); + EXPECT_EQ(shape_infer->get_pads_begin(), CoordinateDiff({0, 0})); + EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); +} + TEST_F(ConvolutionV1StaticShapeInferenceTest, 2d_auto_pads_same_lower_inputs_dynamic_rank) { const auto strides = Strides{1, 1}; const auto dilations = Strides{1, 1}; diff --git a/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_backprop_shape_inference_test.cpp b/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_backprop_shape_inference_test.cpp index a58e20c257d..fa3318ed892 100644 --- a/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_backprop_shape_inference_test.cpp +++ b/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_backprop_shape_inference_test.cpp @@ -65,6 +65,30 @@ TEST_F(GroupConvolutionBackpropDataStaticShapeInferenceTest, default_ctor) { EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({2, 1, 3})); } +TEST_F(GroupConvolutionBackpropDataStaticShapeInferenceTest, default_ctor_more_inputs) { + op = make_op(); + op->set_strides({1, 1, 1}); + op->set_dilations({1, 1, 1}); + op->set_pads_begin({2, 2, 2}); + op->set_pads_end({2, 1, 3}); + op->set_output_padding({1, 1, 1}); + op->set_auto_pad(op::PadType::EXPLICIT); + + int32_t spatial_shape[] = {5, 10, 15}; + const auto const_data = + std::map{{2, std::make_shared(element::i32, Shape{3}, spatial_shape)}}; + + // More than three inputs can be provided, but not used + input_shapes = ShapeVector{{1, 6, 10, 12, 2}, {3, 2, 2, 5, 5, 5}, {3}, {0}}; + auto shape_infer = make_shape_inference(op); + output_shapes = shape_infer->infer(input_shapes, const_data).shapes; + + EXPECT_EQ(output_shapes.size(), 1); + EXPECT_EQ(output_shapes.front(), StaticShape({1, 6, 5, 10, 15})); + EXPECT_EQ(shape_infer->get_pads_begin(), CoordinateDiff({2, 2, 2})); + EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({2, 1, 3})); +} + TEST_F(GroupConvolutionBackpropDataStaticShapeInferenceTest, 2d_inputs_dynamic_rank_no_spatial_shape) { const auto strides = Strides{1, 1}; const auto dilations = Strides{1, 1}; diff --git a/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_shape_inference_test.cpp b/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_shape_inference_test.cpp index 77b5b4f3e70..a2b90a691e3 100644 --- a/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_shape_inference_test.cpp +++ b/src/plugins/intel_cpu/tests/unit/shape_inference_test/group_convolution_shape_inference_test.cpp @@ -56,6 +56,25 @@ TEST_F(GroupConvolutionV1StaticShapeInferenceTest, default_ctor) { EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({2, 1})); } +TEST_F(GroupConvolutionV1StaticShapeInferenceTest, default_ctor_three_input_shapes) { + op = make_op(); + op->set_strides({1, 1}); + op->set_dilations({1, 1}); + op->set_pads_begin({2, 2}); + op->set_pads_end({2, 1}); + op->set_auto_pad(op::PadType::EXPLICIT); + + // Third input shape (bias) can be provided, but is not used + input_shapes = ShapeVector{{1, 6, 10, 12}, {3, 2, 2, 5, 5}, {3}}; + auto shape_infer = make_shape_inference(op); + output_shapes = shape_infer->infer(input_shapes, {}).shapes; + + EXPECT_EQ(output_shapes.size(), 1); + EXPECT_EQ(output_shapes.front(), StaticShape({1, 6, 10, 11})); + EXPECT_EQ(shape_infer->get_pads_begin(), CoordinateDiff({2, 2})); + EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({2, 1})); +} + TEST_F(GroupConvolutionV1StaticShapeInferenceTest, 1d_explicit_pads_inputs_static_rank) { const auto strides = Strides{1}; const auto dilations = Strides{1};