Skip to content

⚡️ Improve walkProgramGraph driver performance - #1930

Merged
burgholzer merged 20 commits into
mainfrom
enh/improve-driver-performance
Jul 27, 2026
Merged

⚡️ Improve walkProgramGraph driver performance#1930
burgholzer merged 20 commits into
mainfrom
enh/improve-driver-performance

Conversation

@MatthiasReumann

@MatthiasReumann MatthiasReumann commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Description

I spent this morning investigating and profiling the mapping pass using the benchmark I recently created and noticed a few interesting bits. As a consequence I tried to optimize as much as possible - overall a ~30% reduction in runtime on the set of circuits I benchmarked on (See below for table).

Moreover, I've also learned that isa, cast, and consequently TypeSwitch on interfaces is really expensive in MLIR as it always traverses a sorted array of interface libraries to find the correct context (See here for the MLIR implementation). I would expect another maybe not so insignificant improvement in runtime by swapping the UnitaryInterface with isa<XOp, YOp, ...>. To put this in numbers: It requires roughly the same amount of CPU cycles to perform the cast to UnitaryOpInterface as to manage the DenseMap for the pending wires.

Consequently, I tried to avoid redundant isa and cast operation for the interface in the driver function. Additionally, I moved the isa<AllocOp, ...> elsewhere to avoid the check for each iteration step (also noticed while profiling).

Benchmarks

Using 12x10 qubit grid as architecture and

const mlir::qco::MappingPassOptions options{.nlookahead = 20,
                                            .lambda = 0.5,
                                            .niterations = 1,
                                            .ntrials = 18,
                                            .seed = 39393939};
| circuit                                                | time_branch | time_main | time_branch / time_main |
|--------------------------------------------------------|-------------|-----------|-------------------------|
| bmw_quark_copula_nativegates_ibm_falcon_opt2_100       | 420         | 583       | 0.72                    |
| bmw_quark_copula_nativegates_ibm_falcon_opt2_30        | 21          | 27        | 0.78                    |
| bmw_quark_copula_nativegates_ibm_falcon_opt2_40        | 32          | 43        | 0.74                    |
| bmw_quark_copula_nativegates_ibm_falcon_opt2_50        | 68          | 88        | 0.77                    |
| bmw_quark_copula_nativegates_ibm_falcon_opt2_60        | 89          | 122       | 0.73                    |
| bmw_quark_copula_nativegates_ibm_falcon_opt2_70        | 162         | 217       | 0.75                    |
| bmw_quark_copula_nativegates_ibm_falcon_opt3_20        | 7           | 8         | 0.88                    |
| bv_nativegates_ibm_falcon_opt2_100                     | 5           | 6         | 0.83                    |
| bv_nativegates_ibm_falcon_opt2_110                     | 8           | 9         | 0.89                    |
| bv_nativegates_ibm_falcon_opt2_120                     | 7           | 9         | 0.78                    |
| bv_nativegates_ibm_falcon_opt2_30                      | 0           | 1         | 0                       |
| bv_nativegates_ibm_falcon_opt2_40                      | 1           | 2         | 0.5                     |
| bv_nativegates_ibm_falcon_opt2_50                      | 2           | 3         | 0.67                    |
| bv_nativegates_ibm_falcon_opt2_60                      | 3           | 4         | 0.75                    |
| bv_nativegates_ibm_falcon_opt2_90                      | 5           | 6         | 0.83                    |
| ghz_nativegates_ibm_falcon_opt2_100                    | 12          | 14        | 0.86                    |
| ghz_nativegates_ibm_falcon_opt2_110                    | 13          | 16        | 0.81                    |
| ghz_nativegates_ibm_falcon_opt2_120                    | 12          | 16        | 0.75                    |
| ghz_nativegates_ibm_falcon_opt2_50                     | 4           | 5         | 0.8                     |
| ghz_nativegates_ibm_falcon_opt2_60                     | 3           | 5         | 0.6                     |
| ghz_nativegates_ibm_falcon_opt2_70                     | 7           | 8         | 0.88                    |
| ghz_nativegates_ibm_falcon_opt2_80                     | 9           | 10        | 0.9                     |
| ghz_nativegates_ibm_falcon_opt2_90                     | 10          | 12        | 0.83                    |
| hhl_nativegates_ibm_falcon_opt2_100                    | 268         | 373       | 0.72                    |
| hhl_nativegates_ibm_falcon_opt2_110                    | 373         | 502       | 0.74                    |
| hhl_nativegates_ibm_falcon_opt2_120                    | 419         | 560       | 0.75                    |
| hhl_nativegates_ibm_falcon_opt2_30                     | 28          | 38        | 0.74                    |
| hhl_nativegates_ibm_falcon_opt2_40                     | 55          | 75        | 0.73                    |
| hhl_nativegates_ibm_falcon_opt2_50                     | 92          | 120       | 0.77                    |
| hhl_nativegates_ibm_falcon_opt2_60                     | 132         | 166       | 0.8                     |
| hhl_nativegates_ibm_falcon_opt2_80                     | 202         | 270       | 0.75                    |
| hhl_nativegates_ibm_falcon_opt2_90                     | 263         | 349       | 0.75                    |
| modular_adder_nativegates_ibm_falcon_opt2_50           | 55          | 65        | 0.85                    |
| modular_adder_nativegates_ibm_falcon_opt2_60           | 72          | 91        | 0.79                    |
| modular_adder_nativegates_ibm_falcon_opt2_70           | 93          | 138       | 0.67                    |
| qaoa_nativegates_ibm_falcon_opt2_30                    | 41          | 55        | 0.75                    |
| qaoa_nativegates_ibm_falcon_opt2_40                    | 42          | 56        | 0.75                    |
| qaoa_nativegates_ibm_falcon_opt2_45                    | 65          | 82        | 0.79                    |
| qaoa_nativegates_ibm_falcon_opt2_50                    | 93          | 121       | 0.77                    |
| qaoa_nativegates_ibm_falcon_opt2_55                    | 105         | 140       | 0.75                    |
| qaoa_nativegates_ibm_falcon_opt2_60                    | 141         | 172       | 0.82                    |
| qaoa_nativegates_ibm_falcon_opt2_65                    | 173         | 234       | 0.74                    |
| qft_nativegates_ibm_falcon_opt2_100                    | 113         | 160       | 0.71                    |
| qft_nativegates_ibm_falcon_opt2_110                    | 143         | 195       | 0.73                    |
| qft_nativegates_ibm_falcon_opt2_120                    | 144         | 204       | 0.71                    |
| qft_nativegates_ibm_falcon_opt2_30                     | 16          | 21        | 0.76                    |
| qft_nativegates_ibm_falcon_opt2_40                     | 24          | 32        | 0.75                    |
| qft_nativegates_ibm_falcon_opt2_50                     | 42          | 50        | 0.84                    |
| qft_nativegates_ibm_falcon_opt2_60                     | 52          | 69        | 0.75                    |
| qft_nativegates_ibm_falcon_opt2_70                     | 65          | 87        | 0.75                    |
| qft_nativegates_ibm_falcon_opt2_80                     | 79          | 106       | 0.75                    |
| qft_nativegates_ibm_falcon_opt2_90                     | 79          | 110       | 0.72                    |
| qftentangled_nativegates_ibm_falcon_opt2_100           | 128         | 177       | 0.72                    |
| qftentangled_nativegates_ibm_falcon_opt2_110           | 180         | 229       | 0.79                    |
| qftentangled_nativegates_ibm_falcon_opt2_120           | 154         | 235       | 0.66                    |
| qftentangled_nativegates_ibm_falcon_opt2_30            | 116         | 36        | 3.22                    |
| qftentangled_nativegates_ibm_falcon_opt2_40            | 26          | 35        | 0.74                    |
| qftentangled_nativegates_ibm_falcon_opt2_50            | 36          | 47        | 0.77                    |
| qftentangled_nativegates_ibm_falcon_opt2_60            | 59          | 79        | 0.75                    |
| qftentangled_nativegates_ibm_falcon_opt2_70            | 58          | 80        | 0.73                    |
| qftentangled_nativegates_ibm_falcon_opt2_80            | 100         | 124       | 0.81                    |
| qftentangled_nativegates_ibm_falcon_opt2_90            | 139         | 149       | 0.93                    |
| qnn_nativegates_ibm_falcon_opt2_100                    | 13          | 16        | 0.81                    |
| qnn_nativegates_ibm_falcon_opt2_110                    | 14          | 17        | 0.82                    |
| qnn_nativegates_ibm_falcon_opt2_120                    | 13          | 17        | 0.76                    |
| qnn_nativegates_ibm_falcon_opt2_30                     | 3           | 3         | 1                       |
| qnn_nativegates_ibm_falcon_opt2_40                     | 3           | 4         | 0.75                    |
| qnn_nativegates_ibm_falcon_opt2_50                     | 5           | 6         | 0.83                    |
| qnn_nativegates_ibm_falcon_opt2_70                     | 8           | 9         | 0.89                    |
| qnn_nativegates_ibm_falcon_opt2_80                     | 6           | 8         | 0.75                    |
| qnn_nativegates_ibm_falcon_opt2_90                     | 11          | 13        | 0.85                    |
| qpeexact_nativegates_ibm_falcon_opt2_100               | 137         | 196       | 0.7                     |
| qpeexact_nativegates_ibm_falcon_opt2_110               | 179         | 245       | 0.73                    |
| qpeexact_nativegates_ibm_falcon_opt2_120               | 189         | 270       | 0.7                     |
| qpeexact_nativegates_ibm_falcon_opt2_30                | 20          | 24        | 0.83                    |
| qpeexact_nativegates_ibm_falcon_opt2_40                | 27          | 36        | 0.75                    |
| qpeexact_nativegates_ibm_falcon_opt2_50                | 45          | 58        | 0.78                    |
| qpeexact_nativegates_ibm_falcon_opt2_60                | 60          | 78        | 0.77                    |
| qpeexact_nativegates_ibm_falcon_opt2_70                | 73          | 99        | 0.74                    |
| qpeexact_nativegates_ibm_falcon_opt2_80                | 93          | 128       | 0.73                    |
| qpeexact_nativegates_ibm_falcon_opt2_90                | 116         | 155       | 0.75                    |
| qpeinexact_nativegates_ibm_falcon_opt2_100             | 141         | 196       | 0.72                    |
| qpeinexact_nativegates_ibm_falcon_opt2_110             | 187         | 266       | 0.7                     |
| qpeinexact_nativegates_ibm_falcon_opt2_120             | 188         | 280       | 0.67                    |
| qpeinexact_nativegates_ibm_falcon_opt2_30              | 16          | 21        | 0.76                    |
| qpeinexact_nativegates_ibm_falcon_opt2_40              | 26          | 36        | 0.72                    |
| qpeinexact_nativegates_ibm_falcon_opt2_50              | 45          | 56        | 0.8                     |
| qpeinexact_nativegates_ibm_falcon_opt2_60              | 61          | 79        | 0.77                    |
| qpeinexact_nativegates_ibm_falcon_opt2_70              | 76          | 100       | 0.76                    |
| qpeinexact_nativegates_ibm_falcon_opt2_80              | 92          | 127       | 0.72                    |
| qpeinexact_nativegates_ibm_falcon_opt2_90              | 116         | 158       | 0.73                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_103 | 25          | 38        | 0.66                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_118 | 32          | 50        | 0.64                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_31  | 6           | 7         | 0.86                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_46  | 10          | 13        | 0.77                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_55  | 13          | 17        | 0.76                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_64  | 16          | 21        | 0.76                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_73  | 19          | 26        | 0.73                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_82  | 22          | 31        | 0.71                    |
| vbe_ripple_carry_adder_nativegates_ibm_falcon_opt2_91  | 26          | 36        | 0.72                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_100           | 88          | 114       | 0.77                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_110           | 137         | 132       | 1.04                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_120           | 118         | 136       | 0.87                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_30            | 32          | 36        | 0.89                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_40            | 24          | 18        | 1.33                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_50            | 31          | 84        | 0.37                    |
| vqe_real_amp_nativegates_ibm_falcon_opt2_54            | 85          | 28        | 3.04                    |
| vqe_su2_nativegates_ibm_falcon_opt2_100                | 76          | 77        | 0.99                    |
| vqe_su2_nativegates_ibm_falcon_opt2_110                | 125         | 124       | 1.01                    |
| vqe_su2_nativegates_ibm_falcon_opt2_120                | 117         | 130       | 0.9                     |
| vqe_su2_nativegates_ibm_falcon_opt2_30                 | 27          | 26        | 1.04                    |
| vqe_su2_nativegates_ibm_falcon_opt2_40                 | 24          | 31        | 0.77                    |
| vqe_su2_nativegates_ibm_falcon_opt2_50                 | 33          | 44        | 0.75                    |
| vqe_su2_nativegates_ibm_falcon_opt2_90                 | 72          | 147       | 0.49                    |
| vqe_two_local_nativegates_ibm_falcon_opt2_30           | 38          | 53        | 0.72                    |
| vqe_two_local_nativegates_ibm_falcon_opt2_40           | 93          | 130       | 0.72                    |
| vqe_two_local_nativegates_ibm_falcon_opt2_50           | 189         | 263       | 0.72                    |
| vqe_two_local_nativegates_ibm_falcon_opt2_60           | 319         | 415       | 0.77                    |
| vqe_two_local_nativegates_ibm_falcon_opt2_70           | 505         | 668       | 0.76                    |
|                                                        |             |           | 0.194            |

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:

  • Any agent that created, edited, or submitted GitHub content was explicitly authorized for that scope, as required by our AI Usage Guidelines.
  • Every agent-authored or agent-edited public text body begins with the visible disclosure 🤖 *AI text below* 🤖 (titles are exempt).
  • 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.

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

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

Files with missing lines Patch % Lines
mlir/include/mlir/Dialect/QCO/Utils/Drivers.h 91.4% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

@MatthiasReumann

Copy link
Copy Markdown
Collaborator Author

@burgholzer Any change you could ask codex for a review of the driver file (given the PR description)?

@denialhaag denialhaag changed the title ⚡️Improve walkProgramGraph driver performance ⚡️ Improve walkProgramGraph driver performance Jul 23, 2026
@denialhaag denialhaag added this to the MLIR Support milestone Jul 23, 2026
@denialhaag denialhaag added enhancement Improvement of existing feature MLIR Anything related to MLIR labels Jul 23, 2026
@burgholzer

Copy link
Copy Markdown
Member

@burgholzer Any change you could ask codex for a review of the driver file (given the PR description)?

Sure thing, will kick off a run later today when I have stable internet.

@burgholzer

Copy link
Copy Markdown
Member

🤖 AI text below 🤖

I reviewed the driver change and found that the reported speedup is confounded by a correctness regression in walkProgramGraph.

Before this PR, the callback's ready range was recomputed by filtering the complete pending map on every iteration. In this PR, an operation is appended to ReadyVec only when it first becomes ready, and ready.clear() runs after every callback. If the callback releases only some ready operations, the remaining operations stay in pending but are never added to ready again. Once the released wires finish advancing, the walk can return success with deferred operations still pending, so mapping does less work.

A focused regression with two initially ready CNOTs demonstrates this: releasing only one must leave the other visible when the released wires expose the next gate. The PR implementation loses the deferred CNOT. A second end-to-end mapping regression, with a control-flow operation ready alongside an independent barrier chain, also exposed the consequences of persistent/deferred readiness in mapping consumers.

I built a local release-mode A/B harness with deterministic frontier-heavy and routing-heavy circuits, three warmups, 25 paired samples, alternating execution order, and raw timing/statistical output:

  • Comparing the uncorrected PR head with the corrected traversal made the corrected frontier workload slower (median 101.69 ms versus 120.87 ms). This is expected once the skipped work is restored and must not be interpreted as optimization overhead.
  • Comparing the corrected implementation with a correctness-equivalent implementation that retains the old owning/copying representation showed no statistically significant difference:
    • frontier: +0.24%, bootstrap 95% CI [-3.33%, +3.18%];
    • routing: +2.95%, bootstrap 95% CI [-2.70%, +4.87%].

These local workloads are not the original circuit corpus from the PR description, so they do not by themselves quantify how much of the reported ~28% aggregate result came from the behavior change. They do show that the current benchmark comparison is not valid evidence for the proposed optimization.

The clean next step is therefore to revert the ReadyVec/driver refactor to the correct pre-PR behavior, retain the regression coverage, rerun the original benchmark corpus against that correctness baseline, and profile that baseline before attempting a new, narrowly measured optimization.

The test captures that ready operations omitted from one callback must remain visible to later callbacks until they are released.

Assisted-by: GPT-5.6 via Codex
Satisfy the CI-only include-cleaner check for the test-only regression commit.

Assisted-by: GPT-5.6 via Codex
Restore the ready-range behavior so unreleased ready operations remain visible to subsequent callbacks.

Assisted-by: GPT-5.6 via Codex
Assisted-by: GPT-5.6 via Codex
@burgholzer

Copy link
Copy Markdown
Member

9266cd8 adds a regression test that shows the flaw in the implementation of this PR.
3d61656 then reverts the changes here.

What I learned from this: We really need better and more comprehensive testing of the mapping pass so that we do not perform faulty optimizations.
I'll leave it to you @MatthiasReumann to take this PR from here.
Either simply update the title and description and simply merge the regression test or investigate whether some of the changes were genuine improvements.

@MatthiasReumann

Copy link
Copy Markdown
Collaborator Author

