diff --git a/src/common/transformations/include/transformations/op_conversions/convert_pad12_downgrade.hpp b/src/common/transformations/include/transformations/op_conversions/convert_pad12_downgrade.hpp new file mode 100644 index 00000000000000..e00626a4b71484 --- /dev/null +++ b/src/common/transformations/include/transformations/op_conversions/convert_pad12_downgrade.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +namespace ov { +namespace pass { +/** + * @ingroup ie_transformation_common_api + * @brief Converts Pad v12 to Pad v1 + */ +class TRANSFORMATIONS_API ConvertPad12ToPad1 : public MatcherPass { +public: + OPENVINO_RTTI("ConvertPad12ToPad1", "0"); + ConvertPad12ToPad1(); +}; + +} // namespace pass +} // namespace ov diff --git a/src/common/transformations/src/transformations/common_optimizations/common_optimizations.cpp b/src/common/transformations/src/transformations/common_optimizations/common_optimizations.cpp index 941427fa40480c..a9e5d971b944b7 100644 --- a/src/common/transformations/src/transformations/common_optimizations/common_optimizations.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/common_optimizations.cpp @@ -83,6 +83,7 @@ #include "transformations/op_conversions/convert_minimum_to_power_and_max.hpp" #include "transformations/op_conversions/convert_mod.hpp" #include "transformations/op_conversions/convert_multiclass_nms_upgrade.hpp" +#include "transformations/op_conversions/convert_pad12_downgrade.hpp" #include "transformations/op_conversions/convert_pad_to_group_conv.hpp" #include "transformations/op_conversions/convert_prior_box_v8_to_v0.hpp" #include "transformations/op_conversions/convert_reduce_to_pooling.hpp" @@ -213,6 +214,7 @@ bool ov::pass::CommonOptimizations::run_on_model(const std::shared_ptr(); ADD_MATCHER(fq_fusions, FakeQuantizeMulFusion) diff --git a/src/common/transformations/src/transformations/op_conversions/convert_pad12_downgrade.cpp b/src/common/transformations/src/transformations/op_conversions/convert_pad12_downgrade.cpp new file mode 100644 index 00000000000000..b37c247be42e41 --- /dev/null +++ b/src/common/transformations/src/transformations/op_conversions/convert_pad12_downgrade.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/op_conversions/convert_pad12_downgrade.hpp" + +#include +#include +#include + +#include "itt.hpp" + +ov::pass::ConvertPad12ToPad1::ConvertPad12ToPad1() { + MATCHER_SCOPE(ConvertPad12ToPad1); + + const auto pad_v12_pattern = pattern::wrap_type(); + + const matcher_pass_callback callback = [=](pattern::Matcher& m) { + const auto pad_v12 = std::dynamic_pointer_cast(m.get_match_root()); + if (!pad_v12 || transformation_callback(pad_v12)) { + return false; + } + + std::shared_ptr pad_v1; + if (pad_v12->get_input_size() == 4) { + pad_v1 = std::make_shared(pad_v12->input_value(0), + pad_v12->input_value(1), + pad_v12->input_value(2), + pad_v12->input_value(3), + pad_v12->get_pad_mode()); + } else { + const auto pad_value = + ov::op::v0::Constant::create(pad_v12->input_value(0).get_element_type(), ov::Shape{}, {0}); + + pad_v1 = std::make_shared(pad_v12->input_value(0), + pad_v12->input_value(1), + pad_v12->input_value(2), + pad_value, + pad_v12->get_pad_mode()); + } + pad_v1->set_friendly_name(pad_v12->get_friendly_name()); + copy_runtime_info(pad_v12, pad_v1); + replace_node(pad_v12, pad_v1); + + return true; + }; + + auto m = std::make_shared(pad_v12_pattern, matcher_name); + register_matcher(m, callback); +} diff --git a/src/common/transformations/tests/op_conversions/convert_pad12_downgrade_test.cpp b/src/common/transformations/tests/op_conversions/convert_pad12_downgrade_test.cpp new file mode 100644 index 00000000000000..813f3cf2ca6e7d --- /dev/null +++ b/src/common/transformations/tests/op_conversions/convert_pad12_downgrade_test.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" + +using namespace testing; + +namespace { +std::shared_ptr create_v12_model(const ov::op::PadMode pad_mode, const int16_t pad_v = -1) { + const auto input = std::make_shared(ov::element::i16, ov::Shape{1, 3, 100, 100}); + const auto pads_begin = + std::make_shared(ov::element::i64, ov::Shape{4}, std::vector{0, 2, 1, 0}); + const auto pads_end = + std::make_shared(ov::element::i64, ov::Shape{4}, std::vector{0, 1, 1, 0}); + + std::shared_ptr pad; + if (pad_v != -1) { + const auto pad_value = + std::make_shared(ov::element::i16, ov::Shape{}, std::vector{pad_v}); + pad = std::make_shared(input, pads_begin, pads_end, pad_value, pad_mode); + } else { + pad = std::make_shared(input, pads_begin, pads_end, pad_mode); + } + pad->set_friendly_name("pad12"); + + return std::make_shared(pad->outputs(), ov::ParameterVector{input}); +} + +std::shared_ptr create_v1_model(const ov::op::PadMode pad_mode, const int16_t pad_v) { + const auto input = std::make_shared(ov::element::i16, ov::Shape{1, 3, 100, 100}); + const auto pads_begin = + std::make_shared(ov::element::i64, ov::Shape{4}, std::vector{0, 2, 1, 0}); + const auto pads_end = + std::make_shared(ov::element::i64, ov::Shape{4}, std::vector{0, 1, 1, 0}); + const auto pad_value = + std::make_shared(ov::element::i16, ov::Shape{}, std::vector{pad_v}); + + const auto pad = std::make_shared(input, pads_begin, pads_end, pad_value, pad_mode); + pad->set_friendly_name("pad1"); + + return std::make_shared(pad->outputs(), ov::ParameterVector{input}); +} + +} // namespace + +TEST_F(TransformationTestsF, ConvertPad12ToPad1) { + manager.register_pass(); + function = create_v12_model(ov::op::PadMode::CONSTANT); + function_ref = create_v1_model(ov::op::PadMode::CONSTANT, 0); + comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES); + comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES); +} + +TEST_F(TransformationTestsF, ConvertPad12ToPad1_explicit_pad_value) { + manager.register_pass(); + function = create_v12_model(ov::op::PadMode::CONSTANT, 5); + function_ref = create_v1_model(ov::op::PadMode::CONSTANT, 5); + comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES); + comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES); +} + +TEST_F(TransformationTestsF, ConvertPad12ToPad1_symmetric) { + manager.register_pass(); + function = create_v12_model(ov::op::PadMode::SYMMETRIC); + function_ref = create_v1_model(ov::op::PadMode::SYMMETRIC, 0); + comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES); + comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES); +} + +TEST_F(TransformationTestsF, ConvertPad12ToPad1_symmetric_explicit_pad_value) { + manager.register_pass(); + function = create_v12_model(ov::op::PadMode::SYMMETRIC, 5); + function_ref = create_v1_model(ov::op::PadMode::SYMMETRIC, 5); + comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES); + comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES); +}