[CPU][Snippets]fix candidate merged node's subgraph inputs have common subgraph input (#16249)
This commit is contained in:
1 parent
1525f6cc16
commit
34b3abc0e2
6 files changed
+162
-1
No files matched your search
@@ -389,7 +389,11 @@ TokenizeSnippets::TokenizeSnippets() {
|
||||
size_t current_input_index = body_parameters.size();
|
||||
for (size_t p_ind = 0; p_ind < body_parameters.size(); p_ind++) {
|
||||
const auto & p = body_parameters[p_ind];
|
||||
if (p->get_friendly_name() == found->get_node_shared_ptr()->get_friendly_name()) {
|
||||
// unite two body parameters from two input subgraphs only if:
|
||||
// 1. two input subgraphs are connected to the same parent node/subgraph,
|
||||
// 2. and connected to the same output port of this parent node/subgraph.
|
||||
if (p->get_friendly_name() == found->get_node_shared_ptr()->get_friendly_name() &&
|
||||
external_inputs[p_ind] == *found) {
|
||||
current_input_index = p_ind;
|
||||
break;
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "snippets/edge_replace.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace snippets {
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<ov::PartialShape> input_shapes{{4}};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_Snippets_edge_replace, EdgeReplace,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(input_shapes),
|
||||
::testing::Values(ov::element::f32),
|
||||
::testing::Values(3),
|
||||
::testing::Values(1),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
EdgeReplace::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
} // namespace snippets
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared_test_classes/base/snippets_test_utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace snippets {
|
||||
|
||||
typedef std::tuple<
|
||||
ov::PartialShape, // Input Shape
|
||||
ov::element::Type, // Element type
|
||||
size_t, // Expected num nodes
|
||||
size_t, // Expected num subgraphs
|
||||
std::string // Target Device
|
||||
> EdgeReplaceParams;
|
||||
|
||||
class EdgeReplace : public testing::WithParamInterface<ov::test::snippets::EdgeReplaceParams>,
|
||||
virtual public ov::test::SnippetsTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<ov::test::snippets::EdgeReplaceParams> obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace snippets
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "snippets/edge_replace.hpp"
|
||||
#include "subgraph_simple.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace snippets {
|
||||
|
||||
std::string EdgeReplace::getTestCaseName(testing::TestParamInfo<ov::test::snippets::EdgeReplaceParams> obj) {
|
||||
ov::PartialShape inputShape;
|
||||
ov::element::Type type;
|
||||
std::string targetDevice;
|
||||
size_t num_nodes, num_subgraphs;
|
||||
std::tie(inputShape, type, num_nodes, num_subgraphs, targetDevice) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=" << CommonTestUtils::partialShape2str({inputShape}) << "_";
|
||||
result << "T=" << type << "_";
|
||||
result << "#N=" << num_nodes << "_";
|
||||
result << "#S=" << num_subgraphs << "_";
|
||||
result << "targetDevice=" << targetDevice;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void EdgeReplace::SetUp() {
|
||||
ov::PartialShape inputShape;
|
||||
ov::element::Type type;
|
||||
std::tie(inputShape, type, ref_num_nodes, ref_num_subgraphs, targetDevice) = this->GetParam();
|
||||
init_input_shapes({{{inputShape}, {inputShape.get_shape()}}});
|
||||
|
||||
auto f = ov::test::snippets::EdgeReplaceFunction({inputShape});
|
||||
function = f.getOriginal();
|
||||
setInferenceType(type);
|
||||
}
|
||||
|
||||
TEST_P(EdgeReplace, CompareWithRefImpl) {
|
||||
run();
|
||||
validateNumSubgraphs();
|
||||
}
|
||||
|
||||
} // namespace snippets
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
@@ -243,6 +243,21 @@ protected:
|
||||
|
||||
PartialShape m_target_shape;
|
||||
};
|
||||
|
||||
/// graph use case to cover duplicated subgraphs edge elimination in such as in yolo-v3
|
||||
// subgraph/node
|
||||
// / |
|
||||
// subgraph subgraph
|
||||
// \ /
|
||||
// eltwise node
|
||||
class EdgeReplaceFunction : public SnippetsFunctionBase {
|
||||
public:
|
||||
explicit EdgeReplaceFunction(const std::vector<PartialShape>& inputShapes) : SnippetsFunctionBase(inputShapes) {
|
||||
NGRAPH_CHECK(input_shapes.size() == 1, "Got invalid number of input shapes");
|
||||
}
|
||||
protected:
|
||||
std::shared_ptr<ov::Model> initOriginal() const override;
|
||||
};
|
||||
} // namespace snippets
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
@@ -318,6 +318,39 @@ std::shared_ptr<ov::Model> BroadcastSelectFunction::initOriginal() const {
|
||||
|
||||
return std::make_shared<Model>(NodeVector{select}, ParameterVector{data0, data1, data2});
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> EdgeReplaceFunction::initOriginal() const {
|
||||
auto input = std::make_shared<op::v0::Parameter>(ov::element::f32, input_shapes[0]);
|
||||
const auto axis = ngraph::op::Constant::create(element::i64, Shape{}, {0});
|
||||
// first parent and second parent have common inputs from output of split
|
||||
auto split = std::make_shared<ov::op::v1::Split>(input, axis, 2);
|
||||
auto mul_lhs = split->output(0);
|
||||
auto mul_rhs = split->output(1);
|
||||
|
||||
// first parent subgraph in tokenization stage
|
||||
const auto data0 = std::make_shared<ov::opset8::Constant>(ov::element::Type_t::f32, ov::Shape({1, 1, 1, 3, 2}),
|
||||
std::vector<float>{0.0, 0.2, 0.4, 0.6, 0.8, 1.0});
|
||||
const auto const_a4 = std::make_shared<ov::opset8::Constant>(ov::element::Type_t::f32, ov::Shape({2}), std::vector<float>{0.2, 0.1});
|
||||
auto mul_a4 = std::make_shared<op::v1::Multiply>(mul_rhs, const_a4);
|
||||
auto add_a1 = std::make_shared<op::v1::Add>(mul_a4, data0);
|
||||
auto mul_a5 = std::make_shared<op::v1::Multiply>(add_a1, mul_lhs);
|
||||
|
||||
// second parent subgraph in tokenization stage
|
||||
const auto data1 = std::make_shared<ov::opset8::Constant>(ov::element::Type_t::f32, ov::Shape({1, 1, 1, 3, 2}),
|
||||
std::vector<float>{0.1, 0.3, 0.5, 0.7, 0.9, 1.0});
|
||||
auto mul_a1 = std::make_shared<op::v1::Multiply>(data1, mul_lhs);
|
||||
const auto const_a2 = std::make_shared<ov::opset8::Constant>(ov::element::Type_t::f32, ov::Shape({2}), std::vector<float>{0.2, 0.4});
|
||||
auto mul_a2 = std::make_shared<op::v1::Multiply>(mul_a1, const_a2);
|
||||
const auto const_a3 = std::make_shared<ov::opset8::Constant>(ov::element::Type_t::f32, ov::Shape({2}), std::vector<float>{0.3, 0.1});
|
||||
auto mul_a3 = std::make_shared<op::v1::Multiply>(mul_a2, const_a3);
|
||||
|
||||
auto add_a3 = std::make_shared<op::v1::Add>(mul_a5, mul_a3);
|
||||
auto add_a2 = std::make_shared<op::v1::Add>(mul_a5, mul_a2);
|
||||
|
||||
auto concat = std::make_shared<op::v0::Concat>(ngraph::OutputVector{add_a3, add_a2}, 0);
|
||||
|
||||
return std::make_shared<Model>(NodeVector{concat}, ParameterVector{input});
|
||||
}
|
||||
} // namespace snippets
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
Reference in new issue
Block a user