Skip to content

✨ Add walkUnit Driver#1583

Merged
burgholzer merged 13 commits intomainfrom
enh/alternative-commit-trial
Mar 27, 2026
Merged

✨ Add walkUnit Driver#1583
burgholzer merged 13 commits intomainfrom
enh/alternative-commit-trial

Conversation

@MatthiasReumann
Copy link
Copy Markdown
Collaborator

@MatthiasReumann MatthiasReumann commented Mar 26, 2026

Description

This pull request adds a utility function walkUnit which traverses a quantum IR top down (analogously to the built-in walk functions of MLIR) and maintains a Qubits object that keeps track of the current SSA values. We use this function and the datastructure to solve the SSA Dominance issues once and for all by inserting SWAPs from a textual perspective (instead of a circuit def-use one).

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 self-assigned this Mar 26, 2026
@MatthiasReumann MatthiasReumann added c++ Anything related to C++ code MLIR Anything related to MLIR labels Mar 26, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 26, 2026

Codecov Report

❌ Patch coverage is 91.11111% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
mlir/include/mlir/Dialect/QCO/Utils/Drivers.h 89.4% 2 Missing ⚠️
mlir/lib/Dialect/QCO/Utils/Driver.cpp 92.3% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added qubit-tracking utilities and a non-recursive IR traversal helper to improve mapping visibility.
  • Refactor

    • Reworked place-and-route mapping to use a two-phase placement/commit flow with direct IR-level SWAP insertion and streamlined swap accounting.
  • Tests

    • Added unit tests validating traversal interruption and qubit-mapping behavior.
  • Chores

    • Updated changelog to include the new PR.

Walkthrough

Adds a QCO qubit state tracker mlir::qco::Qubits, a non-recursive walkUnit(Region, Fn) walker, refactors the Mapping pass to use these utilities for placement and commit (SWAP insertion), provides out-of-line Qubits implementations, and adds a unit test plus changelog/CMake updates.

Changes

Cohort / File(s) Summary
Qubits Utility
mlir/include/mlir/Dialect/QCO/Utils/Drivers.h, mlir/lib/Dialect/QCO/Utils/Driver.cpp
Add mlir::qco::Qubits with program↔hardware↔value mapping and methods: add(q), add(q, hw), remap(prev,next), remove(q), getProgramQubit(idx), getHardwareQubit(idx); implement out-of-line logic keeping containers synchronized.
Region Walker
mlir/include/mlir/Dialect/QCO/Utils/Drivers.h
Add template<typename Fn> void walkUnit(Region&, Fn&&) — top-down non-recursive region traversal invoking Fn(Operation*, Qubits&) and updating Qubits via type-dispatched op handlers.
Mapping Pass Refactor
mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp
Introduce LayeringResult; change layering API, split trial application into place() and commit(); remove old commitTrial; commit() now walks IR with walkUnit, inserts SWAPs using anchors, updates Qubits, and counts swaps.
Tests & Build
mlir/unittests/Dialect/QCO/Utils/test_drivers.cpp, mlir/unittests/Dialect/QCO/Utils/CMakeLists.txt
Add DriversTest.FullWalk gtest that exercises dynamic/static allocation, ops, measure/dealloc, and walkUnit interruption; include new test in the CMake target.
Changelog
CHANGELOG.md
Add PR reference #1583 to Unreleased "Added" list and PR links.

Sequence Diagram(s)

sequenceDiagram
    participant Commit as commit()
    participant WalkUnit as walkUnit(Region)
    participant TypeSwitch as TypeSwitch
    participant Qubits as Qubits
    participant IR as IR

    Commit->>WalkUnit: traverse region using anchors
    loop per operation
        WalkUnit->>TypeSwitch: dispatch op kind
        alt StaticOp
            TypeSwitch->>Qubits: add(q, static_index)
        else AllocOp
            TypeSwitch->>Qubits: add(new_q)
        else UnitaryOpInterface
            TypeSwitch->>Qubits: remap(inputs → outputs)
        else ResetOp/MeasureOp
            TypeSwitch->>Qubits: remap(in → out)
        else DeallocOp
            TypeSwitch->>Qubits: remove(q)
        end
        WalkUnit->>IR: insert SWAPs at anchor (if required)
        WalkUnit->>Qubits: update mappings
    end
    WalkUnit-->>Commit: SWAPs inserted, Qubits updated
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • burgholzer
  • denialhaag

Poem

🐰 I hop through ops and map each qubit,
program indices settle, hardware fit.
walkUnit leads the march, remap and swap,
anchors place steps, then forward we hop.
A tiny rabbit routing the circuit top.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change by referencing the key addition of the walkUnit utility driver, which is the primary focus of this PR.
Description check ✅ Passed The description covers the key objective (adding walkUnit function and Qubits tracking), provides motivation (addressing SSA dominance issues), and completes all required checklist items with checkmarks indicating fulfillment.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch enh/alternative-commit-trial

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
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/lib/Dialect/QCO/Utils/Driver.cpp`:
- Around line 32-44: Add a defensive assertion in Qubits::remap to ensure prev
is tracked before calling valueToIndex_.lookup: check
valueToIndex_.contains(prev) (or find(prev) != end()) and assert/fail if not,
mirroring the existence check in remove(); then proceed with the existing
lookup/erase/try_emplace logic so you never operate on a default-constructed
pair when prev is missing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 48039b74-0489-42d4-b2bf-b05e276017ea

📥 Commits

Reviewing files that changed from the base of the PR and between 725c8e6 and 4512b8f.

📒 Files selected for processing (3)
  • mlir/include/mlir/Dialect/QCO/Utils/Drivers.h
  • mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp
  • mlir/lib/Dialect/QCO/Utils/Driver.cpp

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/lib/Dialect/QCO/Utils/Driver.cpp`:
- Around line 21-30: The add methods in Qubits
(Qubits::add(TypedValue<QubitType>) and Qubits::add(TypedValue<QubitType>,
std::size_t)) can create duplicate keys and ignore insertion failures; replace
using programToValue_.size() with a monotonic counter (e.g., nextProgramIndex_)
to generate unique program indices and check the return of try_emplace for both
programToValue_/hardwareToValue_ and valueToIndex_ insertions; if any
try_emplace fails, handle it deterministically (assert, throw, or log+abort) to
avoid silent divergence between programToValue_/hardwareToValue_ and
valueToIndex_, and ensure both maps are only updated when both insertions
succeed (or roll back the first on failure).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e1e86a5f-f880-46d3-b476-00564d1b2ba3

📥 Commits

Reviewing files that changed from the base of the PR and between 4512b8f and c13905e.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • mlir/include/mlir/Dialect/QCO/Utils/Drivers.h
  • mlir/lib/Dialect/QCO/Utils/Driver.cpp
  • mlir/unittests/Dialect/QCO/Utils/test_drivers.cpp

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/unittests/Dialect/QCO/Utils/test_drivers.cpp`:
- Line 66: The test currently dereferences
module->getOps<mlir::func::FuncOp>().begin() into auto func without checking the
range; change the code to guard that getOps<mlir::func::FuncOp>() is not empty
before dereferencing (e.g., check begin() != end() or use an iterator and ensure
it != end()), and if empty emit a clear test assertion/failure message
indicating the expected FuncOp was not found; update the variable acquisition
around module and func to only dereference when the iterator is valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ab68fab5-c388-45de-8162-545a355225ec

📥 Commits

Reviewing files that changed from the base of the PR and between c13905e and c0a47fd.

📒 Files selected for processing (1)
  • mlir/unittests/Dialect/QCO/Utils/test_drivers.cpp

@MatthiasReumann
Copy link
Copy Markdown
Collaborator Author

@burgholzer Any idea why the coverage test fails even though there is a unit test which calls the "missed" line functions? 🤔

@burgholzer
Copy link
Copy Markdown
Member

@burgholzer Any idea why the coverage test fails even though there is a unit test which calls the "missed" line functions? 🤔

Haven't looked too deeply yet. Is the test executed?

@MatthiasReumann
Copy link
Copy Markdown
Collaborator Author

Haven't looked too deeply yet. Is the test executed?

Sorry, I'm an idiot. Forgot to commit and push the CMakeLists.txt.

@burgholzer
Copy link
Copy Markdown
Member

Haven't looked too deeply yet. Is the test executed?

Sorry, I'm an idiot. Forgot to commit and push the CMakeLists.txt.

Always glad to help 😉

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 pretty clean to me.
Some of the comments are more general questions. Most actual feedback is on small details.
Should be pretty quick to address.

@burgholzer burgholzer added this to the MLIR Support milestone Mar 26, 2026
@burgholzer burgholzer added the usability Anything related to usability label Mar 26, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp`:
- Around line 743-745: The function declaration for place is annotated with
[[nodiscard]] but returns void; remove the [[nodiscard]] attribute from the
place function declaration/definition to avoid meaningless attribute warnings.
Locate the static function named place(ArrayRef<QubitValue>, const Layout&,
Region&, IRRewriter&) in Mapping.cpp and delete the [[nodiscard]] token from its
signature so the function is a plain void return without the attribute.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 36d817e0-4d5a-401e-b666-2eb64d69bc07

📥 Commits

Reviewing files that changed from the base of the PR and between 3f521c9 and 8f06cfc.

📒 Files selected for processing (2)
  • mlir/include/mlir/Dialect/QCO/Utils/Drivers.h
  • mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp`:
- Around line 765-769: In commit(ArrayRef<SmallVector<IndexGate>> swaps,
ArrayRef<Operation*> anchors, Region& funcBody, IRRewriter& rewriter) add a
defensive assertion at the start that swaps.size() == anchors.size() with a
clear message; this ensures the function invariant (both arrays derived from the
same layering) is validated before using anchorIt/swapIt and will fail fast if
they diverge. Reference the commit function and the swaps and anchors parameters
when adding the check.
- Around line 752-759: The synthesized StaticOp and its DeallocOp are created
with rewriter.getUnknownLoc(), which loses traceability; change the creation to
use a descriptive location (e.g., the function's location or a fused location
combining the function and current insertion point). Specifically, in the loop
that iterates from dynQubits.size() to layout.nqubits() where you call
StaticOp::create(...) and DeallocOp::create(...), replace
rewriter.getUnknownLoc() with a meaningful MLIR Location (for example use
func.getLoc() or rewriter.getFusedLoc({func.getLoc(), someOp.getLoc()})) so both
StaticOp::create and DeallocOp::create carry that location for better debugging
and IR inspection. Ensure you import/derive the location value before the create
calls and pass it into both create invocations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dd9e62f8-9750-4e8d-a372-3b0b898e38b6

📥 Commits

Reviewing files that changed from the base of the PR and between 8f06cfc and b7be148.

📒 Files selected for processing (1)
  • mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp

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.

Thanks for the additional changes. LGTM 👍🏼

@burgholzer burgholzer merged commit 2ac824c into main Mar 27, 2026
33 checks passed
@burgholzer burgholzer deleted the enh/alternative-commit-trial branch March 27, 2026 10:10
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 MLIR Anything related to MLIR usability Anything related to usability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants