Skip to content

Support magic-T allocation via qp.allocate (MLIR + capture path) - #3029

Open
Qottmann wants to merge 34 commits into
mainfrom
qottmann/allocate-magic-core
Open

Support magic-T allocation via qp.allocate (MLIR + capture path)#3029
Qottmann wants to merge 34 commits into
mainfrom
qottmann/allocate-magic-core

Conversation

@Qottmann

@Qottmann Qottmann commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds capture-path (qjit(capture=True)) support for qp.allocate(..., state="magic-T"|"magic-T-adj"), pairing with the merged PennyLaneAI/pennylane#9846. Magic states lower through qref/PBC to pbc.fabricate (H+T / H+T†).

This is PR 1 of 2. #3027 adds all legacy (capture=False) tracing on top of this PR.

User-facing state strings: "magic-T" and "magic-T-adj". MLIR/PBC enums remain magic / magic_conj; Catalyst maps at lowering time.

MLIR / PBC lowering

  • Add pbc.ref.fabricate for magic and magic-conjugate preparation
  • Lower pbc.ref.fabricatepbc.fabricate in value-semantics conversion, with dead-anchor cleanup
  • Resource analysis + MLIR lit tests

Unified allocate/deallocate jaxpr

  • Capture frontend emits PennyLane allocate_prim / deallocate_prim
  • MLIR lowering in qref_jax_primitives.py selects qref.alloc vs pbc.ref.fabricate from state
  • Map "magic-T" / "magic-T-adj" → MLIR magic / magic_conj

Capture path only

  • qfunc_interpreter.py handles allocate/deallocate via unified jaxpr primitives
  • Device verification accepts new states

CI / deps

  • PennyLane 0.46.0.dev62 (.dep-versions, doc/requirements.txt)

Tests & docs (capture-only)

  • MLIR lit + Python lit (all capture=True)
  • Pytest: magic-T allocation, manual deallocate, MLIR lowering (capture=True only)
  • sharp_bits.rst + changelog

Review guide

Area Files
MLIR mlir/include/PBC/IR/PBCRefOps.td, mlir/lib/QRef/Transforms/value_semantics_conversion.*, mlir/lib/PBC/IR/PBCOps.cpp
JAX → MLIR frontend/catalyst/from_plxpr/qref_jax_primitives.py
Capture frontend/catalyst/from_plxpr/qfunc_interpreter.py, frontend/catalyst/device/verification.py

Test plan

Related

@Qottmann Qottmann changed the title Support magic state allocation via qp.allocate (MLIR + capture path) Support magic-T allocation via qp.allocate (MLIR + capture path) Jul 22, 2026
Qottmann added a commit that referenced this pull request Jul 22, 2026
Keep #3029 focused on MLIR lowering and the capture path. Legacy tape
tracing, non-capture tests, and jax_tracer qref-mode changes move to #3027.

Co-authored-by: Cursor <cursoragent@cursor.com>
Qottmann added a commit that referenced this pull request Jul 22, 2026
Own all jax_tracer legacy support on top of #3029: qref-mode dynamic
wires, allocate/deallocate tracing, MCM/PPM routing, control-flow wire
propagation, qref register lifetime, and ppr-to-ppm deallocation ordering.
Includes legacy and dual-mode pytest coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Update SpecsResources field names and bump the PennyLane pin to
0.46.0.dev62 so CI uses the latest resource hierarchy.

Co-authored-by: Cursor <cursoragent@cursor.com>
Qottmann added a commit that referenced this pull request Jul 22, 2026
Keep #3029 focused on MLIR lowering and the capture path. Legacy tape
tracing, non-capture tests, and jax_tracer qref-mode changes move to #3027.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Qottmann
Qottmann force-pushed the qottmann/allocate-magic-core branch from efcea1a to 541804b Compare July 22, 2026 10:49
Qottmann added a commit that referenced this pull request Jul 22, 2026
Own all jax_tracer legacy support on top of #3029: qref-mode dynamic
wires, allocate/deallocate tracing, MCM/PPM routing, control-flow wire
propagation, qref register lifetime, and ppr-to-ppm deallocation ordering.
Includes legacy and dual-mode pytest coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Qottmann
Qottmann changed the base branch from main to qottmann/fix-resources July 22, 2026 10:49
Qottmann added a commit that referenced this pull request Jul 22, 2026
Restore capture=False allocate error coverage, add negative deallocate tests,
consolidate deallocate guard logic, document staged fabricate primitives for

