Skip to content

✨ Add Additional Canonicalization Patterns for QTensor#1728

Merged
burgholzer merged 26 commits into
mainfrom
enh/additional-tensor-canonicalization
May 28, 2026
Merged

✨ Add Additional Canonicalization Patterns for QTensor#1728
burgholzer merged 26 commits into
mainfrom
enh/additional-tensor-canonicalization

Conversation

@MatthiasReumann
Copy link
Copy Markdown
Collaborator

@MatthiasReumann MatthiasReumann commented May 21, 2026

Description

This pull request adds two additional canonicalization patterns to the qtensor::InsertOp operation.

As discussed in #1718, in combination with the QuantumLoopUnroll pass, this should us allow to map any quantum program using scf.for operations to superconducting architectures that do not support backwards branching.

For example, base profile backends and adaptive profile backends without backwards branching support can run the following pass pipeline to map their quantum program.

--quantum-loop-unroll
  --cse
    --canonicalization
       --place-and-route

Changes

Follow-Ups

  • To map scf.for operations natively, implement an approximative algorithm to find a SWAP sequence that restores one layout to another.

Checklist

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

If PR contains AI-assisted content:

  • I have disclosed the use of AI tools in the PR description as per our AI Usage Guidelines.
  • AI-assisted commits include an Assisted-by: [Model Name] via [Tool Name] footer.
  • I confirm that I have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

@MatthiasReumann MatthiasReumann added this to the MLIR Support milestone May 21, 2026
@MatthiasReumann MatthiasReumann self-assigned this May 21, 2026
@MatthiasReumann MatthiasReumann added enhancement Improvement of existing feature c++ Anything related to C++ code MLIR Anything related to MLIR labels May 21, 2026
@burgholzer
Copy link
Copy Markdown
Member

burgholzer commented May 21, 2026

If I understood this correctly, then this complements the Extract-Insert canonicalization with an Insert-Extract one. Wouldn't that be better suited in the ExtractOp.cpp file?

Furthermore: Does the bubbling canonicalization provide any "real" advantage besides sorting? Both canonicalizations can handle tensor chains well already without it, right?

But I am most likely missing something 😌

@MatthiasReumann
Copy link
Copy Markdown
Collaborator Author

MatthiasReumann commented May 21, 2026

If I understood this correctly, then this complements the Extract-Insert canonicalization with an Insert-Extract one.

Roughly yes. However, where the Extract-Insert one removes "no-ops":

%q0_0, %t0_1 = extract %t0_0, 0
%t0_1 = insert %q0_0, %t0_1, 0

// transformed to 
// <empty>

the Insert-Extract removes double-extracts of the same index:

%q0_0, %t0_1 = extract %t0_0, 0
%q0_1 = qco.h %q0_0
%t0_1 = insert %q0_1, %t0_1, 0
%q0_2, %t0_2 = extract %t0_1, 0
%q0_3 = qco.x %q0_2
%t0_3 = insert %q0_3, %t0_2, 0

// transformed to 
%q0_0, %t0_1 = extract %t0_0, 0
%q0_1 = qco.h %q0_0
%q0_2 = qco.x %q0_1
%t0_2 = insert %q0_2, %t0_1, 0

Wouldn't that be better suited in the ExtractOp.cpp file?

This is probably true nonetheless. I was initially thinking about putting it to the AllocOp.cpp file since it affects the tensor "globally".

Both canonicalizations can handle tensor chains well already without it, right?

Yes.

Furthermore: Does the bubbling canonicalization provide any "real" advantage besides sorting?

I would argue the following (may be irrelevant or invalid)

Lastly, the pattern has been inspired by the -bubble-down-memory-space-casts pass.

@burgholzer
Copy link
Copy Markdown
Member

If I understood this correctly, then this complements the Extract-Insert canonicalization with an Insert-Extract one.

Roughly yes. However, where the Extract-Insert one removes "no-ops":

%q0_0, %t0_1 = extract %t0_0, 0
%t0_1 = insert %q0_0, %t0_1, 0

