Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- **QEC Stim MPP Import**: Added utilities for building `StabilizerCode` inputs from unsigned Stim `MPP` layers, including sparse Stim qubit id mapping, coordinate import, multi-layer selection, detector/logical-observable import, and the optional `graphqomb[stim]` extra. Signed products using inverted Pauli targets are rejected because stabilizer signs are not retained.
- **Stim Circuit Import**: Added `stim_file_to_pattern()`, `stim_text_to_pattern()`, and `stim_circuit_to_pattern()` for converting supported Stim circuits into GraphQOMB patterns. The importer handles Clifford unitary blocks and `TICK`-separated Pauli measurements (`M`/`MZ`, `MX`, `MY`, `MXX`, `MYY`, `MZZ`, and `MPP`), assigns single-qubit measurement bases directly to their graph nodes, terminates each qubit lifetime at its direct measurement while allowing disjoint qubits to continue, validates that same-block MPP products commute, supports Type I and Type II Y foliation, causally lowers commuting MPP groups, composes each MPP unit through a separate unmeasured output layer, and resolves detector/logical-observable records once across the full flattened circuit. Circuit-level noise and measurement-error probabilities are intentionally omitted because GraphQOMB uses an MBQC-specific noise model; reset, measurement-reset, and feedback instructions remain unsupported.

### Changed

- **Development Tooling**: Use uv as the default dependency manager for local development, CI, documentation builds, and publishing workflows.
- **Graph State API**: Replaced legacy `physical_*` graph methods/properties with standard graph-style `nodes`, `edges`, `add_node()`, `add_edge()`, `remove_node()`, `remove_edge()`, and count/query helpers.
- **Pattern Simulator**: Materialize pending output Pauli-frame corrections when returning output statevectors or explicit output measurement results.

### Fixed

- **Stim Compiler**: Preserve minus-signed axis measurement bases using inverted Stim measurement targets.
- **State Vector Array Conversion**: Convert to a real NumPy dtype without warnings when every amplitude is real-valued, and reject the conversion when it would discard nonzero imaginary amplitudes.

### Removed

- **Pattern Commands**: Removed explicit `graphqomb.command.X` and `graphqomb.command.Z` correction commands. Output corrections are now represented by `PauliFrame` only, and `.ptn` files containing `X`/`Z` command lines are rejected.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ If you already have a graph-state design and explicit feedforward maps, you can
- **API reference**: https://graphqomb.readthedocs.io/en/latest/references.html
- **QEC graph-state builder reference**: https://graphqomb.readthedocs.io/en/latest/qec.html
- **Stim MPP import reference**: https://graphqomb.readthedocs.io/en/latest/stim_mpp.html
- **Stim circuit import reference**: https://graphqomb.readthedocs.io/en/latest/stim_importer.html
- **Stim compiler reference**: https://graphqomb.readthedocs.io/en/latest/stim_compiler.html

## Current Scope
Expand Down
7 changes: 7 additions & 0 deletions docs/source/qec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ graph-state builder uses the first two qubit-coordinate components for the data
plane and the first three explicitly supplied stabilizer-coordinate components
for ancilla placement.

With ``data_as_io=True``, the stabilizer-measurement unit has a separate,
unmeasured output layer. Type I therefore has two measured data layers followed
by an output layer. Type II uses three Y-measured layers for qubits with Y
support, followed by an output layer; qubits without Y support retain the Type I
two-measurement-layer layout. Ancilla support edges only touch measurement
layers, and the output of one composed unit becomes the input of the next.

.. automodule:: graphqomb.qec.qeccode
:members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/source/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Module reference
scheduler
qec
stim_mpp
stim_importer
stim_compiler
noise_model
visualizer
Expand Down
84 changes: 84 additions & 0 deletions docs/source/stim_importer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Stim circuit import
===================

Install the optional Stim integration before importing this module:

.. code-block:: console

uv add "graphqomb[stim]"

The circuit importer converts supported Stim circuits into GraphQOMB
measurement patterns. It accepts Clifford unitary blocks and Pauli measurement
blocks separated by ``TICK``. The supported Pauli measurement instructions are
``M``/``MZ``, ``MX``, ``MY``, ``MXX``, ``MYY``, ``MZZ``, and ``MPP``.

Single-qubit measurements assign an ``AxisMeasBasis`` directly to the measured
graph node. They do not create an ``MPP`` extraction or an ancillary parity
measurement node. Inverted single-qubit measurement targets select the minus
sign of that node's basis. A direct single-qubit measurement terminates that
qubit's lifetime: a later quantum operation on the same qubit is rejected,
while operations on other qubits may continue. Reset and qubit reuse are not
supported.

Two-qubit measurements are parity measurements and are lowered to equivalent
unsigned ``MPP`` products. Inverted targets in ``MXX``, ``MYY``, ``MZZ``, and
``MPP`` are rejected because GraphQOMB does not currently retain the
corresponding parity offset.

All ``MPP`` instructions within one ``TICK`` block are represented by one
combined extraction and are validated to commute. Anticommuting products in
the same block are rejected. The importer uses one compact
stabilizer-measurement unit when its correction flow is causal. If the compact
unit has a cyclic Pauli flow, the commuting products are lowered to equivalent
sequential units instead. Non-commuting measurements must be separated by
``TICK`` in the source circuit. Each unit has a distinct unmeasured output
layer, which is composed with the next unitary or measurement fragment by qubit
index. Pass ``y_foliation=YFoliation.TYPE_II`` to any of the three import entry
points to use the three-layer Y-measurement construction; Type I is the default.

The flattened ideal circuit is analyzed once for measurement records. Records
from single-qubit measurements, pair measurements, ``MPP``, and ideal-zero
``MPAD`` replacements share one absolute index space. ``DETECTOR`` and
``OBSERVABLE_INCLUDE`` targets are resolved against that whole-circuit index
space, and each ``StimMppExtraction`` retains the corresponding absolute record
sets even when an annotation also references records outside that MPP unit.

Noise policy
------------

Circuit-level Stim noise is intentionally not imported. GraphQOMB applies
noise to the compiled MBQC pattern through its own noise-model API, where
preparation, entanglement, measurement, and idle events differ from the source
circuit operations.

Pure noise instructions are omitted during import. Error probabilities attached
to Pauli measurements are also omitted while retaining the ideal measurement.
Heralded noise records are retained as ideal zero-valued record positions so
that later ``DETECTOR`` and ``OBSERVABLE_INCLUDE`` references remain aligned.

Reset instructions (``R``/``RZ``, ``RX``, and ``RY``) and combined
measurement-reset instructions (``MR``/``MRZ``, ``MRX``, and ``MRY``) are not
handled by this importer. Consequently, a directly measured qubit cannot begin
a new lifetime later in the circuit.

.. code-block:: python

from graphqomb.qec.qeccode import YFoliation
from graphqomb.stim_importer import stim_text_to_pattern

result = stim_text_to_pattern(
"""
MX 0
MYY 1 2
DETECTOR rec[-2] rec[-1]
""",
y_foliation=YFoliation.TYPE_II,
)
pattern = result.pattern

API reference
-------------

.. automodule:: graphqomb.stim_importer
:members:
:show-inheritance:
9 changes: 7 additions & 2 deletions docs/source/stim_mpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ ancilla nodes.

Set ``coord_dims`` to the number of leading ``QUBIT_COORDS`` components to
retain. The importer does not restrict this value to two or three dimensions;
each referenced coordinate declaration must contain at least the requested
number of components.
each referenced qubit's final accumulated coordinate must contain at least the
requested number of components. Repeated declarations are combined according
to Stim's coordinate semantics.

.. code-block:: python

Expand All @@ -34,6 +35,10 @@ number of components.
API reference
-------------

.. autoclass:: graphqomb.qec.stim_mpp.StimMppExtraction
:members:
:show-inheritance:

.. automodule:: graphqomb.qec.stim_mpp
:members:
:show-inheritance:
Loading
Loading