Co-authored-by: Cursor <cursoragent@cursor.com>
#3027, and fix the sharp_bits.rst cross-reference syntax.
Qottmann added a commit that referenced this pull request Jul 22, 2026
Own all jax_tracer legacy support on top of #3029: qref-mode dynamic
wires, allocate/deallocate tracing, MCM/PPM routing, control-flow wire
propagation, qref register lifetime, and ppr-to-ppm deallocation ordering.
Includes legacy and dual-mode pytest coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Update resource specs tests, Operator2 PLXPR expectations, and decomposition
graph handling for abstract Adjoint/Controlled resource reps introduced with
magic-T and the new resource API.

Co-authored-by: Cursor <cursoragent@cursor.com>

@dime10 dime10 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.

Nice work! I think we just need to sort out the jax primitive situation

Comment thread doc/dev/sharp_bits.rst Outdated
Comment thread doc/dev/sharp_bits.rst Outdated
Comment thread doc/releases/changelog-dev.md Outdated
Comment thread doc/releases/changelog-dev.md Outdated
Comment thread frontend/catalyst/device/verification.py Outdated
Comment thread frontend/catalyst/from_plxpr/qfunc_interpreter.py
Comment thread frontend/catalyst/from_plxpr/qref_jax_primitives.py Outdated
Comment thread frontend/catalyst/from_plxpr/qref_jax_primitives.py
Comment thread mlir/lib/Catalyst/Analysis/ResourceAnalysis.cpp Outdated
Comment thread mlir/lib/PBC/IR/PBCOps.cpp
Qottmann and others added 3 commits July 23, 2026 12:02
Skip C(...) decomposition-graph nodes for Operator2 controlled reps, restore
exact SpecsResources type equality in specs tests, and add a changelog entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
Test-suite and dependency-pin updates are not user-facing release notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Qottmann added a commit that referenced this pull request Jul 23, 2026
Own all jax_tracer legacy support on top of #3029: qref-mode dynamic
wires, allocate/deallocate tracing, MCM/PPM routing, control-flow wire
propagation, qref register lifetime, and ppr-to-ppm deallocation ordering.
Includes legacy and dual-mode pytest coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Qottmann and others added 11 commits July 23, 2026 12:20
When controls are applied via qfunc form (e.g. qp.ctrl(qp.S, wire)(0)),
PennyLane stores control wires on the interpreter rather than in
operator_p.n_ctrls. Merge self.control_wires into handle_operator and
add regression tests from #3035.

Co-authored-by: Cursor <cursoragent@cursor.com>
Lower state="magic" and state="magic_conj" to pbc.ref.fabricate with qref
deallocation, and enable the legacy tape path for dynamic wire allocation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Erase dead pbc.ref.fabricate and qref.alloc_qb anchor ops at the end of
conversion so they do not reach LLVM lowering, and update TestPBC checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fix import ordering, apply black formatting, and add a changelog entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Both capture and legacy frontends now emit allocate/deallocate at the
jaxpr level; MLIR lowering selects qref.alloc or pbc.ref.fabricate from
the state argument.

Co-authored-by: Cursor <cursoragent@cursor.com>
Map the new Python state strings to existing MLIR magic enums during
allocate lowering and update tests and docs accordingly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep #3029 focused on MLIR lowering and the capture path. Legacy tape
tracing, non-capture tests, and jax_tracer qref-mode changes move to #3027.

Co-authored-by: Cursor <cursoragent@cursor.com>
Restore capture=False allocate error coverage, add negative deallocate tests,
consolidate deallocate guard logic, document staged fabricate primitives for

Co-authored-by: Cursor <cursoragent@cursor.com>
#3027, and fix the sharp_bits.rst cross-reference syntax.
Describe the capture-path allocate feature in terms of user benefit rather
than implementation details, per changelog guidelines.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Qottmann
Qottmann force-pushed the qottmann/allocate-magic-core branch from bb4d012 to 391268d Compare July 23, 2026 10:34
Graph decomposition tests used state="any" and restored=True, which now
correctly raise CompileError per review feedback; zero-state allocation
matches the previous Catalyst behaviour for these cases.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread frontend/test/pytest/from_plxpr/test_decompose_transform.py
Qottmann and others added 4 commits July 23, 2026 17:05
Match the style of other tests in test_from_plxpr.py per review feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>

@dime10 dime10 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.

Excellent work 💯

I'm happy with it, leaving some final comments. @paul0403 Could you provide a second review? :)