// transformed to 
// <empty>

the Insert-Extract removes double-extracts of the same index:

%q0_0, %t0_1 = extract %t0_0, 0
%q0_1 = qco.h %q0_0
%t0_1 = insert %q0_1, %t0_1, 0
%q0_2, %t0_2 = extract %t0_1, 0
%q0_3 = qco.x %q0_2
%t0_3 = insert %q0_3, %t0_2, 0

// transformed to 
%q0_0, %t0_1 = extract %t0_0, 0
%q0_1 = qco.h %q0_0
%q0_2 = qco.x %q0_1
%t0_2 = insert %q0_2, %t0_1, 0

Maybe I am stupid, but this is the same right. It is also removing a "no-op", it's just not an extract-insert but an insert-extract one. Same same in my mind.

Wouldn't that be better suited in the ExtractOp.cpp file?

This is probably true nonetheless. I was initially thinking about putting it to the AllocOp.cpp file since it affects the tensor "globally".

Something really global would potentially better fit in the QTensorOps.cpp file, wouldn't it?
But I think at least the two Extract/Insert canons fit well in the respective files.

Furthermore: Does the bubbling canonicalization provide any "real" advantage besides sorting?

I would argue the following (may be irrelevant or invalid)

Lastly, the pattern has been inspired by the -bubble-down-memory-space-casts pass.

Fair points. It is probably reasonable to aim for a canonical ordering here.
Best case, this also provides a better starting point for the Extract/Insert canons requiring less iteration.
Convinced; let's keep it.

Moreso a general observation: At some point we may think about whether we really want to run the full canonicalization at every stage in our pipeline or whether we'd rather run more targeted sequences of patterns.
For example, I am not sure whether it really makes sense to run these particular passes more than once on a program.
This is definitely something for a follow-up though.

@MatthiasReumann
Copy link
Copy Markdown
Collaborator Author

Maybe I am stupid, but this is the same right.

Now that I think about it, you are right 🫠

At some point we may think about whether we really want to run the full canonicalization at every stage in our pipeline [...]

Probably also depends on how fast the end-to-end pipeline is, right?

@burgholzer
Copy link
Copy Markdown
Member

At some point we may think about whether we really want to run the full canonicalization at every stage in our pipeline [...]

Probably also depends on how fast the end-to-end pipeline is, right?

Yeah, small potential inefficiencies like these are particularly noticeable now since we do not yet have sophisticated passes running by default.
I would suppose that the runtime of a mapping pass will overshadow most inefficiencies.
Which, nonetheless, is not a reason for not thinking about them.
In the end, we want the compiler to be as fast and efficient as possible.

MatthiasReumann and others added 3 commits May 22, 2026 09:26
(cherry picked from commit c6985f0190f8a9450086411b03096edae6534e12)
@MatthiasReumann MatthiasReumann mentioned this pull request May 22, 2026
11 tasks
@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

❌ Patch coverage is 98.43750% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...lir/lib/Dialect/QTensor/IR/Operations/InsertOp.cpp 97.7% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

burgholzer added a commit that referenced this pull request May 27, 2026
## Description

This pull request adds the bi-directional `TensorIterator` class (the
analog of the `WireIterator` for tensors). Cherry-picked from #1728 to
ease the reviewing effort.

## Checklist

<!---
This checklist serves as a reminder of a couple of things that ensure
your pull request will be merged swiftly.
-->

- [x] The pull request only contains commits that are focused and
relevant to this change.
- [x] I have added appropriate tests that cover the new/changed
functionality.
- [x] I have updated the documentation to reflect these changes.
- [x] I have added entries to the changelog for any noteworthy
additions, changes, fixes, or removals.
- [x] I have added migration instructions to the upgrade guide (if
needed).
- [x] The changes follow the project's style guidelines and introduce no
new warnings.
- [x] The changes are fully tested and pass the CI checks.
- [x] I have reviewed my own code changes.

**If PR contains AI-assisted content:**