9266cd8 adds a regression test that shows the flaw in the implementation of this PR. 3d61656 then reverts the changes here.

What I learned from this: We really need better and more comprehensive testing of the mapping pass so that we do not perform faulty optimizations. I'll leave it to you @MatthiasReumann to take this PR from here. Either simply update the title and description and simply merge the regression test or investigate whether some of the changes were genuine improvements.

It's Saturday, but I couldn't let this go, so I simply fixed this right now and re-run the benchmarks. First of all, thanks for wasting your codex credits for fixing such an obvious bug. I hope CodeRabbit would've also been able to catch this. However, I think it's quite sad that codex didn't get the actual reason why this should be faster: Because the isa, cast checks are expensive and run often on hot paths. Updated the table in the pull request description. Improvement dropped to 20% - but still.

@mergify mergify Bot added the conflict label Jul 25, 2026
@mergify mergify Bot removed the conflict label Jul 25, 2026
@burgholzer

Copy link
Copy Markdown
Member

9266cd8 adds a regression test that shows the flaw in the implementation of this PR. 3d61656 then reverts the changes here.

What I learned from this: We really need better and more comprehensive testing of the mapping pass so that we do not perform faulty optimizations. I'll leave it to you @MatthiasReumann to take this PR from here. Either simply update the title and description and simply merge the regression test or investigate whether some of the changes were genuine improvements.

It's Saturday, but I couldn't let this go, so I simply fixed this right now and re-run the benchmarks. First of all, thanks for wasting your codex credits for fixing such an obvious bug. I hope CodeRabbit would've also been able to catch this. However, I think it's quite sad that codex didn't get the actual reason why this should be faster: Because the isa, cast checks are expensive and run often on hot paths. Updated the table in the pull request description. Improvement dropped to 20% - but still.

Interesting. Now the improvement also looks way more consistent than before.
The fact that gpt-5.6 rather reverted the changes was likely due to my way of prompting it. I'll let it take another stab at it.
Thanks for being persistent here!

Assisted-by: GPT-5.6 via Codex
Require the mapping pass to route incompatible two-qubit interactions across every qco.index_switch region. This test fails on the current PR head because the merge dropped IndexSwitchOp dispatch.

Assisted-by: GPT-5.6 via Codex
Restore IndexSwitchOp to the recursive routing dispatch after the latest main merge dropped it.

Assisted-by: GPT-5.6 via Codex
Record whether a pending operation is unitary when the graph driver first classifies it. Reuse that bit in mapping callbacks instead of repeating MLIR interface lookups on the hot path.

Assisted-by: GPT-5.6 via Codex
@burgholzer

Copy link
Copy Markdown
Member

🤖 AI text below 🤖

Matthias's follow-up is correct: after restoring the traversal semantics, the remaining driver changes still provide a genuine performance improvement. The key is avoiding repeated MLIR interface checks on a hot path, not the earlier change in ready-operation behavior.

Profiling makes that distinction visible:

  • On the current main baseline, walkProgramGraph accounted for 66% of sampled CPU time. Unitary-interface checks accounted for 34.1%, ready filtering for 32.2%, and getNumQubitArgs alone for 25.7%.
  • On Matthias's corrected PR head, walkProgramGraph dropped to 50.8%; unitary-interface checks dropped to 15.2% and ready filtering to 7.4%. In particular, d0570d6 caches the required-qubit count instead of repeatedly querying the interface.

During the follow-up I found a separate correctness regression introduced by the later merge commit: qco.index_switch had disappeared from the mapping pass's recursive-region dispatch. I published the regression independently in 34a2d770b. On that test-only head, focused local execution produced only the three original swaps instead of routing the three switch regions, and CI independently reported exactly one failing test out of 3,771: MappingPassTest.RouteIndexSwitchRegions. 59ad964b2 restores the missing dispatch.

The final small optimization in bcc37c3f5 records whether a pending operation is unitary when it enters the pending set and reuses that classification. This removes the remaining repeated casts/type switches without introducing a second cache or more complex invalidation logic.

I reran a release-mode A/B benchmark against current main with three warmups and 25 paired samples in randomized order. The benchmark-only commits change no production files relative to either measured SHA.

Scenario main median Integrated head median Speedup Bootstrap 95% CI
Frontier-heavy 214.697 ms 169.191 ms 27.89% 25.66% to 29.18%
Routing-heavy 9.909 ms 7.934 ms 24.81% 20.72% to 28.10%

An exploratory isolated A/B attributes roughly another 4.5% to the final classification cache. Route-quality samples remained overlapping for the frontier workload, while the routing workload produced exactly 171 swaps for every sample, so the timing improvement is not explained by systematically easier routes.

Local validation on the final head passed all 83 QCO utility tests, all 16 mapping tests, and the full repository lint suite. Final-head CI is now running. The benchmark harness and raw artifacts remain local, as planned, so they can be refined and proposed separately without expanding this PR.

@MatthiasReumann
MatthiasReumann marked this pull request as ready for review July 27, 2026 06:09
@MatthiasReumann

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Enhancements

    • Improved program-graph traversal and operation scheduling for more reliable processing of quantum operations.
    • Updated mapping workflows to use the enhanced traversal results while preserving routing behavior.
    • Ready operations remain available across traversal steps when not immediately released.
  • Bug Fixes

    • Improved routing behavior across index_switch regions.
  • Tests

    • Added coverage for routing through indexed switch regions.
    • Added validation for retained operations and insufficient-wire traversal scenarios.

Walkthrough

The graph walker now tracks pending operations with collected wire indices and exposes ready operations through ReadyMap. Mapping callbacks consume the new structure, and tests cover retained operations, traversal controls, and routing across index-switch regions.

Changes

QCO ReadyMap traversal

Layer / File(s) Summary
ReadyMap walker implementation
mlir/include/mlir/Dialect/QCO/Utils/Drivers.h
walkProgramGraph uses operation-keyed pending state, classifies traversal steps, collects wire indices, and updates the callback contract to ReadyMap.
Mapping pass ReadyMap integration
mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp, mlir/unittests/Dialect/QCO/Transforms/Mapping/test_mapping.cpp
Mapping consumes ready operations, releases executable operations, defers unroutable operations, and tests routing through qco.index_switch regions.
ReadyMap traversal tests
mlir/unittests/Dialect/QCO/Utils/test_drivers.cpp
Tests adopt ReadyMap callbacks and verify retained unreleased operations, forward and backward traversal, skipping, interruption, and block-argument starts.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProgramGraph
  participant Mapping
  participant Layout
  ProgramGraph->>Mapping: Provide ReadyMap operation and wire-index entries
  Mapping->>Layout: Check mapped qubit adjacency
  Layout-->>Mapping: Return adjacency status
  Mapping->>ProgramGraph: Release executable operations or defer routing
Loading

Possibly related PRs

Suggested labels: c++

Suggested reviewers: burgholzer

Poem

A bunny hops through wires bright,
Ready maps arrange the flight.
Pending gates wait, then bloom,
Swaps guide paths through every room.
Tests cheer softly: “Graph, resume!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: improving walkProgramGraph driver performance.
Description check ✅ Passed The description includes summary, motivation, context, benchmarks, and tests, and largely matches the template requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch enh/improve-driver-performance

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.

@MatthiasReumann

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mlir/include/mlir/Dialect/QCO/Utils/Drivers.h`:
- Around line 38-57: Update the Doxygen callback signature documentation for
WalkProgramGraphFn to replace the stale ReadyRange reference with ReadyMap,
matching the alias used by the actual function_ref type; leave the surrounding
documentation unchanged.

In `@mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp`:
- Around line 1169-1195: Deduplicate nested-region operations staged by the
walkProgramGraph callback before stack.emplace_back(). Track the operations
already added to stack during this traversal and skip subsequent entries for the
same operation, while preserving existing BarrierOp and adjacent UnitaryOp
release behavior.
🪄 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 Plus

Run ID: 0dbde1bd-dc73-4fcc-8ba3-2f765e2b3385

📥 Commits

Reviewing files that changed from the base of the PR and between 07fafad and 5d3a893.

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

Comment thread mlir/include/mlir/Dialect/QCO/Utils/Drivers.h Outdated
Comment thread mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp
Keep implementation members distinct from parameters, localize the pending state, use DenseMap insertion directly, and iterate key views where mapped values are unused.

Assisted-by: GPT-5.6 via Codex
Track nested operations when staging recursive routing so persistent ready operations are dispatched only once while independent wires advance. Cover the failure with a multi-qubit barrier-chain regression.

Assisted-by: GPT-5.6 via Codex

@burgholzer burgholzer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These look like genuine improvements. Let's get this merged 🚀

@burgholzer
burgholzer merged commit 88d1caf into main Jul 27, 2026
33 checks passed
@burgholzer
burgholzer deleted the enh/improve-driver-performance branch July 27, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement of existing feature MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants