Skip to content

Support for output-specific pattern matching #31647

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

evkotov
Copy link
Contributor

@evkotov evkotov commented Aug 7, 2025

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:

  • False positive matches requiring additional validation
  • Complex callback logic to filter correct outputs
  • Reduced pattern matching precision and performance
  • Error-prone transformations due to manual index verification

Solution

This PR introduces two new pattern predicates that enable output-specific pattern matching:

  1. Single Output Index Matching

op::Predicate output_index_matches(size_t expected_index);

  1. Multiple Output Index Matching

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:

  • 171629

@evkotov evkotov requested review from a team as code owners August 7, 2025 15:47
@evkotov evkotov requested review from itikhono, mryzhov and CuriousPanCake and removed request for a team August 7, 2025 15:47
@evkotov evkotov self-assigned this Aug 7, 2025
@evkotov evkotov added the category: transformations OpenVINO Runtime library - Transformations label Aug 7, 2025
@github-actions github-actions bot added category: Core OpenVINO Core (aka ngraph) category: CPP API OpenVINO CPP API bindings labels Aug 7, 2025
@CuriousPanCake
Copy link
Contributor

CuriousPanCake commented Aug 8, 2025

From what I remember, the initial idea was to add output's id checks the way this is done for Node, instead of adding predicates:
image

This might add certain limitation to wrap_type, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: Core OpenVINO Core (aka ngraph) category: CPP API OpenVINO CPP API bindings category: transformations OpenVINO Runtime library - Transformations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants