diff --git a/src/common/transformations/include/transformations/utils/utils.hpp b/src/common/transformations/include/transformations/utils/utils.hpp index 70e9b595e2bd6e..a9d2d0081bf5ac 100644 --- a/src/common/transformations/include/transformations/utils/utils.hpp +++ b/src/common/transformations/include/transformations/utils/utils.hpp @@ -280,7 +280,8 @@ TRANSFORMATIONS_API bool can_eliminate_eltwise_node(const std::shared_ptr& TRANSFORMATIONS_API bool is_constant_and_all_values_equal_int(const Output& output, const int64_t& v); -TRANSFORMATIONS_API bool is_on_constant_path(const ov::Output& output); +TRANSFORMATIONS_API bool is_on_constant_path(const ov::Output& output, + const std::unordered_set& break_node_types = {}); TRANSFORMATIONS_API bool process_subgraph(ov::pass::ModelPass& model_pass, const std::shared_ptr& node); diff --git a/src/common/transformations/src/transformations/utils/utils.cpp b/src/common/transformations/src/transformations/utils/utils.cpp index 3b24a8112133e0..f32c5adeec4785 100644 --- a/src/common/transformations/src/transformations/utils/utils.cpp +++ b/src/common/transformations/src/transformations/utils/utils.cpp @@ -489,7 +489,8 @@ bool is_constant_and_all_values_equal_int(const Output& output, const int6 return false; } -bool is_on_constant_path(const ov::Output& output) { +bool is_on_constant_path(const ov::Output& output, + const std::unordered_set& break_node_types) { auto status = true; std::deque nodes_to_calculate = {output.get_node()}; @@ -497,6 +498,14 @@ bool is_on_constant_path(const ov::Output& output) { auto current_node = nodes_to_calculate.front(); nodes_to_calculate.pop_front(); + // Check if the current node matches any type in break_node_types + if (!break_node_types.empty()) { + std::type_index current_type(typeid(*current_node)); + if (break_node_types.find(current_type) != break_node_types.end()) { + return false; + } + } + if (current_node->get_input_size() == 0 && !ov::is_type(current_node)) { status = false; } else { diff --git a/src/plugins/intel_cpu/src/transformations/cpu_opset/common/pass/convert_matmul_to_fc.cpp b/src/plugins/intel_cpu/src/transformations/cpu_opset/common/pass/convert_matmul_to_fc.cpp index e8e7eccdb4f2ca..9f3d9d3ab484fd 100644 --- a/src/plugins/intel_cpu/src/transformations/cpu_opset/common/pass/convert_matmul_to_fc.cpp +++ b/src/plugins/intel_cpu/src/transformations/cpu_opset/common/pass/convert_matmul_to_fc.cpp @@ -10,6 +10,7 @@ #include "openvino/core/type/element_type.hpp" #include "openvino/op/convert.hpp" #include "openvino/op/matmul.hpp" +#include "openvino/op/random_uniform.hpp" #include "openvino/op/transpose.hpp" #include "openvino/pass/pattern/op/wrap_type.hpp" #include "ov_ops/fully_connected.hpp" @@ -19,7 +20,7 @@ ov::intel_cpu::ConvertMatMulToFC::ConvertMatMulToFC() { MATCHER_SCOPE(ConvertMatMulToFC); auto activations_m = ov::pass::pattern::any_input(ov::pass::pattern::has_static_rank()); auto weights_path = [](const ov::Output& output) { - return ov::op::util::is_on_constant_path(output); + return ov::op::util::is_on_constant_path(output, {typeid(ov::op::v8::RandomUniform)}); }; auto weights_m = ov::pass::pattern::any_input(weights_path); auto matmul_m = ov::pass::pattern::wrap_type({activations_m, weights_m}, diff --git a/src/plugins/intel_cpu/tests/unit/transformations/convert_matmul_test.cpp b/src/plugins/intel_cpu/tests/unit/transformations/convert_matmul_test.cpp index 7d17dc0324b85f..61ad707816c9cf 100644 --- a/src/plugins/intel_cpu/tests/unit/transformations/convert_matmul_test.cpp +++ b/src/plugins/intel_cpu/tests/unit/transformations/convert_matmul_test.cpp @@ -9,6 +9,7 @@ #include "openvino/opsets/opset1_decl.hpp" #include "openvino/opsets/opset3_decl.hpp" #include "openvino/opsets/opset7_decl.hpp" +#include "openvino/opsets/opset8_decl.hpp" #include #include #include @@ -25,6 +26,7 @@ #include "openvino/op/shape_of.hpp" #include "openvino/op/subtract.hpp" #include "openvino/op/transpose.hpp" +#include "openvino/op/random_uniform.hpp" using namespace testing; using namespace ov::intel_cpu; @@ -543,3 +545,38 @@ TEST_F(TransformationTestsF, ConvertMatMulToFCTest_compressed_u8_weights) { model_ref = std::make_shared(ov::OutputVector{matmul}, ov::ParameterVector{data}); } } + +TEST_F(TransformationTestsF, ConvertMatMulToFCTest_WithRandomUniform) { + { + auto input1 = std::make_shared(ov::element::f32, ov::PartialShape{-1, -1, -1}); + + auto random_uniform_shape = ov::opset1::Constant::create(ov::element::i32, ov::Shape{2}, {2, 2}); + auto random_uniform_min = ov::opset1::Constant::create(ov::element::f32, ov::Shape{1}, {0.0}); + auto random_uniform_max = ov::opset1::Constant::create(ov::element::f32, ov::Shape{1}, {1.0}); + auto random_uniform = std::make_shared(random_uniform_shape, + random_uniform_min, + random_uniform_max, + ov::element::f32); + + auto matmul = std::make_shared(input1, random_uniform, false, false); + + model = std::make_shared(ov::OutputVector{matmul}, ov::ParameterVector{input1}); + + manager.register_pass(); + } + { + auto input1 = std::make_shared(ov::element::f32, ov::PartialShape{-1, -1, -1}); + + auto random_uniform_shape = ov::opset1::Constant::create(ov::element::i32, ov::Shape{2}, {2, 2}); + auto random_uniform_min = ov::opset1::Constant::create(ov::element::f32, ov::Shape{1}, {0.0}); + auto random_uniform_max = ov::opset1::Constant::create(ov::element::f32, ov::Shape{1}, {1.0}); + auto random_uniform = std::make_shared(random_uniform_shape, + random_uniform_min, + random_uniform_max, + ov::element::f32); + + auto matmul = std::make_shared(input1, random_uniform, false, false); + + model_ref = std::make_shared(ov::OutputVector{matmul}, ov::ParameterVector{input1}); + } +} \ No newline at end of file