Skip to content

Sara/quantum phase folding#2944

Draft
sarababaeii wants to merge 39 commits into
mainfrom
sara/quantum-phase-folding
Draft

Sara/quantum phase folding#2944
sarababaeii wants to merge 39 commits into
mainfrom
sara/quantum-phase-folding

Conversation

@sarababaeii

@sarababaeii sarababaeii commented Jun 12, 2026

Copy link
Copy Markdown

Before submitting

Please complete the following checklist when submitting a PR:

  • All new functions and code must be clearly commented and documented.

  • Ensure that code is properly formatted by running make format.
    The latest version of black and clang-format-20 are used in CI/CD to check formatting.

  • All new features must include a unit test.
    Integration and frontend tests should be added to frontend/test,
    Quantum dialect and MLIR tests should be added to mlir/test, and
    Runtime tests should be added to runtime/tests.

When all the above are checked, delete everything above the dashed
line and fill in the pull request template.


Context:

Phase-folding optimization [Amy et. al.] for pure quantum programs.

It reduces T-count —and more generally the number of Rz gates— of Clifford+Rz circuits, using a SymbolicCircuit data structure consisting of two main properties: PhasePolynomial and AffineTransformation, which store the transformations of a circuit in the phase space and state space, respectively. The underlying data structure for both PhasePolynomial and AffineTransformation is the Parity class, which is essentially an efficient bitvector, representing a binary affine functional, i.e. parity function.

The algorithm has two main parts:

  1. Phase analysis, which scans the circuit and updates the SymbolicCircuit by each operation, accordingly.
  2. Phase merge, which iterates through PhasePolynomial terms to merge Rz gates conditional on the same Parity.

Description of the Change:
Implements [sc-119891], [sc-119857], and [sc-119862]

Benefits:

  • Supports multiple register allocations throughout the program
  • Supports qubit (ancilla) state initialization to computational basis states (by static values)
  • Features efficient —in both time and memory— bitvector operations for Parity class

Possible Drawbacks:

  • Does not support dynamic values
  • Does not support classical control flow

Related GitHub Issues:

Sara and others added 28 commits May 29, 2026 13:38
…2894)

**Context:**

We introduce `qecl.fabricate [magic]` in the QEC Logical layer, and want
to lower it to a subroutine for encoding a codeblock in the magic state
in the QEC Physical dialect. This subroutine will eventually be
performed by a magic state factory rather than being included in the IR,
but including it allows us to validate our processes via simulator. We
will not inject noise into the magic state fabrication subroutine, so
this does not need to be implemented in a fault-tolerant manner.

**Description of the Change:**

We add lowering for putting a code-block in the magic state based on the
unitary encoding for the ground-state of the codeblock. Note that the
unitary rather than measurement-based encoding must be used, because the
measurement-based encoding projects the codeblock into the code space,
but the magic state exists outside the code space.

We also fix a bug from the previous (QEC Logical level) PR for
`fabricate [magic]`, where the op is used in the `apply_T` subroutine.
The conditional `SX` correction was added in the wrong order.

**Benefits:**

We can lower `qecl.fabricate` to something that can be executed on a
simulator to create a codeblock in the magic state.

**Possible drawbacks:**

We don't lower `fabricate` to a magic-state distillation protocol, so
its not mimicking the instructions for hardware; this could be a source
of confusion if not communicated clearly.

Also, it's likely that we will eventually lower this op to
`qecp.fabricate` instead of including instructions for "fabrication" in
the IR - the fabrication instructions will already be known in the
magic-state factory, and we will be interfacing with it. However, for
exploration and validation, this is the solution most suited to our
current needs.

---------

Co-authored-by: Joey Carter <joseph.carter@xanadu.ai>
Co-authored-by: Joey Carter <joey.snarrcarter@gmail.com>
…2895)

**Context:**

We have 3 ops that we add to the IR for creating and using magic states
that need to be translated back to the `quantum` dialect for execution.
These are:

- `allocate_cb`: to create an additional auxiliary codeblock that we can
put in the magic state
- `deallocate_cb`: to deallocate the data codeblock after the
entanglement and measurement protocol teleports the data to the
allocated auxiliary codeblock (new data codeblock)
- `t`: used on a single physical qubit in the subroutine for generating
a magic state on the auxiliary codeblock

**Description of the Change:**

We add lowering for:

- `allocate_cb`: translates to allocating a quantum register of size `n`
- `deallocate_cb`: translates to deallocating a quantum register
- `t`: translates to `quantum.custom "T"`

We add integration tests to confirm that this and previous PRs for
`apply_T` and `fabricate_magic_state` allow us to apply T gates in the
Steane code as expected.

**Benefits:**

We can execute circuits with T-gates using the Steane code
We have the pieces in place to lower other protocols fabricating and
using magic states, like pi/8 PPMs

---------

Co-authored-by: Joey Carter <joseph.carter@xanadu.ai>
Co-authored-by: Joey Carter <joey.snarrcarter@gmail.com>
A static conditional can be evaluated trivially at trace time since it
doesn't really have a reason to exist. Static loops still serve the
purpose of compacting the program, but will introduce additional dynamic
variables. In some conditions resolving these at trace time can also be
desirable.

The toggle is global because in the context where the decision is made
we don't have access to QJIT-instance specific compilation options. This
is the simplest way forward, although alternatives could expand the
EvaluationContext with a reference to the currently active
`CompileOptions` in the future (for example).

[sc-121161]

---------

Co-authored-by: Isaac De Vlugt <34751083+isaacdevlugt@users.noreply.github.com>
…2923)

**Context:**
In order to analyze resources the operations must be in value semantics,
which requires a conversion step for any op in reference semantics.

**Description of the Change:**
Adds direct support for reference semantics to the `resource-analysis`
pass and underlying class.

**Benefits:**
Conversions are no longer needed for resource analysis.

**Possible Drawbacks:**

**Related GitHub Issues:**

[sc-121611]

---------

Co-authored-by: paul0403 <paulhaochen.wang@gmail.com>
**Context:**

When translating to the `qecp` dialect, we currently only generate a
subroutine for `S`, and not for adjoint S.

**Description of the Change:**

We add support for adjoint S. We add a subroutine by adding an `s_adj`
in the `QecCode` definition for `Steane`, and we map `qecl.s %0 adj` to
`s_adj` instead of `s` when selecting a subroutine.

Currently S is the only qecl logical op that can have adjoint=True, but
if other ops are added in the future, they can similarly have their
lowering defined by adding `opname_adj` to the `QecCode`.

**Benefits:**
We can use logical `adjoint(S)` and get correct results.

[sc-121126]

---------

Co-authored-by: Joey Carter <joseph.carter@xanadu.ai>
**Context:**
Remove libboost-dev src installation dep. Tested locally and on
manylinux_2_28 x86/aarch64

**Description of the Change:**

**Benefits:**
- Remove libboost-dev src installation dep on CIs
- No impacts on wheels recipes.

**Possible Drawbacks:**

**Related GitHub Issues:**
[sc-121685]
… flat circuits (#2920)

**Context:**
Implement the conversion pass from value semantics to reference
semantics.

To relieve review pressure, I'll again split into multiple PRs: flat
circuits (alloc, gates, observables), regioned ops (control flow +
adjoint), and subroutines.

**Description of the Change:**
The logic and code structure is essentially just a "conjugated"
`--convert-to-value-semantics` pass, but much easier, since we don't
need to build the extract/insert quantum dataflow.

Essentially, a map keeps track of what `qref` references each value
semantics qubit/qreg SSA value corresponds to. At each quantum
operation, e.g.
```mlir
   %out_qubit = quantum.custom "gate" %in_qubit
```
the map is cascaded forward via
```
   v_to_r_map[%out_qubit] = v_to_r_map[%in_qubit]
```

Note that this way of cascading forward saves the time needed to
repeatedly walk back the chain every time a new quantum value is
visited.

**Benefits:**
We have full qref support!
With both directions' conversion in place, pass implementors can freely
choose the semantics they want.

**Possible Drawbacks:**
None

[sc-105534]

---------

Co-authored-by: Mehrdad Malek <39844030+mehrdad2m@users.noreply.github.com>
@sarababaeii sarababaeii requested a review from sengthai June 12, 2026 16:51
@sarababaeii sarababaeii self-assigned this Jun 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hello. You may have forgotten to update the changelog!
Please edit doc/releases/changelog-dev.md on your branch with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

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

Thanks @sarababaeii for PR. Here is my initialize comments. Could you add tests in pytest as well. it could compare the circuit with and without phase folding. Doing this, would convince the correctness of the pass, and also usually check that test to see how it use as well.

Comment thread main.py

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 to show how we use the pass. We normally show the usage code such that in test (e.g in /catalyst/frontend/test/lit). So, the user could know how to use it while test the end-to-end pass as well.

Comment thread PhaseFoldingTest.mlir

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.

Great to have a test file! Could you add this folder in mlir/test/Quantum

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.

could you add the copyright text on the top of each files as well?

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.

8 participants