Skip to content

🐛 Export independently scheduled measurements - #2452

Open
simon1hofmann wants to merge 4 commits into
codex/preserve-mapped-classical-controlfrom
codex/export-grouped-measurements
Open

🐛 Export independently scheduled measurements#2452
simon1hofmann wants to merge 4 commits into
codex/preserve-mapped-classical-controlfrom
codex/export-grouped-measurements

Conversation

@simon1hofmann

@simon1hofmann simon1hofmann commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤖 AI text below 🤖

Description

Stacked on #2351, updated through parent commit 2850cf57e (including current
main). This PR fixes the native Qiskit exporter boundary exposed by the
remaining 25 Benchpress feed-forward profiles, separately from the routing
correction in the parent PR. Merge the parent first, then retarget this PR to
main.

Mapping may legally separate a measurement from its classical destination by
other measurements or independent control flow. Permit destination fusion when
recursive effects cannot access that bit, using CBit's non-aliasing register
contract and static-index disambiguation. Keep measurements at their original
quantum positions and add no scratch classical bits.

Record the earlier fused write in the parent's write index, including nested
operations. Both scalar snapshot materialization and deferred-expression
validation must observe that write. Preserve the parent's scope-based caches
and scalar snapshot support instead of restoring recursive write scans.

Overlapping accesses, unknown effects, and unsupported stale snapshots remain
diagnosed. Stale register snapshots wider than 64 bits remain unsupported.
The unique measurement-destination requirement remains an exporter limitation,
not a QC dialect invariant; multiple classical destinations are outside this PR.

Current validation

  • Rebuilt bindings with Python 3.13 and Qiskit 2.5.2: all 389 tests in
    test_mlir_qiskit_translation.py and test_mlir_loops.py pass.
  • The updated scalar-snapshot regression checks QC and QC/QCO round trips with
    consumers before and after the delayed store. A final controlled-qubit
    measurement verifies the captured value without adding classical bits.
  • Required stub generation, full repository lint, and whole-file C++ lint
    against origin/codex/preserve-mapped-classical-control pass. Generated stubs
    add no API changes relative to the parent.
  • Hosted CI must rerun on the updated head; previous-head results are not
    validation of this update.

Historical Benchpress validation

At source commit 7dad9e19e, a fresh wheel with Qiskit 2.5.0 passed all 42
targeted Benchpress native-export checks: 31 previously guarded profiles, ten
existing profiles, and BV100. No OpenQASM fallback was used. All 4,621
conditionals remained, nested gates passed Qiskit basis/connectivity analysis,
and BV100 retained exactly 99 classical bits and measurements. All 80
Benchpress integration tests and the then-current 330 Qiskit translation tests
passed; the preceding build failed 12 of the new positive cases.

These Benchpress checks were not rerun for this update. The old integration
snapshot-rejection test predates the parent's scalar snapshot support and has
not been revalidated.

The historical Benchpress checks used a corresponding local integration update:
pin that PR snapshot, retire the temporary textual event-order checker, retain
input restrictions, and enable only the validated profiles. Those adapter
changes are not part of this Core diff. The full benchmark suite was not
restarted; structural counts are not a general dynamic-program equivalence
proof.

No changelog or migration entry is needed for this unreleased-v4 fix with no
public API changes. Implementation, tests, and this description were prepared
with AI assistance through Codex. Human review remains required.

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).
  • I have disclosed AI assistance in the PR description.
  • I confirm that I have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

Permit measurement destination fusion across disjoint recursive effects while accounting for the earlier write in classical snapshot validation.

Assisted-by: GPT-5 via Codex
Document the successful native-export matrix and the retained stale-snapshot boundary.

Assisted-by: GPT-5 via Codex
@simon1hofmann simon1hofmann added fix Fix for something that isn't working c++ Anything related to C++ code MLIR Anything related to MLIR skip-changelog Changes that do not need to show up in the changelog labels Sep 7, 2026

@MatthiasReumann MatthiasReumann left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Solid work 🗿 Left some nitpicks. Nothing too dramatic! I'll leave it to @burgholzer to judge how these changes fit into the bigger picture of the QASM export.

Comment on lines +1703 to +1706
if (destination) {
throw std::runtime_error(
"QC measurement has more than one classical destination");
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can keep this assumption for now. However, generally, this could be valid right? @burgholzer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 AI text below 🤖

Yes, this is valid QC IR: the measurement returns an i1 that can be stored in
several destinations. This is an existing native-Qiskit exporter limitation,
not a dialect invariant; this PR moves the check into a shared helper.

Keeping the restriction here as suggested. Supporting multiple destinations
would require one measurement followed by classical copies that preserve write
order and captured values. That extension is outside this PR's scope.

Comment thread bindings/mlir/qiskit/QiskitExport.cpp Outdated
Comment thread bindings/mlir/qiskit/QiskitExport.cpp Outdated
Comment thread bindings/mlir/qiskit/QiskitExport.cpp Outdated
Use TypeSwitch and shared memory-effect handling while preserving
static-index disambiguation and the existing exporter limits.
Cover disjoint bit accesses and intervening register allocations.

Assisted-by: GPT-5 via Codex
@simon1hofmann simon1hofmann self-assigned this Sep 8, 2026
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Important

Approval pending

CodeRabbit has no unresolved comments, but it has not reviewed the latest commit.

Use the checkbox below to review the latest commit. CodeRabbit will approve the changes if it finds no blocking issues.

  • 🔍 Trigger review

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.

@mergify mergify Bot added the conflict label Sep 8, 2026
Keep indexed writes and scalar snapshots from the updated routing branch. Index fused measurement destinations at their earlier write position and verify snapshot semantics before and after delayed stores.

Assisted-by: Codex
@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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 fix Fix for something that isn't working MLIR Anything related to MLIR skip-changelog Changes that do not need to show up in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants