Skip to content
Merged
  •  
  •  
  •  

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
#include "openvino/pass/pattern/op/wrap_type.hpp"
#include "transformations/utils/utils.hpp"

using namespace ov::op;
namespace ov::pass {

ov::pass::AdaptivePoolToReduce::AdaptivePoolToReduce() {
namespace v0 = ov::op::v0;
namespace v1 = ov::op::v1;
namespace v8 = ov::op::v8;

AdaptivePoolToReduce::AdaptivePoolToReduce() {
MATCHER_SCOPE(AdaptivePoolToReduce);
auto data_pattern = pattern::any_input();
auto out_spatial_shape = pattern::wrap_type<v0::Constant>();
Expand Down Expand Up @@ -58,6 +62,8 @@ ov::pass::AdaptivePoolToReduce::AdaptivePoolToReduce() {
return true;
};

auto m = std::make_shared<ov::pass::pattern::Matcher>(a_pool, matcher_name);
auto m = std::make_shared<pattern::Matcher>(a_pool, matcher_name);
this->register_matcher(m, callback);
}

} // namespace ov::pass
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,35 @@
#include "openvino/pass/pattern/op/wrap_type.hpp"
#include "transformations/utils/utils.hpp"

ov::pass::AddFakeQuantizeFusion::AddFakeQuantizeFusion() {
namespace v0 = ov::op::v0;
namespace v1 = ov::op::v1;
namespace op_util = ov::op::util;

namespace ov::pass {

AddFakeQuantizeFusion::AddFakeQuantizeFusion() {
MATCHER_SCOPE(AddFakeQuantizeFusion);
auto input_pattern = pass::pattern::any_input();
auto const_pattern = ov::pass::pattern::wrap_type<ov::op::v0::Constant>();
auto add_pattern =
ov::pass::pattern::wrap_type<ov::op::v1::Add>({input_pattern, const_pattern}, pattern::consumers_count(1));
auto fq_pattern = ov::pass::pattern::wrap_type<ov::op::v0::FakeQuantize>({add_pattern,
pass::pattern::any_input(),
pass::pattern::any_input(),
pass::pattern::any_input(),
pass::pattern::any_input()});
auto input_pattern = pattern::any_input();
auto const_pattern = pattern::wrap_type<v0::Constant>();
auto add_pattern = pattern::wrap_type<v1::Add>({input_pattern, const_pattern}, pattern::consumers_count(1));
auto fq_pattern = pattern::wrap_type<v0::FakeQuantize>(
{add_pattern, pattern::any_input(), pattern::any_input(), pattern::any_input(), pattern::any_input()});
matcher_pass_callback callback = [OV_CAPTURE_CPY_AND_THIS](pattern::Matcher& m) {
const auto& pattern_value_map = m.get_pattern_value_map();
const auto& input = pattern_value_map.at(input_pattern);
const auto& type = input.get_element_type();
if (type.bitwidth() < element::f32.bitwidth())
return false;
auto fq = ov::as_type_ptr<ov::op::v0::FakeQuantize>(pattern_value_map.at(fq_pattern).get_node_shared_ptr());
auto fq = ov::as_type_ptr<v0::FakeQuantize>(pattern_value_map.at(fq_pattern).get_node_shared_ptr());
if (!fq)
return false;
const auto& add_node = pattern_value_map.at(add_pattern).get_node_shared_ptr();
auto add_const =
ov::as_type_ptr<ov::op::v0::Constant>(pattern_value_map.at(const_pattern).get_node_shared_ptr());
auto add_const = ov::as_type_ptr<v0::Constant>(pattern_value_map.at(const_pattern).get_node_shared_ptr());
if (!add_const)
return false;

auto const_shape = add_const->get_shape();
if (!ov::op::util::check_for_broadcast(input.get_partial_shape(), const_shape)) {
if (!op_util::check_for_broadcast(input.get_partial_shape(), const_shape)) {
// We can't eliminate Add if Constant input broadcasts another input shape because
// when we reconnect input from Add to FQ won't broadcast given input, so it will result
// in shape collision.
Expand All @@ -63,9 +64,9 @@ ov::pass::AddFakeQuantizeFusion::AddFakeQuantizeFusion() {

if (!is_single_value) {
float v;
is_single_value = ov::op::util::get_single_value(add_const, v);
is_single_value = op_util::get_single_value(add_const, v);
if (is_single_value) {
new_const = std::make_shared<ov::op::v0::Constant>(add_const->get_element_type(), Shape{1}, v);
new_const = std::make_shared<v0::Constant>(add_const->get_element_type(), Shape{1}, v);
}
}

Expand All @@ -78,9 +79,9 @@ ov::pass::AddFakeQuantizeFusion::AddFakeQuantizeFusion() {
if (diff > 0) {
// Reshape constants like (C, 1, 1) to (1, C, 1, 1)
const_shape.insert(const_shape.begin(), diff, 1);
new_const = std::make_shared<ov::op::v1::Reshape>(
new_const = std::make_shared<v1::Reshape>(
new_const,
ov::op::v0::Constant::create(element::u64, Shape{const_shape.size()}, const_shape),
v0::Constant::create(element::u64, Shape{const_shape.size()}, const_shape),
false);
}

Expand All @@ -96,29 +97,27 @@ ov::pass::AddFakeQuantizeFusion::AddFakeQuantizeFusion() {
bool add_parent_is_conv_or_mm =
std::any_of(add_inputs.begin(), add_inputs.end(), [](const Output<Node>& node) -> bool {
auto node_ptr = node.get_node();
return is_type<ov::op::v1::Convolution>(node_ptr) ||
is_type<ov::op::v1::GroupConvolution>(node_ptr) ||
is_type<ov::op::v1::ConvolutionBackpropData>(node_ptr) ||
is_type<ov::op::v1::GroupConvolutionBackpropData>(node_ptr) ||
is_type<ov::op::v0::MatMul>(node_ptr);
return is_type<v1::Convolution>(node_ptr) || is_type<v1::GroupConvolution>(node_ptr) ||
is_type<v1::ConvolutionBackpropData>(node_ptr) ||
is_type<v1::GroupConvolutionBackpropData>(node_ptr) || is_type<v0::MatMul>(node_ptr);
});
if (add_parent_is_conv_or_mm)
return false;
auto fq_users = fq->get_users();
// Concat LPT transformation supports per tensor quantization only
bool fq_user_is_concat =
std::any_of(fq_users.begin(), fq_users.end(), [](const std::shared_ptr<Node> node_ptr) -> bool {
return is_type<ov::op::v0::Concat>(node_ptr);
return is_type<v0::Concat>(node_ptr);
});
if (fq_user_is_concat)
return false;
}

auto input_low_sub = std::make_shared<ov::op::v1::Subtract>(fq->input_value(1), new_const);
auto input_low_sub = std::make_shared<v1::Subtract>(fq->input_value(1), new_const);
std::shared_ptr<Node> new_input_low = ov::util::get_constant_from_source(input_low_sub);
if (!new_input_low)
new_input_low = input_low_sub;
auto input_high_sub = std::make_shared<ov::op::v1::Subtract>(fq->input_value(2), new_const);
auto input_high_sub = std::make_shared<v1::Subtract>(fq->input_value(2), new_const);
std::shared_ptr<Node> new_input_high = ov::util::get_constant_from_source(input_high_sub);
if (!new_input_high)
new_input_high = input_high_sub;
Expand All @@ -133,6 +132,8 @@ ov::pass::AddFakeQuantizeFusion::AddFakeQuantizeFusion() {
return true;
};

auto m = std::make_shared<ov::pass::pattern::Matcher>(fq_pattern, matcher_name);
auto m = std::make_shared<pattern::Matcher>(fq_pattern, matcher_name);
this->register_matcher(m, callback);
}

} // namespace ov::pass
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,22 @@
#include "openvino/op/util/binary_elementwise_logical.hpp"
#include "openvino/pass/pattern/op/wrap_type.hpp"

ov::pass::AlignEltwiseInputRanks::AlignEltwiseInputRanks() {
auto eltwise_pattern = pattern::wrap_type<ov::op::v0::SquaredDifference,
ov::op::util::BinaryElementwiseComparison,
ov::op::util::BinaryElementwiseLogical,
ov::op::util::BinaryElementwiseArithmetic,
ov::op::v0::FakeQuantize>(pattern::has_static_rank());
namespace ov::pass {

namespace v0 = ov::op::v0;
namespace op_util = ov::op::util;

AlignEltwiseInputRanks::AlignEltwiseInputRanks() {
auto eltwise_pattern = pattern::wrap_type<v0::SquaredDifference,
op_util::BinaryElementwiseComparison,
op_util::BinaryElementwiseLogical,
op_util::BinaryElementwiseArithmetic,
v0::FakeQuantize>(pattern::has_static_rank());

matcher_pass_callback callback = [=](pattern::Matcher& m) {
auto node = m.get_match_root();

auto fq = as_type<ov::op::v0::FakeQuantize>(node.get());
auto fq = as_type<v0::FakeQuantize>(node.get());
if (fq) {
if (fq->get_auto_broadcast() != ov::op::AutoBroadcastType::NUMPY) {
return false;
Expand All @@ -40,23 +45,23 @@ ov::pass::AlignEltwiseInputRanks::AlignEltwiseInputRanks() {
if (ov::is_type<ov::op::v1::Multiply>(node)) {
auto inputs = node->input_values();
if (std::any_of(inputs.begin(), inputs.end(), [](const Output<Node>& input) -> bool {
return ov::is_type<ov::op::v0::NormalizeL2>(input.get_node());
return ov::is_type<v0::NormalizeL2>(input.get_node());
}))
return false;
}

const auto rank = static_cast<int64_t>(node->get_output_partial_shape(0).size());

for (size_t i = 0; i < node->get_input_size(); i++) {
auto const_node = as_type<ov::op::v0::Constant>(node->get_input_node_ptr(i));
auto const_node = as_type<v0::Constant>(node->get_input_node_ptr(i));
if (const_node == nullptr)
continue;
const auto& const_shape = const_node->get_shape();
auto diff = rank - static_cast<int64_t>(const_shape.size());
if (diff > 0) {
Shape new_shape = const_shape;
new_shape.insert(new_shape.begin(), diff, 1);
auto new_const = std::make_shared<ov::op::v0::Constant>(*const_node, new_shape);
auto new_const = std::make_shared<v0::Constant>(*const_node, new_shape);
copy_runtime_info(node->get_input_node_shared_ptr(i), new_const);
node->input(i).replace_source_output(new_const);
}
Expand All @@ -68,3 +73,5 @@ ov::pass::AlignEltwiseInputRanks::AlignEltwiseInputRanks() {
auto m = std::make_shared<pattern::Matcher>(eltwise_pattern, "AlignEltwiseInputRanks");
this->register_matcher(m, callback);
}

} // namespace ov::pass
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
#include "openvino/pass/pattern/op/wrap_type.hpp"
#include "ov_ops/augru_cell.hpp"

using namespace std;
using namespace ov::element;
using namespace ov::pass::pattern;
namespace ov::pass {

namespace v0 = ov::op::v0;
namespace v1 = ov::op::v1;

namespace {

// The 1st input to the Add op is automatically broadcasted
// from 1d to 2d tensor, but to be compatible with what
Expand All @@ -37,8 +40,7 @@ static std::shared_ptr<ov::Node> get_bias_add(const std::shared_ptr<ov::Node>& b
auto input_source_1_ps = bias_add->input_value(1).get_partial_shape();
if (input_source_1_ps.is_static() && input_source_1_ps.rank().get_length() == 1) {
auto unsqueeze =
rg.make<ov::op::v0::Unsqueeze>(bias_add->input_value(1),
ov::op::v0::Constant::create(ov::element::i32, ov::Shape{}, {0}));
rg.make<v0::Unsqueeze>(bias_add->input_value(1), v0::Constant::create(ov::element::i32, ov::Shape{}, {0}));
bias_add->input(1).replace_source_output(unsqueeze);
}

Expand All @@ -54,19 +56,20 @@ static std::shared_ptr<ov::Node> get_bias_add(const std::shared_ptr<ov::Node>& b
// compatible with the code of the transformation.
static std::shared_ptr<ov::Node> get_weights_matmul(const std::shared_ptr<ov::Node>& mat_mul,
ov::pass::NodeRegistry& rg) {
if (auto matmul = ov::as_type_ptr<ov::op::v0::MatMul>(mat_mul)) {
if (auto matmul = ov::as_type_ptr<v0::MatMul>(mat_mul)) {
if (!matmul->get_transpose_b()) {
auto transpose =
rg.make<ov::op::v1::Transpose>(matmul->input_value(1),
ov::op::v0::Constant::create(ov::element::i32, ov::Shape{2}, {1, 0}));
auto transpose = rg.make<v1::Transpose>(matmul->input_value(1),
v0::Constant::create(ov::element::i32, ov::Shape{2}, {1, 0}));
matmul->input(1).replace_source_output(transpose);
}
}

return mat_mul;
}

ov::pass::AUGRUCellFusion::AUGRUCellFusion() {
} // namespace

AUGRUCellFusion::AUGRUCellFusion() {
MATCHER_SCOPE(AUGRUCellFusion);

// we can't determine hidden_size or input_size in this case
Expand All @@ -75,27 +78,28 @@ ov::pass::AUGRUCellFusion::AUGRUCellFusion() {
return !(p_shape.rank().is_dynamic() || p_shape[1].is_dynamic());
};

auto concat_1 = wrap_type<ov::op::v0::Concat>({any_input(is_first_dim_static), any_input(is_first_dim_static)});
auto matmul_1 = wrap_type<ov::op::v0::MatMul>({concat_1, any_input(is_first_dim_static)});
auto add_1 = wrap_type<ov::op::v1::Add>({matmul_1, any_input()});
auto concat_1 = pattern::wrap_type<v0::Concat>(
{pattern::any_input(is_first_dim_static), pattern::any_input(is_first_dim_static)});
auto matmul_1 = pattern::wrap_type<v0::MatMul>({concat_1, pattern::any_input(is_first_dim_static)});
auto add_1 = pattern::wrap_type<v1::Add>({matmul_1, pattern::any_input()});
// only Sigmoid is supported in the current version of AUGRUCell
auto sigmoid = wrap_type<ov::op::v0::Sigmoid>({add_1});
auto split = wrap_type<ov::op::v1::Split>({sigmoid, any_input()});
auto multiply = wrap_type<ov::op::v1::Multiply>({split, any_input()});
auto sigmoid = pattern::wrap_type<v0::Sigmoid>({add_1});
auto split = pattern::wrap_type<v1::Split>({sigmoid, pattern::any_input()});
auto multiply = pattern::wrap_type<v1::Multiply>({split, pattern::any_input()});

auto concat_2 = wrap_type<ov::op::v0::Concat>({any_input(), multiply});
auto matmul_2 = wrap_type<ov::op::v0::MatMul>({concat_2, any_input(is_first_dim_static)});
auto add_2 = wrap_type<ov::op::v1::Add>({matmul_2, any_input()});
auto concat_2 = pattern::wrap_type<v0::Concat>({pattern::any_input(), multiply});
auto matmul_2 = pattern::wrap_type<v0::MatMul>({concat_2, pattern::any_input(is_first_dim_static)});
auto add_2 = pattern::wrap_type<v1::Add>({matmul_2, pattern::any_input()});
// only Tanh is supported in the current version of AUGRUCell
auto tanh = wrap_type<ov::op::v0::Tanh>({add_2});
auto tanh = pattern::wrap_type<v0::Tanh>({add_2});

auto subtract_1 = wrap_type<ov::op::v1::Subtract>({any_input(), any_input()});
auto multiply_2 = wrap_type<ov::op::v1::Multiply>({subtract_1, split});
auto subtract_2 = wrap_type<ov::op::v1::Subtract>({any_input(), multiply_2});
auto multiply_3 = wrap_type<ov::op::v1::Multiply>({subtract_2, tanh});
auto subtract_1 = pattern::wrap_type<v1::Subtract>({pattern::any_input(), pattern::any_input()});
auto multiply_2 = pattern::wrap_type<v1::Multiply>({subtract_1, split});
auto subtract_2 = pattern::wrap_type<v1::Subtract>({pattern::any_input(), multiply_2});
auto multiply_3 = pattern::wrap_type<v1::Multiply>({subtract_2, tanh});

auto multiply_4 = wrap_type<ov::op::v1::Multiply>({multiply_2, any_input()});
auto add_3 = wrap_type<ov::op::v1::Add>({multiply_4, multiply_3});
auto multiply_4 = pattern::wrap_type<v1::Multiply>({multiply_2, pattern::any_input()});
auto add_3 = pattern::wrap_type<v1::Add>({multiply_4, multiply_3});

matcher_pass_callback callback = [=](pattern::Matcher& m) {
NodeRegistry rg;
Expand All @@ -110,35 +114,34 @@ ov::pass::AUGRUCellFusion::AUGRUCellFusion() {
auto hidden_size = h_pshape[1].get_length();
auto input_size = x_pshape[1].get_length();

auto axis_0 = rg.make<ov::op::v0::Constant>(i64, Shape{}, 0);
auto axis_1 = rg.make<ov::op::v0::Constant>(i64, Shape{}, 1);
auto axis_0 = rg.make<v0::Constant>(element::i64, Shape{}, 0);
auto axis_1 = rg.make<v0::Constant>(element::i64, Shape{}, 1);

auto A = pattern_map.at(subtract_1)->input_value(1);
// biases are required
auto bias_add_1 = get_bias_add(pattern_map.at(add_1), rg);
auto split_bias_r_z = rg.make<ov::op::v1::Split>(bias_add_1->input_value(1), axis_1, 2);
auto split_bias_r_z = rg.make<v1::Split>(bias_add_1->input_value(1), axis_1, 2);
auto bias_add_2 = get_bias_add(pattern_map.at(add_2), rg);

auto B = rg.make<ov::op::v0::Concat>(
auto B = rg.make<v0::Concat>(
OutputVector{split_bias_r_z->output(1), split_bias_r_z->output(0), bias_add_2->input_value(1)},
1);

auto WRrz = get_weights_matmul(pattern_map.at(matmul_1), rg)->input_value(1);
auto WRh = get_weights_matmul(pattern_map.at(matmul_2), rg)->input_value(1);

auto split_lenghts = rg.make<ov::op::v0::Constant>(i64, Shape{2}, vector<int64_t>{input_size, hidden_size});
auto split_WRrz = rg.make<ov::op::v1::VariadicSplit>(WRrz, axis_1, split_lenghts);
auto split_W_r_z = rg.make<ov::op::v1::Split>(split_WRrz->output(0), axis_0, 2);
auto split_R_r_z = rg.make<ov::op::v1::Split>(split_WRrz->output(1), axis_0, 2);
auto split_WRh = rg.make<ov::op::v1::VariadicSplit>(WRh, axis_1, split_lenghts);
auto Wzrh = rg.make<ov::op::v0::Concat>(
OutputVector{split_W_r_z->output(1), split_W_r_z->output(0), split_WRh->output(0)},
0);
auto Rzrh = rg.make<ov::op::v0::Concat>(
OutputVector{split_R_r_z->output(1), split_R_r_z->output(0), split_WRh->output(1)},
0);

auto squeeze_B = rg.make<ov::op::v0::Squeeze>(B, axis_0);
auto split_lenghts =
rg.make<v0::Constant>(element::i64, Shape{2}, std::vector<int64_t>{input_size, hidden_size});
auto split_WRrz = rg.make<v1::VariadicSplit>(WRrz, axis_1, split_lenghts);
auto split_W_r_z = rg.make<v1::Split>(split_WRrz->output(0), axis_0, 2);
auto split_R_r_z = rg.make<v1::Split>(split_WRrz->output(1), axis_0, 2);
auto split_WRh = rg.make<v1::VariadicSplit>(WRh, axis_1, split_lenghts);
auto Wzrh =
rg.make<v0::Concat>(OutputVector{split_W_r_z->output(1), split_W_r_z->output(0), split_WRh->output(0)}, 0);
auto Rzrh =
rg.make<v0::Concat>(OutputVector{split_R_r_z->output(1), split_R_r_z->output(0), split_WRh->output(1)}, 0);

auto squeeze_B = rg.make<v0::Squeeze>(B, axis_0);
auto cell =
rg.make<ov::op::internal::AUGRUCell>(X, H, Wzrh, Rzrh, squeeze_B, A, H.get_partial_shape()[1].get_length());

Expand All @@ -148,6 +151,8 @@ ov::pass::AUGRUCellFusion::AUGRUCellFusion() {
return true;
};

auto m = make_shared<Matcher>(add_3, matcher_name);
auto m = std::make_shared<pattern::Matcher>(add_3, matcher_name);
this->register_matcher(m, callback);
}

} // namespace ov::pass
Loading
Loading