Support for output-specific pattern matching #31647
Open
+139
−0
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.
Details:
The current pattern matching system in OpenVINO's new symbols machinery has a critical limitation when dealing with multi-output operations. When patterns specify a particular output index (e.g., qkv_proj->output(0)), the pattern matcher would
incorrectly match any output from that operation, not specifically the requested output index.
Example of the Problem:
// Pattern intended to match specifically output 0 of VariadicSplit
auto pattern = wrap_typeov::op::v1::VariadicSplit([](const Output& output) {
// This predicate runs on ALL outputs, not just output(0)
return /* some condition */;
});
// This pattern would incorrectly match variadic_split->output(1) or output(2)
// when we specifically wanted output(0)
This forced developers to implement workarounds in transformation callbacks, manually checking the actual output index after pattern matching, leading to:
Solution
This PR introduces two new pattern predicates that enable output-specific pattern matching:
op::Predicate output_index_matches(size_t expected_index);
op::Predicate output_index_matches(const std::vector<size_t>& expected_indices);
Usage Examples
Before (requiring workarounds):
auto pattern = wrap_typeov::op::v1::VariadicSplit();
// Pattern matches any output, requiring callback validation
matcher.register_matcher(pass, pattern, [](pattern::Matcher& m) {
auto variadic_split = m.get_match_root();
// Manual workaround: check if matched output is actually output(0)
if (/* complex logic to verify output index */) {
// Perform transformation
}
});
After (clean and precise):
auto pattern = wrap_typeov::op::v1::VariadicSplit(output_index_matches(0));
// Pattern only matches output(0) specifically
matcher.register_matcher(pass, pattern, [](pattern::Matcher& m) {
// No additional validation needed - guaranteed to be output(0)
// Perform transformation directly
});
Multiple indices support:
auto pattern = wrap_typeov::op::v1::VariadicSplit(output_index_matches({0, 2}));
// Matches only outputs 0 and 2, but not 1
Tickets: