[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
This commit is contained in:
Katarzyna Mitrus 2023-04-06 12:59:37 +02:00 committed by GitHub
parent 932a668a2f
commit 7a5c472ccc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 109 additions and 6 deletions

View File

@ -18,8 +18,8 @@ std::vector<TShape> shape_infer(const ConvolutionBackpropData* op,
CoordinateDiff& pads_end, CoordinateDiff& pads_end,
const std::map<size_t, HostTensorPtr>& constant_data = {}) { const std::map<size_t, HostTensorPtr>& constant_data = {}) {
const auto inputs_count = input_shapes.size(); const auto inputs_count = input_shapes.size();
const auto has_spatial_shape = inputs_count == 3; const auto has_spatial_shape = inputs_count >= 3;
NODE_VALIDATION_CHECK(op, inputs_count == 2 || has_spatial_shape); NODE_VALIDATION_CHECK(op, inputs_count >= 2);
using namespace ov::util; using namespace ov::util;
TShape out_spatial_shape; TShape out_spatial_shape;

View File

@ -129,7 +129,7 @@ void apply_padding(const util::ConvolutionBackPropBase* op,
const auto& filters_shape = input_shapes[1]; const auto& filters_shape = input_shapes[1];
// apply padding if required // 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()) { filters_shape.rank().is_static()) {
convolution::apply_auto_pad(op, convolution::apply_auto_pad(op,
data_shape, data_shape,

View File

@ -29,8 +29,8 @@ std::vector<TShape> shape_infer(const GroupConvolutionBackpropData* op,
CoordinateDiff& pads_end, CoordinateDiff& pads_end,
const std::map<size_t, HostTensorPtr>& constant_data = {}) { const std::map<size_t, HostTensorPtr>& constant_data = {}) {
const auto inputs_count = input_shapes.size(); const auto inputs_count = input_shapes.size();
const auto has_spatial_shape = inputs_count == 3; const auto has_spatial_shape = inputs_count >= 3;
NODE_VALIDATION_CHECK(op, inputs_count == 2 || has_spatial_shape); NODE_VALIDATION_CHECK(op, inputs_count >= 2);
using namespace ov::util; using namespace ov::util;
TShape out_spatial_shape; TShape out_spatial_shape;

View File

@ -28,7 +28,7 @@ std::vector<TShape> shape_infer(const GroupConvolution* op,
CoordinateDiff& pads_begin, CoordinateDiff& pads_begin,
CoordinateDiff& pads_end, CoordinateDiff& pads_end,
const std::map<size_t, HostTensorPtr>& constant_data = {}) { const std::map<size_t, HostTensorPtr>& constant_data = {}) {
NODE_VALIDATION_CHECK(op, input_shapes.size() == 2); NODE_VALIDATION_CHECK(op, input_shapes.size() >= 2);
using namespace ov::util; using namespace ov::util;
const auto num_spatial = convolution::calculate_num_spatial(op, input_shapes); const auto num_spatial = convolution::calculate_num_spatial(op, input_shapes);

View File

@ -40,6 +40,25 @@ TEST_F(BinaryConvolutionV1StaticShapeInferenceTest, default_ctor) {
EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); 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) { TEST_F(BinaryConvolutionV1StaticShapeInferenceTest, auto_pads_same_lower_inputs_dynamic_rank) {
const auto strides = Strides{1, 1}; const auto strides = Strides{1, 1};
const auto dilations = Strides{1, 1}; const auto dilations = Strides{1, 1};

View File

@ -84,6 +84,28 @@ TEST_F(ConvolutionBackpropDataV1StaticShapeInferenceTest, default_ctor) {
EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); 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) { TEST_F(ConvolutionBackpropDataV1StaticShapeInferenceTest, 2d_inputs_dynamic_rank_no_spatial_shape) {
const auto strides = Strides{1, 1}; const auto strides = Strides{1, 1};
const auto dilations = Strides{1, 1}; const auto dilations = Strides{1, 1};

View File

@ -37,6 +37,25 @@ TEST_F(ConvolutionV1StaticShapeInferenceTest, default_ctor) {
EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({0, 0})); 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) { TEST_F(ConvolutionV1StaticShapeInferenceTest, 2d_auto_pads_same_lower_inputs_dynamic_rank) {
const auto strides = Strides{1, 1}; const auto strides = Strides{1, 1};
const auto dilations = Strides{1, 1}; const auto dilations = Strides{1, 1};

View File

@ -65,6 +65,30 @@ TEST_F(GroupConvolutionBackpropDataStaticShapeInferenceTest, default_ctor) {
EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({2, 1, 3})); 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<size_t, HostTensorPtr>{{2, std::make_shared<HostTensor>(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) { TEST_F(GroupConvolutionBackpropDataStaticShapeInferenceTest, 2d_inputs_dynamic_rank_no_spatial_shape) {
const auto strides = Strides{1, 1}; const auto strides = Strides{1, 1};
const auto dilations = Strides{1, 1}; const auto dilations = Strides{1, 1};

View File

@ -56,6 +56,25 @@ TEST_F(GroupConvolutionV1StaticShapeInferenceTest, default_ctor) {
EXPECT_EQ(shape_infer->get_pads_end(), CoordinateDiff({2, 1})); 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) { TEST_F(GroupConvolutionV1StaticShapeInferenceTest, 1d_explicit_pads_inputs_static_rank) {
const auto strides = Strides{1}; const auto strides = Strides{1};
const auto dilations = Strides{1}; const auto dilations = Strides{1};