-
Notifications
You must be signed in to change notification settings - Fork 3k
[Snippets][CPU] Introduce InsertTailFill pass in ReduceDecomposition #33963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
aobolensk
merged 7 commits into
openvinotoolkit:master
from
aobolensk:snippets-cpu-eliminate-inplace-ops
Feb 12, 2026
Merged
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4e8a10e
[Snippets][CPU] Introduce EliminateInplaceOps pass
aobolensk 3aaed2c
Fix assert condition
aobolensk 66ed10d
Apply review comment
aobolensk a03abcd
fixes
aobolensk 544e543
Address review comments
aobolensk 817dfed
Address review comments
aobolensk 2384c17
Merge branch 'master' into snippets-cpu-eliminate-inplace-ops
aobolensk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
src/common/snippets/include/snippets/lowered/pass/eliminate_inplace_ops.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| // Copyright (C) 2018-2026 Intel Corporation | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <functional> | ||
|
|
||
| #include "openvino/core/rtti.hpp" | ||
| #include "snippets/lowered/linear_ir.hpp" | ||
| #include "snippets/lowered/pass/pass.hpp" | ||
|
|
||
| namespace ov::snippets::lowered::pass { | ||
|
|
||
| /** | ||
| * @interface EliminateInplaceOps | ||
| * @brief Eliminates operations that are effectively inplace (input == output). | ||
| * Currently handles Fill operations where offset equals register capacity, | ||
| * which means the operation doesn't actually fill any new data. | ||
| * This pass should run after InsertSpecificIterations and before InitRegisters. | ||
| * @ingroup snippets | ||
| */ | ||
| class EliminateInplaceOps : public Pass { | ||
| public: | ||
| OPENVINO_RTTI("EliminateInplaceOps", "", Pass); | ||
|
|
||
| /** | ||
| * @brief Callback type for determining if a Fill operation is inplace. | ||
| * Takes offset and element size, returns true if the Fill is inplace. | ||
| */ | ||
| using IsInplaceFillCallback = std::function<bool(size_t offset, size_t element_size)>; | ||
|
|
||
| /** | ||
| * @brief Constructor with callback for inplace detection | ||
| * @param is_inplace_fill_callback Function to determine if a Fill is inplace based on offset and element size | ||
| */ | ||
| explicit EliminateInplaceOps(IsInplaceFillCallback is_inplace_fill_callback); | ||
|
|
||
| /** | ||
| * @brief Apply the pass to the Linear IR | ||
| * @param linear_ir the target Linear IR | ||
| * @return status of the pass (true if any changes were made) | ||
| */ | ||
| bool run(LinearIR& linear_ir) override; | ||
|
|
||
| private: | ||
| /** | ||
| * @brief Check if a Fill operation is inplace using the configured callback | ||
| * @param fill_expr expression containing Fill operation | ||
| * @return true if the Fill operation is inplace and can be eliminated | ||
| */ | ||
| bool is_inplace_fill(const ExpressionPtr& fill_expr) const; | ||
|
|
||
| /** | ||
| * @brief Remove inplace Fill operation from the linear IR | ||
| * @param linear_ir the target Linear IR | ||
| * @param fill_expr expression containing inplace Fill operation | ||
| */ | ||
| static void eliminate_fill(LinearIR& linear_ir, const ExpressionPtr& fill_expr); | ||
|
|
||
| IsInplaceFillCallback m_is_inplace_fill_callback; | ||
| }; | ||
|
|
||
| } // namespace ov::snippets::lowered::pass |
80 changes: 80 additions & 0 deletions
80
src/common/snippets/src/lowered/pass/eliminate_inplace_ops.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| // Copyright (C) 2018-2026 Intel Corporation | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
|
|
||
| #include "snippets/lowered/pass/eliminate_inplace_ops.hpp" | ||
|
|
||
| #include <utility> | ||
|
|
||
| #include "openvino/core/except.hpp" | ||
| #include "openvino/core/type.hpp" | ||
| #include "snippets/itt.hpp" | ||
| #include "snippets/lowered/expression.hpp" | ||
| #include "snippets/lowered/expression_port.hpp" | ||
| #include "snippets/lowered/linear_ir.hpp" | ||
| #include "snippets/op/fill.hpp" | ||
|
|
||
| namespace ov::snippets::lowered::pass { | ||
|
|
||
| EliminateInplaceOps::EliminateInplaceOps(IsInplaceFillCallback is_inplace_fill_callback) | ||
| : m_is_inplace_fill_callback(std::move(is_inplace_fill_callback)) { | ||
| OPENVINO_ASSERT(m_is_inplace_fill_callback, "Callback for inplace Fill detection must be provided"); | ||
| } | ||
|
|
||
| bool EliminateInplaceOps::is_inplace_fill(const ExpressionPtr& fill_expr) const { | ||
| const auto fill = ov::as_type_ptr<snippets::op::Fill>(fill_expr->get_node()); | ||
| if (!fill) { | ||
| return false; | ||
| } | ||
|
|
||
| const auto offset = fill->get_offset(); | ||
| const auto element_size = fill->get_output_element_type(0).size(); | ||
|
|
||
| return m_is_inplace_fill_callback(offset, element_size); | ||
| } | ||
|
|
||
| void EliminateInplaceOps::eliminate_fill(LinearIR& linear_ir, const ExpressionPtr& fill_expr) { | ||
| // Inplace Fill has one input and one output | ||
| // We need to redirect all consumers of the Fill's output to use the Fill's input instead | ||
|
|
||
| OPENVINO_ASSERT(fill_expr->get_input_count() == 1, "Fill should have exactly one input"); | ||
| OPENVINO_ASSERT(fill_expr->get_output_count() == 1, "Fill should have exactly one output"); | ||
|
|
||
| const auto& fill_input_connector = fill_expr->get_input_port_connector(0); | ||
| const auto& fill_output_connector = fill_expr->get_output_port_connector(0); | ||
|
|
||
| // Get all consumers of this Fill operation | ||
| const auto consumers = fill_output_connector->get_consumers(); | ||
|
|
||
| // Redirect all consumers to use the input of Fill directly | ||
| lowered::replace_input_port_connectors(consumers, fill_input_connector); | ||
|
|
||
| // Remove Fill from the linear IR | ||
| linear_ir.erase(linear_ir.find(fill_expr)); | ||
| } | ||
|
|
||
| bool EliminateInplaceOps::run(LinearIR& linear_ir) { | ||
| OV_ITT_SCOPED_TASK(ov::pass::itt::domains::SnippetsTransform, "Snippets::EliminateInplaceOps"); | ||
|
|
||
| bool modified = false; | ||
|
|
||
| // Iterate through all expressions and eliminate inplace Fill operations | ||
| // We iterate from the end to avoid iterator invalidation issues when erasing | ||
| auto expr_it = linear_ir.begin(); | ||
| while (expr_it != linear_ir.end()) { | ||
| const auto& expr = *expr_it; | ||
|
|
||
| if (is_inplace_fill(expr)) { | ||
| eliminate_fill(linear_ir, expr); | ||
| modified = true; | ||
| // After erasing, we need to reset the iterator | ||
| expr_it = linear_ir.begin(); | ||
| } else { | ||
| ++expr_it; | ||
| } | ||
| } | ||
|
|
||
| return modified; | ||
| } | ||
|
|
||
| } // namespace ov::snippets::lowered::pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.