🐛 Enforce quantum allocation and QIR output contracts - #2446
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
burgholzer
left a comment
There was a problem hiding this comment.
I am wondering whether this is the right scope to reject this.
Shouldn't we reject this at the QC/QCO dialect verification level already? I do not think our current infrastructure can handle programs with allocations placed in SCF regions or modifiers (which already forbid them).
Even functions, at least how they are currently implemented, do not really support this.
|
🤖 AI text below 🤖 @burgholzer Yes, if this is a general allocation invariant, checking it once during QC/QCO program verification makes sense. There is existing behavior to align: this QC-to-QCO test explicitly verifies and converts an allocation inside Is the intended rule that dynamic quantum allocations may occur only in the entry block of the If so, I propose reworking this PR to enforce that rule consistently for The code is unchanged pending agreement on that scope. |
Yeah, I would be tempted to say so. |
e6b2518 to
6fc5241
Compare
|
🤖 AI text below 🤖 @burgholzer Implemented the agreed rule in 6fc5241 and rebased onto Dynamic Removed the Adaptive-specific allocation scan and the redundant Mapping Local validation passed: the full lint-preset build, all 2,358 configured MLIR |
92ae2b5 to
2f1c4cb
Compare
Require dynamic qubit allocations in the entry function to remain in its original entry block. Reject unsupported conditional allocations before QIR lowering can move their releases outside the allocation scope. Assisted-by: GPT-6 via Codex
Assisted-by: GPT-6 via Codex
Assisted-by: GPT-6 via Codex
Enforce the shared QC/QCO program contract during verification and construction. Keep helpers resource-parameterized and remove redundant pass-local placement checks. Assisted-by: GPT-6 via Codex
Keep the whitespace fixture valid and check loop allocation rejection at program construction. Qualify the PennyLane capability reference so strict docs builds resolve it. Assisted-by: GPT-5 via Codex
2f1c4cb to
24e4ac8
Compare
Use shared allocation checks at standalone QIR and mapping boundaries. Preserve quantum release control flow, allocate Adaptive scalar results consistently with result registers, and validate output-store fusion before mutation. Diagnose multiple entry returns and document the supported subset. Keep builder result ownership consistent and model qc.yield as effect-free for recursive effect analysis. Add native regressions and migration guidance. Assisted-by: GPT-6 via Codex
Drop the added CF dialect dependency from the MQT verifier tests and use SCF for the conditional-release regression. Defer changelog and upgrade guide entries for unreleased v4 functionality to the release cleanup. Assisted-by: GPT-6 via Codex
burgholzer
left a comment
There was a problem hiding this comment.
I iterated on this quite a bit and added another QIR audit on top of it. This does a bit more now, but I believe it does it well.
If you are fine with the changes as well, let's get this in.
Preserve the shared allocation verifier alongside the target-environment lookup. Update the standalone mapping regression for the new pass factory and retain both boundary tests. Use direct owning-reference access in the merged target-environment tests to keep whole-file C++ lint clean. Assisted-by: Codex
🤖 AI text below 🤖
Description
Dynamic QC/QCO qubit allocations must occur directly in the entry block of the
mqt.entry_pointfunction. The shared MQT verifier enforces this program contract, builders reject invalid insertion points, and standalone QIR and mapping passes invoke the same allocation check before transforming input.Adaptive QIR preserves the control-flow position of quantum releases. Scalar results now use dynamic allocation alongside result registers, and only owned results are released. The QIR builder applies the same result policy independently of qubit allocation and releases owned qubits at finalization.
Shared QIR output preparation requires one entry-function return and validates measurement/store fusion before rewriting returns or deleting stores. Fusion requires the same block, an available index, and no intervening classical interference; stores to distinct constant indices remain supported. Unknown effects, overlapping writes, and changed execution conditions produce diagnostics.
qc.yieldis effect-free so recursive analysis can recognize supported quantum modifier bodies.Addresses the conditional-allocation finding in #2287 and the allocation, lifetime, result-ownership, and output-store audit findings. No new dependencies.
Validation: 1,952 native tests passed across the mapping, compiler, MQT/QC/QCO/QIR IR, QC-to-QCO, Base/Adaptive QIR, and OpenQASM suites after integrating main (
784519cf9). The release build used AppleClang 21 with LLVM/MLIR 23.1.0 andENABLE_IPO=ON. The compiler and MQT suites were rebuilt and passed again after fixing two lint warnings in the merged tests.uvx nox -s lintanduvx nox -s cpp-lintpassed; C++ lint checked every line of the changed C++ files with clang-tidy 23 and reported zero findings. Hosted CI for the updated head is pending; the full Python and documentation suites were not run locally.The allocation-verifier tests use SCF without an added CF dependency, and the conditional-release regression uses
scf.if. CF remains an internal QIR lowering dependency and is used to test rejection of unsupported multiple returns. Changelog and upgrade-guide updates for unreleased v4 functionality are deferred to the release cleanup.GPT-6 via Codex assisted the implementation, regression tests, validation, and PR text.
Checklist
If PR contains AI-assisted content:
🤖 *AI text below* 🤖(titles are exempt).