Repository navigation
Add composable C++ graph pattern rewriter - #33631
Draft
G. Ramalingam (gramalingam) wants to merge 45 commits into
Draft
G. Ramalingam (gramalingam) wants to merge 45 commits into
G. Ramalingam (gramalingam) wants to merge 45 commits into
Conversation
Extract the engine, six example rules, API/design documentation, and correctness tests from the completed rewriter implementation without performance-evaluation artifacts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace match-wide float32 scans with explicit data-binding checks. Keep scalar initializer validation and add focused guard tests plus numerical RMS coverage with an independently typed int64 Pow exponent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Expose textual Pattern and Replacement construction with read-only introspection. Keep parser builders private through a named internal parser, support explicit named final outputs, migrate correctness helpers and malformed-recipe coverage to parsed definitions, and replace the design investigation with a user-facing rule-writing guide. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace the last mutable single-node recipe use with a parsed plan containing an invalid schema attribute, preserving runtime failure and unchanged-graph assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the winning rule's pattern rather than the shared structural group's pattern when lowering parsed callback replacements. This preserves rule-local names for shared plans and the existing named-lookup safety regression. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Graph::Resolve deletes unused untyped graph NodeArgs. Keep the negative guard-test NodeArg on the stack so copied matches never reference freed graph-owned storage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Accept optional braced bodies and returns of all final operator outputs in order. Reject combined assignment-return syntax and migrate multi-output definitions and examples while preserving direct calls and unbraced compatibility. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use explicit void-cast brace expressions in Google Test exception macros to avoid declaration parsing and default-constructor lookup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Parse dotted domain names in patterns as well as replacements. Match and synthesize numeric rank-one tensor literals in positional inputs and exact numeric list attributes in keyword arguments, with parsing, structural, rollback and numerical coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The mismatching [1,3] graph correctly matched the additional [1,3] rule. Use [4,5] for the always-rejected structural-plan regression and trace mode/scenario explicitly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…iagnostics Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…tions Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Make every concrete named pattern callable, defer rooted-entry checks to GetPattern, and preserve nested alternative selection views. Update composition tests, manual C++ examples, and syntax documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Preserve tensor interface ports, reject aliased duplicate entry outputs, and bound cumulative expanded calls before scoped metadata copying. Use the portable classic-locale float reader and cover all four review findings with regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Make structural signatures locale-independent, require mapped interface outputs, preserve global checker order with cached structural matches, and guard contrib-only helpers. Add focused regressions and document the contracts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Keep annotation occurrences ordered through argument remapping, preserve tensor interface requirements across callers, materialize replacement schema defaults, and reject dependency nesting beyond 64 definitions before native recursion. Add focused regressions and document the guarantees and bound. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Retain tensor classification for annotations imported from ordinary callees, including identity aliases, while preserving already-classified typed attribute formals. Diagnose conflicts during library construction and cover nested calls and classification order in both matcher modes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Treat singleton named dimensions as permissive captures and repeated names as equality constraints requiring known matching metadata in every selected occurrence. Count only complete annotation choices, preserve scoped composition and retry isolation, and provide named diagnostics. Add regressions and document semantics; explicitly discard nodiscard Status in the throwing test assertion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Relocate the unchanged six-rule example factory and helpers into the test anonymous namespace, remove the production source and public declaration, and clarify documentation usage. Production callers author their own rules. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Move construction and ownership details after the opening example and use the explicit float[...] any-rank annotation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Keep type-alternative discussion local to annotations and move call constraint ordering and graph/type retry distinctions into the composition section. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Support typed positional signatures, explicit multi-output calls, tensor aliases, wildcard actuals, and branch-optional captures while retaining legacy instance-only multi-output calls. Bound nested expansion and document scoped introspection separately from tensor lookup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Allow unconstrained inferred result branches without adding annotation occurrences, reject output labels that shadow tensor aliases, and preserve ordinary typed attribute inputs with explicit output signatures. Add direct and nested regression coverage in both matcher modes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Document component contracts, check-and-bind, and engine resolution boundaries with a two-Transpose example. Add standalone component tests and numerical rule integration coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Signed-off-by: Ganesan Ramalingam <grama@microsoft.com>
Address PR16 feedback with MatchAt first-candidate matching, explicit lookup types, optional attribute constraints, and later rule construction documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Keep the initial component API example focused on MatchAt, then introduce multiple candidates and checker retry with a concrete disjunction example. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Add typed attribute-or-None captures with explicit presence state, nullable scoped lookup, repeated-binding checks, and omission through shared replacement staging. Preserve standalone missing-name errors with explicit absent-attribute bindings. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Keep the composed checker/replacement example as a later standalone section and update navigation for the new reading order. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: daf231a0-ce61-4a2b-9649-0f31e2296e4f
Ti-Tai Wang (titaiwangms)
self-requested a review
October 27, 2026 00:06
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
Introduce an experimental, explicitly opt-in C++ graph pattern rewriter in
onnxruntime::rewrite, with documentation and component/integration tests. This is infrastructure for authoring rewrites, not a production fusion rollout; it is not registered among ORT's default optimizers.Pattern::MatchAt/VisitMatchesandReplacement::InstantiateAPIs, candidate-localMatchbindings, C++ check-and-bind callbacks, rewrite rules, and aGraphTransformer-compatible engine.perm : ints | None, distinguishing captured absence from unknown names, with nullable lookup and replacement omission followed by schema default/required-attribute validation.Graph::Resolveare not transactional.Validation already performed on Windows CPU Release at implementation commit
e5927feb856711fc0f4c06145a553c1c2675cdf9; the subsequent head319fa38a679b3730ca7487c2269fa388dca58f2bchanges documentation order/cross-links only:Result: passed incremental Release build.
From
C:\ortbuild\rewriter3\Release\Release:Result: 155 tests passed across five suites, including component contracts, numerical CPU equivalence, composition/alternative retry, optional attributes, graph boundaries and replacement rollback.
Independent focused review additionally rebuilt the engine and artifact-only harnesses, passed 100 grouped optional-attribute checks plus existing component/dimension/positional checks, and compiled both test translation units in normal and
DISABLE_CONTRIB_OPSconfigurations (four successful compiles). The reviewer also reran the owner-built 155-test executable. These are local results, not upstream CI results. No clean full runtime rebuild, disabled-contrib runtime execution, or GPU validation was performed. Documentation checks preserve all code examples and verify local anchors, fenced blocks, heading order andgit diff --check.Motivation and Context
Graph rewrites combine recurring structural matching and graph-edit safety logic with rule-specific semantic and kernel-support checks. This separates those responsibilities: patterns describe structure, C++ check-and-bind functions establish applicability and prepare values, replacements describe construction, and the engine handles ordered application.
Standalone matching and fragment construction make each component independently testable. Reusable pattern composition avoids duplicating common graph forms while preserving local bindings and explicit alternative selection. Semantic equivalence, arithmetic/dependent constraints and kernel compatibility remain the rule author's responsibility in C++; there are no higher-order pattern parameters, general recursive backtracking, automatic C++ generation, or default optimizer behavior changes.
This draft is submitted from the existing
gramalingam:gramalingam-rewriter3branch for upstream discussion. It targets upstreammain(the current default;masteris no longer an actual upstream branch) without rebasing the source branch.