- [x] I have disclosed the use of AI tools in the PR description as per
our [AI Usage
Guidelines](https://github.com/munich-quantum-toolkit/core/blob/main/docs/ai_usage.md).
- [x] AI-assisted commits include an `Assisted-by: [Model Name] via
[Tool Name]` footer.
- [x] I confirm that I have personally reviewed and understood all
AI-generated content, and accept full responsibility for it.

---------

Signed-off-by: burgholzer <burgholzer@me.com>
Signed-off-by: Daniel Haag <121057143+denialhaag@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: burgholzer <burgholzer@me.com>
Co-authored-by: Daniel Haag <121057143+denialhaag@users.noreply.github.com>
@mergify mergify Bot added the conflict label May 27, 2026
@mergify mergify Bot removed the conflict label May 27, 2026
@MatthiasReumann MatthiasReumann marked this pull request as ready for review May 27, 2026 07:34
@MatthiasReumann
Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds canonicalization support for QTensor extract and insert operations by introducing rewrite patterns that remove redundant extract–insert pairs and reorder operations when semantically safe. The implementation is wired into the build system through updated CMake dependencies.

Changes

QTensor Extract/Insert Canonicalization

Layer / File(s) Summary
ExtractOp canonicalization contract and pattern
mlir/include/mlir/Dialect/QTensor/IR/QTensorOps.td, mlir/lib/Dialect/QTensor/IR/Operations/ExtractOp.cpp
ExtractOp declares hasCanonicalizer = 1 and implements RemoveExtractInsertPairPattern to eliminate matching extract–insert pairs where the scalar value is reinserted unchanged at the same constant index.
InsertOp canonicalization refactoring
mlir/lib/Dialect/QTensor/IR/Operations/InsertOp.cpp
InsertOp canonicalization is restructured to register two new patterns: RemoveInsertExtractPairPattern removes matching insert–extract pairs by traversing the tensor chain, and BubbleDownInsertPattern reorders an insert to occur after a subsequent extract when indices are non-equivalent. Helper logic for linearity-safety checks is updated to support the new patterns.
Build system dependencies and test wiring
mlir/lib/Dialect/QTensor/IR/CMakeLists.txt, mlir/lib/Dialect/QTensor/Utils/CMakeLists.txt, mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt, mlir/unittests/Dialect/QCO/Utils/CMakeLists.txt, mlir/unittests/Dialect/QIR/IR/CMakeLists.txt
Dialect and test targets are updated to link correct dependencies: MLIRQTensorDialect now depends on MLIRQTensorUtils, MLIRQTensorUtils switches to depend on MLIRQCODialect, and test executables are adjusted to include MLIRQTensorUtils where needed and remove or add dialect dependencies.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • munich-quantum-toolkit/core#1730: Introduces TensorIterator utility that the canonicalization patterns depend on for tensor chain traversal.
  • munich-quantum-toolkit/core#1542: Earlier work extending ExtractOp and InsertOp with extract/insert pairing verification logic that is now reused by the new canonicalization patterns.

Suggested reviewers

  • burgholzer
  • denialhaag

Poem

🐰 A tensor hop, extract and insert aligned,
Now canonicalization rules the line—
Pairs of operations fade away,
The IR grows cleaner every day!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding canonicalization patterns to the QTensor dialect. It is concise and directly relevant to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description is well-structured and complete, covering the change summary, related issue, motivation, and context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch enh/additional-tensor-canonicalization

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! Just one small typo. Feel free to merge afterwards.

Comment thread mlir/lib/Dialect/QTensor/IR/Operations/ExtractOp.cpp Outdated
Co-authored-by: Lukas Burgholzer <burgholzer@me.com>
Signed-off-by: matthias <matthias@bereumann.com>
@burgholzer burgholzer merged commit fe82bae into main May 28, 2026
33 checks passed
@burgholzer burgholzer deleted the enh/additional-tensor-canonicalization branch May 28, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Anything related to C++ code enhancement Improvement of existing feature MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants