Skip to content

Commit

Permalink
Merge branch 'main' into lightsout-updates
Browse files Browse the repository at this point in the history
# Conflicts:
#	pyproject.toml
#	uv.lock
  • Loading branch information
lucasberent committed Nov 19, 2024
2 parents fa725d4 + b53722d commit 98a209a
Show file tree
Hide file tree
Showing 156 changed files with 3,020 additions and 216 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
path: dist
merge-multiple: true
- name: Generate artifact attestation for sdist and wheel(s)
uses: actions/[email protected].3
uses: actions/[email protected].4
with:
subject-path: "dist/*"
- uses: pypa/gh-action-pypi-publish@release/v1
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ repos:

# Python linting and formatting using ruff
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.2
rev: v0.7.3
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand Down Expand Up @@ -87,7 +87,7 @@ repos:

# Check for spelling
- repo: https://github.com/crate-ci/typos
rev: v1.27.0
rev: v1.27.3
hooks:
- id: typos

Expand Down Expand Up @@ -140,6 +140,6 @@ repos:

# Check the pyproject.toml file
- repo: https://github.com/henryiii/validate-pyproject-schema-store
rev: 2024.10.21
rev: 2024.11.11
hooks:
- id: validate-pyproject
156 changes: 154 additions & 2 deletions docs/StatePrep.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,172 @@
"cc_simulator.plot_state_prep(ps, min_errors=50, name=\"Distance 5\")"
]
},
{
"cell_type": "markdown",
"id": "81eec694ef6af97a",
"metadata": {},
"source": [
"## Deterministic state preparation ($d < 5$)\n",
"A possible disadvantage of the above approach is that the verification circuits are non-deterministic. This means that we potentially have to run the circuit multiple times to successfully prepare the state. This can be circumvented by using the information gained from the verification measurements to possibly identify the dangerous error and correct it. If this this is done for every possible (single) error, we refer to the state preparation as deterministic [^1].\n",
"\n",
"For small codes ($d < 5$ i.e. we need to consider only a single error) this problem is still tractable and can be solved in an optimal way using satisfiability solvers. QECC can automatically generate deterministic state preparation circuits for such codes.\n",
"\n",
"[^1]: https://arxiv.org/abs/2301.10017\n",
"\n",
"For this we come back to our $d=3$ Steane code. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2373b4ee6cee29d",
"metadata": {},
"outputs": [],
"source": [
"non_ft_sp.circ.draw(output=\"mpl\", initial_state=True)"
]
},
{
"cell_type": "markdown",
"id": "6c8eecaac4df6b88",
"metadata": {},
"source": [
"And initialize an instance of the deterministic verification helper class to facilitate the generation of the deterministic FT state preparation circuit."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1877841300be6d01",
"metadata": {},
"outputs": [],
"source": [
"from mqt.qecc.ft_stateprep import DeterministicVerificationHelper\n",
"\n",
"det_helper = DeterministicVerificationHelper(non_ft_sp)"
]
},
{
"cell_type": "markdown",
"id": "40c9070837bcd21",
"metadata": {},
"source": [
"Calling the `get_solution` method will generate the non-deterministic verification circuit using either the optimal or the heuristic method discussed above. The deterministic verification circuit, separated into X and Z correction layers) is then generated using the satisfiability solver."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3c83621b4ca7a1a1",
"metadata": {},
"outputs": [],
"source": [
"det_verify = det_helper.get_solution(use_optimal_verification=True)\n",
"det_verify_x, det_verify_z = det_verify"
]
},
{
"cell_type": "markdown",
"id": "15b8f7d65e69be64",
"metadata": {},
"source": [
"Such a `DeterministicVerification` object contains the stabilizer measurements for the non-deterministic verification circuit, the stabilizer measurements for the different deterministic verification circuits, depending on the non-deterministic measurement outcomes, and the final correction Pauli operators that need to be applied to the data qubits.\n",
"\n",
"The non-deterministic verification measurements are stored in the `stabs` attribute as a list of numpy arrays where each array represents a stabilizer measurement.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75ac41577e4c0296",
"metadata": {},
"outputs": [],
"source": [
"det_verify_x.stabs"
]
},
{
"cell_type": "markdown",
"id": "ddecefba679c91c1",
"metadata": {},
"source": [
"The deterministic verification measurements are stored in the `det_stabs` attribute as a dictionary where the keys are the non-deterministic measurement outcomes (converted to int) and the values is a tuple with the first element being the deterministic stabilizer measurements and the second element being again a dictionary with the Pauli corrections for the deterministic measurement outcomes.\n",
"\n",
"For example for the Steane code whenever the non-deterministic verification triggers (1) the logical operator on qubits 2,3,6 hast to measured. If the outcome is 1, a Pauli correction on qubit 3 has to be applied, otherwise no correction is necessary."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "45c29390eb2eb0e4",
"metadata": {},
"outputs": [],
"source": [
"det_verify_x.det_correction"
]
},
{
"cell_type": "markdown",
"id": "42c85a709d72bf40",
"metadata": {},
"source": [
"For the case where the non-deterministic verification measurements need to be flagged (not the case for the Steane code), the `hook_corrections` attribute contains the additional stabilizer measurements and corrections in the same format as the `det_stabs` attribute."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ab975d4c4a1c11b7",
"metadata": {},
"outputs": [],
"source": [
"det_verify_x.hook_corrections"
]
},
{
"cell_type": "markdown",
"id": "d4527b797f83f919",
"metadata": {},
"source": [
"### Simulating deterministic state preparation circuits with Qsample\n",
"The resulting `DeterministicVerification` object can be used to directly simulate the deterministic state preparation circuit using the [Qsample](https://github.com/dpwinter/qsample) under the hood. The `NoisyDFTStatePrepSimulator` class automatically constructs a valid Qsample protocol containing the correct circuits and conditional paths to simulate the deterministic state preparation. The passed Error Model and simulation parameters are directly passed to Qsample and explained in the [Qsample documentation](https://dpwinter.github.io/qsample/). Similarly also the Qsample callbacks can be used to e.g. directly plot the logical error rates, showing the expected quadratic scaling."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "90f4d2760bc20453",
"metadata": {},
"outputs": [],
"source": [
"from qsample import callbacks, noise\n",
"\n",
"from mqt.qecc.ft_stateprep import NoisyDFTStatePrepSimulator\n",
"\n",
"error_model = noise.E1_1 # depolarizing error model\n",
"err_params = {\"q\": [1e-4, 5e-4, 1e-3, 5e-3, 1e-2, 5e-2, 1e-1, 5e-1]}\n",
"shots_dss = 2000\n",
"p_max = {\"q\": 0.01}\n",
"L = 1\n",
"\n",
"qsample_sim = NoisyDFTStatePrepSimulator(non_ft_sp.circ, det_verify, steane_code, error_model)\n",
"sampling_stats = qsample_sim.dss_logical_error_rates(err_params, p_max, L, shots_dss, callbacks=[callbacks.PlotStats()])"
]
},
{
"cell_type": "markdown",
"id": "f9ad305e-929f-470f-86c5-e3e958750539",
"metadata": {},
"source": [
"# Circuits and Evaluations\n",
"\n",
"The circuits and benchmark scripts used for our work https://arxiv.org/abs/2408.11894, can be found [here](https://github.com/cda-tum/mqt-qecc/tree/main/src/mqt/qecc/ft_stateprep/eval)."
"The circuits and benchmark scripts used for our non-deterministic work https://arxiv.org/abs/2408.11894, can be found [here](https://github.com/cda-tum/mqt-qecc/tree/main/scripts/ft_stateprep/eval) and for the deterministic work [here](https://github.com/cda-tum/mqt-qecc/tree/main/scripts/ft_stateprep/eval_det)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "venv3_12",
"language": "python",
"name": "python3"
},
Expand Down
20 changes: 20 additions & 0 deletions docs/library/StatePrep.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,23 @@ State preparation circuits can be simulated using the :class:`NoisyNDFTStatePrep

.. autoclass:: NoisyNDFTStatePrepSimulator
:members:

:math:`d<5` codes
---------------------------------------------------------
For small distance codes QECC provides functionality to not only synthesize state preparation circuits based on post-selection but also preparation protocols that yield the logical Pauli state deterministically.
Such a deterministic protocol consists of three parts: (1) a (non-deterministic) verification, (2) a deterministic correction if one of the verification measurements yields a non-trivial result, and (3) a hook correction for the case that one of the verification measurement flags indicates a hook error.
To facilitate the handling (e.g. collecting statistics regarding ancilla and CNOT count) QECC provides the :class:`DeterministicVerification` class.

.. autoclass:: DeterministicVerification
:members:

The :class:`DeterministicVerification` for a certain :class:`StatePrepCircuit` can be obtained using the wrapper class :class:`DeterministicVerificationHelper` which provides the two functions :func:`get_solution` and :func:`get_global_solution` where the latter optimizes over all possible(*potentially exponentially many*) non-deterministic verifications to find the global optimum (recommended only for codes with small qubit number).
The two :class:`DeterministicVerification` objects returned correspond to the two layers of verification (X and Z errors).

.. autoclass:: DeterministicVerificationHelper
:members:
The resulting protocol consisting of the two-layered verification can be converted to a `Qsample <https://github.com/dpwinter/qsample>`_ protocol and simulated using Dynamic Subset Sampling :cite:labelpar:`heussenDynamicalSubsetSampling2024`.
The protocol construction and simulation is done automatically by the :class:`NoisyDFTStatePrepSimulator` class where the returned numbers correspond to the upper and lower bounds with corresponding errors as described at the `Qsample Documentation <https://dpwinter.github.io/qsample/>`_.

.. autoclass:: NoisyDFTStatePrepSimulator
:members:
13 changes: 13 additions & 0 deletions docs/refs.bib
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,16 @@ @article{pryadko2023qdistrnd
journal={arXiv preprint arXiv:2308.15140},
year={2023}
}

@article{heussenDynamicalSubsetSampling2024,
title = {Dynamical Subset Sampling of Quantum Error-Correcting Protocols},
author = {Heu{\ss}en, Sascha and Winter, Don and Rispler, Manuel and M{\"u}ller, Markus},
year = {2024},
month = feb,
journal = {Physical Review Research},
volume = {6},
number = {1},
pages = {013177},
publisher = {American Physical Society},
doi = {10.1103/PhysRevResearch.6.013177},
}
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ dependencies = [
"numba>=0.59; python_version > '3.11'",
"numba>=0.57; python_version <= '3.11'",
"pymatching>=2.2.1",
"qsample>=0.0.2",
"urllib3>=1.26.20,<2.0", # Required by qsample
"fastcore>=1.7.10" # Required by qsample (to be removed)
]
dynamic = ["version"]

Expand Down Expand Up @@ -158,6 +161,10 @@ filterwarnings = [
"ignore:.*pkg_resources.*:DeprecationWarning:",
"ignore:.*The retworkx package is deprecated*:DeprecationWarning:pymatching",
'ignore:.*qiskit.providers.provider.Provider.*:DeprecationWarning:',
'ignore::DeprecationWarning:.*(simpleeval).*',
'ignore::RuntimeWarning:.*(qsample).*',
'ignore:.*invalid escape sequence.*::.*qsample.*',
'ignore:.*invalid escape sequence.*::.*latextools.*',
]

[tool.coverage]
Expand Down Expand Up @@ -186,7 +193,7 @@ exclude = [

[[tool.mypy.overrides]]
module = ["qiskit.*", "qecsim.*", "qiskit_aer.*", "matplotlib.*", "scipy.*", "ldpc.*", "pytest_console_scripts.*",
"z3.*", "bposd.*", "numba.*", "pymatching.*", "stim.*", "multiprocess.*", "sinter.*"]
"z3.*", "bposd.*", "numba.*", "pymatching.*", "stim.*", "multiprocess.*", "sinter.*", "qsample.*", "pandas.*"]
ignore_missing_imports = true


Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def main() -> None:
qc, code=code, p=args.p_error, zero_state=args.zero_state, parallel_gates=not args.no_parallel_gates
)
res = sim.logical_error_rate(min_errors=args.n_errors)
print(",".join([str(x) for x in res])) # noqa: T201
print(",".join([str(x) for x in res]))


if __name__ == "__main__":
Expand Down
23 changes: 23 additions & 0 deletions scripts/ft_stateprep/eval_det/circuits/11_1_3/zero_heuristic.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
OPENQASM 2.0;
include "qelib1.inc";
qreg q[11];
h q[0];
h q[1];
h q[2];
h q[3];
h q[4];
cx q[4],q[9];
cx q[4],q[7];
cx q[3],q[5];
cx q[4],q[10];
cx q[2],q[9];
cx q[1],q[7];
cx q[0],q[5];
cx q[3],q[6];
cx q[1],q[10];
cx q[9],q[5];
cx q[7],q[8];
cx q[1],q[9];
cx q[0],q[7];
cx q[10],q[6];
cx q[5],q[8];
33 changes: 33 additions & 0 deletions scripts/ft_stateprep/eval_det/circuits/16_2_4/zero_heuristic.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
OPENQASM 2.0;
include "qelib1.inc";
qreg q[16];
h q[0];
h q[1];
h q[2];
h q[3];
h q[4];
h q[5];
h q[6];
cx q[5],q[12];
cx q[4],q[12];
cx q[2],q[10];
cx q[6],q[7];
cx q[5],q[8];
cx q[3],q[11];
cx q[1],q[9];
cx q[0],q[10];
cx q[12],q[13];
cx q[6],q[11];
cx q[4],q[7];
cx q[3],q[8];
cx q[13],q[14];
cx q[12],q[9];
cx q[10],q[15];
cx q[6],q[12];
cx q[5],q[11];
cx q[4],q[8];
cx q[3],q[7];
cx q[2],q[13];
cx q[1],q[15];
cx q[0],q[14];
cx q[9],q[10];
27 changes: 27 additions & 0 deletions scripts/ft_stateprep/eval_det/circuits/carbon/zero_heuristic.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
OPENQASM 2.0;
include "qelib1.inc";
qreg q[12];
h q[0];
h q[1];
h q[2];
h q[4];
h q[7];
cx q[7],q[11];
cx q[1],q[5];
cx q[7],q[9];
cx q[4],q[10];
cx q[2],q[8];
cx q[1],q[3];
cx q[0],q[6];
cx q[10],q[9];
cx q[8],q[7];
cx q[6],q[11];
cx q[4],q[3];
cx q[2],q[1];
cx q[0],q[5];
cx q[11],q[10];
cx q[9],q[8];
cx q[7],q[6];
cx q[5],q[4];
cx q[3],q[2];
cx q[1],q[0];
Loading

0 comments on commit 98a209a

Please sign in to comment.