Skip to content

Commit 716b21b

Browse files
authored
🚸 Python Bindings for NA State Preparation (#556)
## Description This PR aims to provide python bindings for the state preparation for neutral atoms part of qmap. ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [x] The pull request only contains commits that are related to it. - [x] I have added appropriate tests and documentation. - [x] I have made sure that all CI jobs on GitHub pass. - [x] The pull request introduces no new warnings and follows the project's style guidelines.
2 parents f131dc4 + e7abb4b commit 716b21b

22 files changed

+702
-70
lines changed

docs/DevelopmentGuide.rst

Lines changed: 25 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -179,27 +179,23 @@ Furthermore, they provide a command to automatically format your code according
179179
Working on the Python module
180180
############################
181181

182-
`Pybind11 <https://pybind11.readthedocs.io/>`_ is used for providing bindings of the C++ core library to Python.
182+
`Pybind11 <https://pybind11.readthedocs.io/en/stable/>`_ is used for providing bindings of the C++ core library to Python.
183183
This allows to keep the performance critical parts of the code in C++ while providing a convenient interface for Python users.
184-
All of the bindings code as well as the Python module itself is contained in the :code:`mqt/qmap` directory.
184+
All of the bindings code is contained in the :code:`src/python` directory.
185+
The Python package itself lives in the :code:`src/mqt/qmap` directory.
185186

186187
Building the Python module
187188
--------------------------
188189

189-
The recommended way of building the Python module is to perform an editable install using `pip <https://pip.pypa.io/en/stable/>`_.
190+
It is usually most efficient to install the build dependencies in your environment once and use the following command that avoids a costly creation of a new virtual environment at every compilation:
190191

191192
.. code-block:: console
192193
193-
(venv) $ pip install --editable .[dev]
194+
(venv) $ pip install 'scikit-build-core[pyproject]' setuptools_scm pybind11
195+
(venv) $ pip install --no-build-isolation -ve ".[dev]"
194196
195-
The :code:`--editable` flag ensures that changes in the Python code are instantly available without re-running the command.
196-
The :code:`[dev]` extra makes sure that all dependencies for running the Python tests and building the documentation are available.
197-
198-
.. note::
199-
When using the :code:`zsh` shell it might be necessary to add double quotes around the :code:`.[dev]` part of the command.
200-
201-
.. warning::
202-
Do not forget to run the above command again after any changes to the C++ core library or bindings to make the changes available in the Python module.
197+
You may optionally add :code:`-Ceditable.rebuild=true` to auto-rebuild when the package is imported.
198+
Otherwise, you need to re-run the above after editing C++ files.
203199

204200
Running Python Tests
205201
--------------------
@@ -210,15 +206,9 @@ A :code:`nox` session is provided to conveniently run the Python tests.
210206

211207
.. code-block:: console
212208
213-
(venv) $ nox -rs tests
209+
(venv) $ nox -s tests
214210
215211
This installs all dependencies for running the tests in an isolated environment, builds the Python package, and then runs the tests.
216-
The :code:`-r` flag ensures that the environment is reused for subsequent runs.
217-
To speed up subsequent runs, the installation step can be skipped by adding the :code:`skip-install` flag.
218-
219-
.. code-block:: console
220-
221-
(venv) $ nox -rs tests -- skip-install
222212

223213
.. note::
224214
If you don't want to use :code:`nox`, you can also run the tests directly using :code:`pytest`.
@@ -233,36 +223,33 @@ Python Code Formatting and Linting
233223
The Python code is formatted and linted using a collection of `pre-commit hooks <https://pre-commit.com/>`_.
234224
This collection includes:
235225

236-
- `black <https://black.readthedocs.io/en/stable/>`_ -- a code formatter that automatically formats Python code according to the `PEP 8 style guide <https://www.python.org/dev/peps/pep-0008/>`_
237-
- `flake8 <https://flake8.pycqa.org/en/latest/>`_ -- a linter that checks for common mistakes in Python code
238-
- `isort <https://pycqa.github.io/isort/>`_ -- a tool that automatically sorts Python imports according to the `PEP 8 style guide <https://www.python.org/dev/peps/pep-0008/>`_
239-
- `mypy <http://mypy-lang.org/>`_ -- a static type checker for Python code
240-
- `pyupgrade <https://github.com/asottile/pyupgrade>`_ -- a tool that automatically upgrades Python syntax to a newer version
226+
- `ruff <https://docs.astral.sh/ruff/>`_ -- an extremely fast Python linter and formatter, written in Rust.
227+
- `mypy <https://mypy-lang.org/>`_ -- a static type checker for Python code
241228

242229
There are two ways of using these hooks:
243230

244-
- You can install the hooks manually by running :code:`pre-commit install` in the project root directory.
231+
- You can install the hooks manually by running
232+
233+
.. code-block:: console
234+
235+
(venv) $ pre-commit install
236+
237+
in the project root directory.
245238
This will install the hooks in the :code:`.git/hooks` directory of the repository.
246239
The hooks will then be executed automatically when committing changes.
240+
247241
- You can use the :code:`nox` session :code:`lint` to run the hooks manually.
248242

249243
.. code-block:: console
250244
251-
(venv) $ nox -rs lint
245+
(venv) $ nox -s lint
252246
253247
.. note::
254248
If you don't want to use :code:`nox`, you can also run the hooks directly using :code:`pre-commit`.
255249

256-
.. code-block:: console
257-
258-
(venv) $ pre-commit run --all-files
259-
260-
In addition to the pre-commit hooks, the Python code is also type checked by `mypy <http://mypy-lang.org/>`_.
261-
This is done by the :code:`nox` session :code:`mypy`.
262-
263250
.. code-block:: console
264251
265-
(venv) $ nox -rs mypy
252+
(venv) $ pre-commit run --all-files
266253
267254
Working on the Documentation
268255
############################
@@ -273,31 +260,19 @@ You can build the documentation using the :code:`nox` session :code:`docs`.
273260

274261
.. code-block:: console
275262
276-
(venv) $ nox -rs docs
263+
(venv) $ nox -s docs
277264
278265
.. note::
279266
In order to properly build the jupyter notebooks in the documentation, you need to have :code:`pandoc` installed. See `the pandoc documentation <https://pandoc.org/installing.html>`_ for installation instructions.
280267

281268
This will install all dependencies for building the documentation in an isolated environment, build the Python package, and then build the documentation.
282-
The session also provides a convenient option to automatically serve the docs on a local web server. Running
283-
284-
.. code-block:: console
285-
286-
(venv) $ nox -rs docs -- serve
287-
288-
will start a local web server on port 8000 and provide a link to open the documentation in your browser.
289-
290-
To build the documentation without (re-)installing the Python package, you can use the :code:`skip-install` flag.
291-
292-
.. code-block:: console
293-
294-
(venv) $ nox -rs docs -- skip-install
269+
Additionally, the session will automatically serve the docs on a local web server.
295270

296271
.. note::
297272
If you don't want to use :code:`nox`, you can also build the documentation directly using :code:`sphinx-build`.
298273

299274
.. code-block:: console
300275
301-
(venv) $ sphinx-build -b html docs/source docs/build
276+
(venv) $ sphinx-build -b html docs/ docs/_build
302277
303-
The docs can then be found in the :code:`docs/build` directory.
278+
The docs can then be found in the :code:`docs/_build` directory.

docs/NAStatePrep.ipynb

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"<style>.widget-subarea{display:none;} /*hide widgets as they do not work with sphinx*/</style>\n",
8+
"\n",
9+
"# Neutral Atom Logical State Preparation\n",
10+
"\n",
11+
"All quantum computers are prone to errors.\n",
12+
"This is the motivation of employing error correction during a quantum computation.\n",
13+
"To this end, a (logical) qubit on the algorithmic level is encoded into a shared and highly entangled state of multiple physical qubits.\n",
14+
"Before the actual computation can start, those physical qubits need to be prepared in a state that represents the logical zero state.\n",
15+
"\n",
16+
"For that, we provide tool that takes a state preparation circuit and generates an optimal sequence of operations tailored to the zoned neutral atom architecture.\n",
17+
"Thereby, the circuit consists of one initial layer of Hadamard gates on all qubits that initialize the physical qubits in the plus state.\n",
18+
"Those are followed by a set of entangling (CZ) gates that generate a so-called graph state.\n",
19+
"The final logical state is achieved by applying additional Hadamard gates on selected qubits.\n",
20+
"\n",
21+
"Below we demonstrate how the optimal schedule can be retrieved for the Steane-code, the smallest 2D color code.\n",
22+
"First, we create the state preparation circuit for the Steane-code as a `qiskit.QuantumCircuit`."
23+
]
24+
},
25+
{
26+
"cell_type": "code",
27+
"execution_count": null,
28+
"metadata": {},
29+
"outputs": [],
30+
"source": [
31+
"from qiskit import QuantumCircuit\n",
32+
"\n",
33+
"qc = QuantumCircuit(7)\n",
34+
"qc.h(range(7))\n",
35+
"qc.cz(0, 3)\n",
36+
"qc.cz(0, 4)\n",
37+
"qc.cz(1, 2)\n",
38+
"qc.cz(1, 5)\n",
39+
"qc.cz(1, 6)\n",
40+
"qc.cz(2, 3)\n",
41+
"qc.cz(2, 4)\n",
42+
"qc.cz(3, 5)\n",
43+
"qc.cz(4, 6)\n",
44+
"qc.h(0)\n",
45+
"qc.h(2)\n",
46+
"qc.h(5)\n",
47+
"qc.h(6)\n",
48+
"\n",
49+
"qc.draw(output=\"mpl\")"
50+
]
51+
},
52+
{
53+
"cell_type": "markdown",
54+
"metadata": {},
55+
"source": [
56+
"We solve the problem of optimal state preparation with an SMT solver (Z3).\n",
57+
"Therefore, we encode the problem into an SMT-model.\n",
58+
"To construct the SMT model, the solver takes the entangling operations (CZ) as a list of qubit pairs."
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": null,
64+
"metadata": {},
65+
"outputs": [],
66+
"source": [
67+
"from mqt.qmap.na import get_ops_for_solver\n",
68+
"\n",
69+
"ops = get_ops_for_solver(qc, \"z\", 1) # We extract the 'Z' gates with '1' control, i.e., CZ gates\n",
70+
"ops"
71+
]
72+
},
73+
{
74+
"cell_type": "markdown",
75+
"metadata": {},
76+
"source": [
77+
"Now, we are ready to initialize the solver and to generate the optimal sequence of operations.\n",
78+
"The parameters of the solver describe an architecture with two storage zones with each two rows, one zone above the entangling zone and one below.\n",
79+
"The entangling zone itself consists of three rows and the architecture model has three columns.\n",
80+
"Within each interaction site, atoms can be offset by two sites in every direction.\n",
81+
"The considered architecture offers two AOD columns and three AOD rows.\n",
82+
"\n",
83+
"We instruct the solver to generate a sequence consisting of four stages.\n",
84+
"Thereby, we do not fix the number of transfer stages.\n",
85+
"The last two boolean arguments, specify that the solver needs not to maintain the order of operations and must shield idling qubits in the storage zone.\n",
86+
"For further details on the employed abstraction of the 2D plane in the solver, please refer to the corresponding article :cite:labelpar:`stadeOptimalStatePreparation2024`."
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": null,
92+
"metadata": {},
93+
"outputs": [],
94+
"source": [
95+
"from mqt.qmap.na import NAStatePreparationSolver\n",
96+
"\n",
97+
"solver = NAStatePreparationSolver(3, 7, 2, 3, 2, 2, 2, 2, 2, 4)\n",
98+
"result = solver.solve(ops, 7, 4, None, False, True)"
99+
]
100+
},
101+
{
102+
"cell_type": "markdown",
103+
"metadata": {},
104+
"source": [
105+
"To inspect the result, it can be exported to the human-readable YAML format by invoking the method `result.yaml()`\n",
106+
"In this example, we take another approach and generate code from the result.\n",
107+
"For that, we call the function `generate_code` with the respective arguments."
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": null,
113+
"metadata": {},
114+
"outputs": [],
115+
"source": [
116+
"from mqt.qmap.na import generate_code\n",
117+
"\n",
118+
"code = generate_code(qc, result)\n",
119+
"print(code)"
120+
]
121+
},
122+
{
123+
"cell_type": "markdown",
124+
"metadata": {},
125+
"source": [
126+
"For further details, please refer to the [reference documentation](library/NAStatePrep.rst)."
127+
]
128+
}
129+
],
130+
"metadata": {
131+
"kernelspec": {
132+
"display_name": "Python 3 (ipykernel)",
133+
"language": "python",
134+
"name": "python3"
135+
},
136+
"language_info": {
137+
"codemirror_mode": {
138+
"name": "ipython",
139+
"version": 3
140+
},
141+
"file_extension": ".py",
142+
"mimetype": "text/x-python",
143+
"name": "python",
144+
"nbconvert_exporter": "python",
145+
"pygments_lexer": "ipython3"
146+
}
147+
},
148+
"nbformat": 4,
149+
"nbformat_minor": 1
150+
}

docs/Publications.rst

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,42 @@ Publications
33

44
*QMAP* is academic software. Thus, many of its built-in algorithms have been published as scientific papers.
55
See :cite:labelpar:`wille2023qmap` for a general overview of *QMAP* and its features.
6+
If you want to cite this article, please use the following BibTeX entry:
7+
8+
.. code-block:: bibtex
9+
10+
@inproceedings{qmap,
11+
title = {{QMAP: A Quantum Circuit Mapping Tool}},
12+
booktitle = {International Symp. on Physical Design},
13+
author = {Wille, Robert and Burgholzer, Lukas},
14+
year = {2023}
15+
}
16+
17+
*QMAP* is part of the Munich Quantum Toolkit, which is described in :cite:labelpar:`willeMQTHandbookSummary2024`.
18+
If you want cite the Munich Quantum Toolkit, please use the following BibTeX entry:
19+
20+
.. code-block:: bibtex
21+
22+
@inproceedings{mqt,
23+
title = {The {{MQT}} Handbook: {{A}} Summary of Design Automation Tools and Software for Quantum Computing},
24+
shorttitle = {{The MQT Handbook}},
25+
booktitle = {IEEE International Conference on Quantum Software (QSW)},
26+
author = {Wille, Robert and Berent, Lucas and Forster, Tobias and Kunasaikaran, Jagatheesan and Mato, Kevin and Peham, Tom and Quetschlich, Nils and Rovara, Damian and Sander, Aaron and Schmid, Ludwig and Schoenberger, Daniel and Stade, Yannick and Burgholzer, Lukas},
27+
date = {2024},
28+
doi = {10.1109/QSW62656.2024.00013},
29+
eprint = {2405.17543},
30+
eprinttype = {arxiv},
31+
addendum = {A live version of this document is available at \url{https://mqt.readthedocs.io}}
32+
}
633
734
If you use *QMAP* in your work, we would appreciate if you cited
835

936
- :cite:labelpar:`zulehnerEfficientMethodologyMapping2019` when using the heuristic mapper,
1037
- :cite:labelpar:`willeMappingQuantumCircuits2019` when using the exact mapper,
11-
- :cite:labelpar:`peham2023DepthOptimalSynthesis` when using the Clifford circuit synthesis approach, and
12-
- :cite:labelpar:`schmid2024HybridCircuitMapping` when using the hybrid mapper for neutral atom quantum computers.
38+
- :cite:labelpar:`peham2023DepthOptimalSynthesis` when using the Clifford circuit synthesis approach,
39+
- :cite:labelpar:`schmid2024HybridCircuitMapping` when using the hybrid mapper for neutral atom quantum computers,
40+
- :cite:labelpar:`stadeAbstractModelEfficient2024` when using the neutral atom logical array compiler (NALAC), and
41+
- :cite:labelpar:`stadeOptimalStatePreparation2024` when using the optimal state preparation for neutral atoms (NASP).
1342

1443
Furthermore, if you use any of the particular algorithms such as
1544

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ We appreciate any feedback and contributions to the project. If you want to cont
2424
Installation
2525
Mapping
2626
Synthesis
27+
NAStatePrep
2728
Publications
2829

2930
.. toctree::

docs/library/Library.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ Library
1111
Synthesis
1212
SynthesisResults
1313
Visualization
14+
NAStatePrep

docs/library/NAStatePrep.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Neutral Atom Logical State Preparation
2+
======================================
3+
4+
This module provides functionality to generate an optimal operation sequence for zoned neutral atom architectures.
5+
The input must be a circuit of single-qubit gates, followed by a set of entangling gates (CZ) and finally single-qubit gates on selected qubits.
6+
Those circuits arise in the realm of error correction when the initial logical state must be prepared.
7+
8+
The process is divided into three steps:
9+
1. Extract a list of qubit pairs from the circuit that represents the entangling gates with :code:`get_ops_for_solver`
10+
11+
.. currentmodule:: mqt.qmap.na
12+
.. autofunction:: get_ops_for_solver
13+
14+
2. Supply the list of entangling operations to the solver and generate the optimal operation sequence with the :code:`NAStatePreparationSolver`.
15+
For further details on the employed abstraction of the 2D plane in the solver, please refer to the corresponding article :cite:labelpar:`stadeOptimalStatePreparation2024`.
16+
17+
.. currentmodule:: mqt.qmap.na
18+
.. autoclass:: NAStatePreparationSolver
19+
20+
3. Generate code from the solver's result with :code:`generate_code`
21+
22+
.. currentmodule:: mqt.qmap.na
23+
.. autofunction:: generate_code

0 commit comments

Comments
 (0)