Comment thread doc/releases/changelog-dev.md
Comment thread doc/releases/changelog-dev.md Outdated
Comment thread frontend/catalyst/device/qjit_device.py
Comment thread frontend/catalyst/from_plxpr/qfunc_interpreter.py
Comment thread mlir/lib/Catalyst/Analysis/ResourceAnalysis.cpp Outdated
Comment thread mlir/lib/QRef/Transforms/value_semantics_conversion.cpp
Comment thread mlir/lib/QRef/Transforms/value_semantics_conversion.cpp
Comment thread mlir/test/QRef/SemanticConversion/TestPBC.mlir
Comment thread frontend/catalyst/from_plxpr/qfunc_interpreter.py
Comment thread frontend/catalyst/from_plxpr/qref_jax_primitives.py
Comment thread frontend/test/pytest/test_dynamic_qubit_allocation.py Outdated
Comment thread mlir/lib/QRef/Transforms/value_semantics_conversion.h
JerryChen97 pushed a commit that referenced this pull request Jul 23, 2026
## Summary

PennyLane **dev62** is the minimum pin that includes both
[PennyLaneAI/pennylane#9846](PennyLaneAI/pennylane#9846)
(`magic-T`) and
[PennyLaneAI/pennylane#9841](PennyLaneAI/pennylane#9841)
(resource API). This PR bumps Catalyst to that pin and fixes the
resulting fallout.

**Resource API migration (#9841)**
- Bump PennyLane to `0.46.0.dev62` in `.dep-versions` and
`doc/requirements.txt`
- Replace `SymbolicSpecsResources` checks with
`SpecsResources.is_symbolic`
- Rename resource fields in tests: `gate_types`/`gate_counts` →
`quantum_operations`, `measurements` → `measurement_processes`,
`num_gates` → `total_quantum_operations`
- Drop `gate_sizes` assertions (no longer tracked)
- Handle `PBCSpecsResources` in PPR specs tests (depth fields)

**dev62 fallout (Operator2 / magic-T)**
- `decompose.py`: safe `.params` access for Operator2 ops; skip abstract
`Adjoint(...)` / `Controlled(...)` decomposition-graph nodes that lack
`op_type`
- PLXPR tests: single-qubit ops like `S`/`T` now lower to
`qref_operator` instead of `qref_qinst`
- `test_adjoint.py`: replace removed `qp.Rotation` with `qp.Rot`
- `test_quantum_control.py`: compare `ControlledOp2` decompositions with
`qp.equal`
- `test_specs.py`: normalize doubly-controlled `C(S)` counts in
`test_complex`

This is the base branch for the magic-state allocation stack (`#3029` →
`#3027`).

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Base automatically changed from qottmann/fix-resources to main July 23, 2026 18:16
Qottmann and others added 4 commits July 24, 2026 12:28
Document static num_wires in allocate lowering, drop redundant magic MLIR
pytest covered by lit, and add value-semantics CHECKs for magic_conj fabricate.

Co-authored-by: Cursor <cursoragent@cursor.com>
Mirror handleRefFabricate in reference_semantics_conversion and cover
magic and magic_conj in Quantum SemanticsConversion lit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

@paul0403 paul0403 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.

Thanks! Almost there

Comment thread mlir/test/Quantum/SemanticsConversion/TestPBC.mlir
Use quantum.custom result wires in reference-semantics conversion tests and
tie ref-side CHECKs to the fabricated qubit in QRef fabricate lit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread mlir/test/QRef/SemanticConversion/TestPBC.mlir Outdated
Qottmann and others added 3 commits July 24, 2026 15:21
Co-authored-by: Cursor <cursoragent@cursor.com>
Deallocate the PauliX result wire after ref-to-value conversion, matching
value-semantics gate behaviour.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use state="zero" in decomposition lit tests, ignore the restored flag in
handle_allocate so PennyLane work-wire decomps compile, and align docs/tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.94%. Comparing base (2e39af6) to head (0ae7ec7).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
frontend/catalyst/device/verification.py 25.00% 2 Missing and 1 partial ⚠️
...rontend/catalyst/from_plxpr/qref_jax_primitives.py 95.83% 1 Missing and 1 partial ⚠️
frontend/catalyst/device/qjit_device.py 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3029      +/-   ##
==========================================
- Coverage   96.97%   96.94%   -0.03%     
==========================================
  Files         165      165              
  Lines       19111    19160      +49     
  Branches     1819     1831      +12     
==========================================
+ Hits        18532    18575      +43     
- Misses        424      427       +3     
- Partials      155      158       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@paul0403 paul0403 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.

Awesome! 🥳

Comment thread doc/dev/sharp_bits.rst
Comment on lines +1379 to +1382
- The ``state="any"`` configuration is not supported by Catalyst and will raise a
compilation error. The ``restored`` keyword is ignored. Catalyst supports
``state="zero"`` initialization (the default), as well as magic state
initialization (see below).

@albi3ro albi3ro Aug 5, 2026

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.

Why can't we just continue treating state="any" as state="zero"? A little less efficient, but should still work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants