@@ -118,14 +156,20 @@ circ.h(1)
circ_opt, results = optimize_clifford(circ)
```
-**Detailed documentation and examples are available at [ReadTheDocs](https://mqt.readthedocs.io/projects/qmap).**
+**Detailed documentation and examples are available at
+[ReadTheDocs](https://mqt.readthedocs.io/projects/qmap).**
## System Requirements and Building
-Building the project requires a C++ compiler with support for C++20 and CMake 3.24 or newer.
-For details on how to build the project, please refer to the [documentation](https://mqt.readthedocs.io/projects/qmap).
-Building (and running) is continuously tested under Linux, macOS, and Windows using the [latest available system versions for GitHub Actions](https://github.com/actions/runner-images).
-MQT QMAP is compatible with all [officially supported Python versions](https://devguide.python.org/versions/).
+Building the project requires a C++ compiler with support for C++20
+and CMake 3.24 or newer.
+For details on how to build the project,
+please refer to the [documentation](https://mqt.readthedocs.io/projects/qmap).
+Building (and running) is continuously tested under Linux, macOS,
+and Windows using the
+[latest available system versions for GitHub Actions](https://github.com/actions/runner-images).
+MQT QMAP is compatible with all
+[officially supported Python versions](https://devguide.python.org/versions/).
## Cite This
@@ -133,7 +177,8 @@ Please cite the work that best fits your use case.
### MQT QMAP (the tool)
-When citing the software itself or results produced with it, cite the MQT QMAP paper:
+When citing the software itself or results produced with it,
+cite the MQT QMAP paper:
```bibtex
@inproceedings{wille2023qmap,
@@ -165,65 +210,95 @@ When discussing the overall MQT project or its ecosystem, cite the MQT Handbook:
### Peer-Reviewed Research
-When citing the underlying methods and research, please reference the most relevant peer-reviewed publications from the list below:
+When citing the underlying methods and research,
+please reference the most relevant peer-reviewed publications from the list
+below:
[[1]](https://www.cda.cit.tum.de/files/eda/2023_ispd_mqt_qmap_efficient_quantum_circuit_mapping.pdf)
-R. Wille and L. Burgholzer. MQT QMAP: Efficient Quantum Circuit Mapping.
+R. Wille and L. Burgholzer.
+MQT QMAP: Efficient Quantum Circuit Mapping.
In _International Symposium on Physical Design (ISPD)_, 2023.
[[2]](https://www.cda.cit.tum.de/files/eda/2018_tcad_efficient_mapping_of_quantum_circuits_to_ibm_qx_architectures.pdf)
-A. Zulehner, A. Paler, and R. Wille. An Efficient Methodology for Mapping Quantum Circuits to the IBM QX Architectures.
-_IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems (TCAD)_, 2018.
+A. Zulehner, A. Paler, and R. Wille.
+An Efficient Methodology
+for Mapping Quantum Circuits to the IBM QX Architectures.
+_IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems
+(TCAD)_, 2018.
[[3]](https://www.cda.cit.tum.de/files/eda/2019_dac_mapping_quantum_circuits_ibm_architectures_using_minimal_number_swap_h_gates.pdf)
-R. Wille, L. Burgholzer, and A. Zulehner. Mapping Quantum Circuits to IBM QX Architectures Using the Minimal Number of SWAP and H Operations.
+R. Wille, L. Burgholzer, and A. Zulehner.
+Mapping Quantum Circuits to IBM QX Architectures Using the Minimal Number of
+SWAP and H Operations.
In _Design Automation Conference (DAC)_, 2019.
[[4]](https://www.cda.cit.tum.de/files/eda/2021_aspdac_exploiting_teleportation_in_quantum_circuit_mappping.pdf)
-S. Hillmich, A. Zulehner, and R. Wille. Exploiting Quantum Teleportation in Quantum Circuit Mapping.
+S. Hillmich, A. Zulehner, and R. Wille.
+Exploiting Quantum Teleportation in Quantum Circuit Mapping.
In _Asia and South Pacific Design Automation Conference (ASP-DAC)_, 2021.
[[5]](https://www.cda.cit.tum.de/files/eda/2022_aspdac_limiting_search_space_optimal_quantum_circuit_mapping.pdf)
-L. Burgholzer, S. Schneider, and R. Wille. Limiting the Search Space in Optimal Quantum Circuit Mapping.
+L. Burgholzer, S. Schneider, and R. Wille.
+Limiting the Search Space in Optimal Quantum Circuit Mapping.
In _Asia and South Pacific Design Automation Conference (ASP-DAC)_, 2022.
-[[6]](https://arxiv.org/pdf/2210.09321.pdf)
-T. Peham, L. Burgholzer, and R. Wille. On Optimal Subarchitectures for Quantum Circuit Mapping.
+[[6]](https://arxiv.org/pdf/2210.09321.pdf) T. Peham, L. Burgholzer,
+and R. Wille.
+On Optimal Subarchitectures for Quantum Circuit Mapping.
_ACM Transactions on Quantum Computing (TQC)_, 2023.
-[[7]](https://arxiv.org/pdf/2208.11713.pdf)
-S. Schneider, L. Burgholzer, and R. Wille. A SAT Encoding for Optimal Clifford Circuit Synthesis.
+[[7]](https://arxiv.org/pdf/2208.11713.pdf) S. Schneider, L. Burgholzer,
+and R. Wille.
+A SAT Encoding for Optimal Clifford Circuit Synthesis.
In _Asia and South Pacific Design Automation Conference (ASP-DAC)_, 2023.
-[[8]](https://arxiv.org/pdf/2305.01674.pdf)
-T. Peham, N. Brandl, R. Kueng, R. Wille, and L. Burgholzer. Depth-Optimal Synthesis of Clifford Circuits with SAT Solvers.
-In _IEEE International Conference on Quantum Computing and Engineering (QCE)_, 2023.
-
-[[9]](https://arxiv.org/pdf/2309.08656.pdf)
-L. Schmid, D. F. Locher, M. Rispler, S. Blatt, J. Zeiher, M. Müller, and R. Wille. Computational Capabilities and Compiler Development for Neutral Atom Quantum Processors: Connecting Tool Developers and Hardware Experts.
+[[8]](https://arxiv.org/pdf/2305.01674.pdf) T. Peham, N. Brandl, R. Kueng,
+R. Wille, and L. Burgholzer.
+Depth-Optimal Synthesis of Clifford Circuits with SAT Solvers.
+In _IEEE International Conference on Quantum Computing and Engineering (QCE)_,
+2023.
+
+[[9]](https://arxiv.org/pdf/2309.08656.pdf) L. Schmid, D. F. Locher, M. Rispler,
+S. Blatt, J. Zeiher, M. Müller, and R. Wille.
+Computational Capabilities and Compiler Development
+for Neutral Atom Quantum Processors:
+Connecting Tool Developers and Hardware Experts.
_Quantum Science and Technology_, 2024.
-[[10]](https://arxiv.org/pdf/2311.14164.pdf)
-L. Schmid, S. Park, S. Kang, and R. Wille. Hybrid Circuit Mapping: Leveraging the Full Spectrum of Computational Capabilities of Neutral Atom Quantum Computers.
+[[10]](https://arxiv.org/pdf/2311.14164.pdf) L. Schmid, S. Park, S. Kang,
+and R. Wille.
+Hybrid Circuit Mapping: Leveraging the Full Spectrum of Computational
+Capabilities of Neutral Atom Quantum Computers.
In _Design Automation Conference (DAC)_, 2024.
[[11]](https://www.cda.cit.tum.de/files/eda/2024_qce_an_abstract_model_and_efficient_routing_for_logical_entangling_gates_on_Zoned_neutral_atom_architectures.pdf)
-Y. Stade, L. Schmid, L. Burgholzer, and R. Wille. An Abstract Model and Efficient Routing for Logical Entangling Gates on Zoned Neutral Atom Architectures.
+Y. Stade, L. Schmid, L. Burgholzer, and R. Wille.
+An Abstract Model and Efficient Routing
+for Logical Entangling Gates on Zoned Neutral Atom Architectures.
In _Int'l Conf. on Quantum Computing and Engineering_, 2024.
[[12]](https://www.cda.cit.tum.de/files/eda/2025_date_optimal_state_preparation_for_logical_arrays_on_zoned_neutral_atom_quantum_computers.pdf)
-Y. Stade, L. Schmid, L. Burgholzer, and R. Wille. Optimal State Preparation for Logical Arrays on Zoned Neutral Atom Quantum Computers.
+Y. Stade, L. Schmid, L. Burgholzer, and R. Wille.
+Optimal State Preparation
+for Logical Arrays on Zoned Neutral Atom Quantum Computers.
In _Design, Automation and Test in Europe_, 2024.
[[13]](https://www.cda.cit.tum.de/files/eda/2025_iccad_routing-aware_placement_zoned_neutral_atom.pdf)
-Y. Stade, W.-H. Lin, J. Cong, and R. Wille. Routing-Aware Placement for Zoned Neutral Atom-based Quantum Computing.
+Y. Stade, W.-H.
+Lin, J. Cong, and R. Wille.
+Routing-Aware Placement for Zoned Neutral Atom-based Quantum Computing.
In _Int'l Conference on CAD_, 2025.
---
## Acknowledgements
-The Munich Quantum Toolkit has been supported by the European Research Council (ERC) under the European Union's Horizon 2020 research and innovation program (grant agreement No. 101001318), the Bavarian State Ministry for Science and Arts through the Distinguished Professorship Program, as well as the Munich Quantum Valley, which is supported by the Bavarian state government with funds from the Hightech Agenda Bayern Plus.
+The Munich Quantum Toolkit has been supported by the European Research Council
+(ERC) under the European Union's Horizon 2020 research and innovation program
+(grant agreement No. 101001318), the Bavarian State Ministry for Science and
+Arts through the Distinguished Professorship Program, as well as the Munich
+Quantum Valley, which is supported by the Bavarian state government with funds
+from the Hightech Agenda Bayern Plus.
diff --git a/UPGRADING.md b/UPGRADING.md
index 1fc37ccab..a4fb9475a 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -1,17 +1,22 @@
# Upgrade Guide
-This document describes breaking changes and how to upgrade. For a complete list of changes including minor and patch releases, please refer to the [changelog](CHANGELOG.md).
+This document describes breaking changes and how to upgrade.
+For a complete list of changes including minor and patch releases,
+please refer to the [changelog](CHANGELOG.md).
## [Unreleased]
-This release also updates the minimum required `mqt-core` version to `v3.6.0` as well as the `nanobind` version to `v2.12.0`.
+This release also updates the minimum required `mqt-core` version to `v3.6.0`
+as well as the `nanobind` version to `v2.12.0`.
### CMake presets
-[CMake presets] have been added to provide a standardized and reproducible way to configure builds across different platforms.
+[CMake presets] have been added to provide a standardized
+and reproducible way to configure builds across different platforms.
These presets are also used in our CI.
-On Unix systems, the `debug`, `release`, and `coverage` presets can be used to configure, build, and test MQT QMAP.
+On Unix systems, the `debug`, `release`,
+and `coverage` presets can be used to configure, build, and test MQT QMAP.
```console
cmake --preset release
@@ -19,7 +24,8 @@ cmake --build --preset release
ctest --preset release
```
-Additionally, the `lint` preset can be used to configure and build MQT QMAP in preparation for a `clang-tidy` run.
+Additionally, the `lint` preset can be used to configure
+and build MQT QMAP in preparation for a `clang-tidy` run.
If you are on Windows, use the `debug-windows` and `release-windows` presets.
@@ -27,7 +33,8 @@ If you are on Windows, use the `debug-windows` and `release-windows` presets.
### Renamings
-To comply with established guidelines for function and attribute names, this release includes the following renamings:
+To comply with established guidelines for function and attribute names,
+this release includes the following renamings:
- `mqt.qmap.plugins.qiskit.sc.compile` has been renamed to `compile_`.
- `mqt.qmap.sc.map` has been renamed to `map_`.
@@ -36,7 +43,8 @@ To comply with established guidelines for function and attribute names, this rel
### Stable ABI wheels
-We are now providing Stable ABI wheels instead of separate version-specific wheels for Python 3.12+.
+We are now providing Stable ABI wheels instead of separate version-specific
+wheels for Python 3.12+.
This was enabled by migrating our Python bindings from `pybind11` to `nanobind`.
The full list of wheels now reads:
@@ -48,28 +56,44 @@ The full list of wheels now reads:
## [3.5.0]
-As part of this release, the scheduler of the zoned neutral atom compiler now features a new parameter `max_filling_factor`.
-It allows limiting the maximum number of parallel entangling gates relative to the maximum capacity of the entangling zone.
+As part of this release,
+the scheduler of the zoned neutral atom compiler now features a new parameter
+`max_filling_factor`.
+It allows limiting the maximum number of parallel entangling gates relative to
+the maximum capacity of the entangling zone.
Note, the default is set to `0.9`.
-The code generator of the zoned neutral atom compiler is updated to also handle routings that only satisfy relaxed routing constraints.
-In contrast to the strict routing, a relaxed routing can change the relative order of atoms.
-The constraint that remains is that atoms previously in one row (column) must remain in the same row (column) after the routing.
+The code generator of the zoned neutral atom compiler is updated to also handle
+routings that only satisfy relaxed routing constraints.
+In contrast to the strict routing,
+a relaxed routing can change the relative order of atoms.
+The constraint that remains is
+that atoms previously in one row (column) must remain in the same row (column)
+after the routing.
-Additionally, we also introduce an extension to the Hybrid Neutral Atom Mapper (HyRoNA), which unifies gate-based routing (SWAP/BRIDGE) with atom shuttling, pass-by, and an optional flying ancilla to find the most suitable routing.
+Additionally, we also introduce an extension to the Hybrid Neutral Atom Mapper
+(HyRoNA), which unifies gate-based routing (SWAP/BRIDGE) with atom shuttling,
+pass-by, and an optional flying ancilla to find the most suitable routing.
Existing workflows should continue to function.
-The optionally new parameters are `usePassBy=False`, `numFlyingAncillas=0`, and `maxBridgeDistance=0` which can all be disabled with the above values to recover the previous behavior.
-Enabling/increasing the corresponding parameters allows enabling individually single routing strategies.
+The optionally new parameters are `usePassBy=False`, `numFlyingAncillas=0`,
+and `maxBridgeDistance=0`
+which can all be disabled with the above values to recover the previous
+behavior.
+Enabling/increasing the corresponding parameters allows enabling individually
+single routing strategies.
-The hybrid mapper now also optionally yields a `.naviz` output which can be handled similarly to the zoned architecture compiler.
+The hybrid mapper now also optionally yields a `.naviz` output
+which can be handled similarly to the zoned architecture compiler.
### Removal of Python 3.13t wheels
Free-threading Python was introduced as an experimental feature in Python 3.13.
It became stable in Python 3.14.
-To conserve space on PyPI and to reduce the CI/CD build times, we have removed all wheels for Python 3.13t.
-We continue to provide wheels for the regular Python versions 3.10 to 3.14, as well as 3.14t.
+To conserve space on PyPI and to reduce the CI/CD build times,
+we have removed all wheels for Python 3.13t.
+We continue to provide wheels for the regular Python versions 3.10 to 3.14,
+as well as 3.14t.
## [3.4.0]
@@ -77,76 +101,122 @@ We continue to provide wheels for the regular Python versions 3.10 to 3.14, as w
Starting with this release, MQT QMAP no longer supports Python 3.9.
This is in line with the scheduled end of life of the version.
-As a result, MQT QMAP is no longer tested under Python 3.9 and no longer ships Python 3.9 wheels.
+As a result, MQT QMAP is no longer tested under Python 3.9
+and no longer ships Python 3.9 wheels.
## [3.3.0]
-Testing previous versions of the `mqt-qmap` package built via `uv sync` or simple `(uv) pip install .` generally failed due to binary incompatibility of the `mqt-core` compiled extension packages and the `mqt-qmap` one.
-This required building `mqt-core` from source and without build isolation to get a working local setup.
-By using the latest `pybind11` release (`v3`), the binary compatibility between extension modules compiled under different circumstances (such as different compilers) has been greatly increased.
-As such, it is no longer necessary to build `mqt-core` (and `mqt-qcec` for testing) from source and without build isolation when locally working on `mqt-qmap`.
+Testing previous versions of the `mqt-qmap` package built via `uv sync`
+or simple `(uv) pip install .` generally failed due to binary incompatibility of
+the `mqt-core` compiled extension packages and the `mqt-qmap` one.
+This required building `mqt-core` from source
+and without build isolation to get a working local setup.
+By using the latest `pybind11` release (`v3`),
+the binary compatibility between extension modules compiled under different
+circumstances (such as different compilers) has been greatly increased.
+As such, it is no longer necessary to build `mqt-core`
+(and `mqt-qcec` for testing)
+from source and without build isolation when locally working on `mqt-qmap`.
A simple `uv sync` is enough to successfully run `pytest`.
-All Python enums (e.g., `sc.Method`) are now exposed via `pybind11`'s new `py::native_enum`, which makes them compatible with Python's `enum.Enum` class (PEP 435).
+All Python enums (e.g., `sc.Method`) are now exposed via `pybind11`'s new
+`py::native_enum`, which makes them compatible with Python's `enum.Enum` class
+(PEP 435).
As a result, the enums can no longer be initialized using a string.
Instead of `Method("exact")` or `"exact"`, use `Method.exact`.
-This release restructures the neutral atom compiler which has consequences for its configuration and the reporting of statistics.
-The placement and routing stages have been merged into a single layout synthesis stage.
-There is a new `PlaceAndRouteSynthesizer` that combines the previously separate placement and routing stages.
-Consequently, the configuration for the placement and routing stages must now be wrapped in a configuration for the layout synthesis stage when using the C++ API.
+This release restructures the neutral atom compiler which has consequences
+for its configuration and the reporting of statistics.
+The placement and routing stages have been merged into a single layout synthesis
+stage.
+There is a new `PlaceAndRouteSynthesizer`
+that combines the previously separate placement and routing stages.
+Consequently, the configuration for the placement
+and routing stages must now be wrapped in a configuration
+for the layout synthesis stage when using the C++ API.
The Python API did not change in this regard.
-Furthermore, when reporting the statistics of the neutral atom compiler, the statistics for placement and routing are now reported as part of the layout synthesis statistics.
+Furthermore, when reporting the statistics of the neutral atom compiler,
+the statistics for placement and routing are now reported
+as part of the layout synthesis statistics.
The latter affects both the C++ and Python APIs.
Finally, the minimum required C++ version has been raised from C++17 to C++20.
-The default compilers of our test systems support all relevant features of the standard.
+The default compilers of our test systems support all relevant features of the
+standard.
## [3.2.0]
With this release, the Python package has been restructured.
In particular, the `mqt.qmap.pyqmap` module has been discontinued.
-Classes and functions can now be imported from the more descriptive `mqt.qmap.clifford_synthesis`, `mqt.qmap.hybrid_mapper`, `mqt.qmap.na`, and `mqt.qmap.sc` modules.
-The superconducting module's `compile()` function has been moved to `mqt.qmap.plugins.qiskit.sc`.
-The entrypoints `synthesize_clifford()` and `optimize_clifford()` of the Clifford synthesis module have been moved to `mqt.qmap.plugins.qiskit.clifford_synthesis`.
+Classes and functions can now be imported from the more descriptive
+`mqt.qmap.clifford_synthesis`, `mqt.qmap.hybrid_mapper`, `mqt.qmap.na`, and
+`mqt.qmap.sc` modules.
+The superconducting module's `compile()` function has been moved to
+`mqt.qmap.plugins.qiskit.sc`.
+The entrypoints `synthesize_clifford()`
+and `optimize_clifford()` of the Clifford synthesis module have been moved to
+`mqt.qmap.plugins.qiskit.clifford_synthesis`.
## [3.1.0]
-This minor release initiates the efforts to re-structure the Python bindings and make them more modular.
-Even tough this is not a breaking change, it is worth mentioning to developers of MQT QMAP that all Python code (except tests) has been moved to the top-level `python` directory.
-Furthermore, the C++ code for the Python bindings has been moved to the top-level `bindings` directory.
+This minor release initiates the efforts to re-structure the Python bindings
+and make them more modular.
+Even tough this is not a breaking change,
+it is worth mentioning to developers of MQT QMAP that all Python code
+(except tests) has been moved to the top-level `python` directory.
+Furthermore, the C++ code
+for the Python bindings has been moved to the top-level `bindings` directory.
## [3.0.0]
-This major release introduces several breaking changes, including the removal of deprecated features.
-The following paragraphs describe the most important changes and how to adapt your code accordingly.
+This major release introduces several breaking changes,
+including the removal of deprecated features.
+The following paragraphs describe the most important changes
+and how to adapt your code accordingly.
We intend to provide a more comprehensive migration guide for future releases.
-The major change in this major release is the move to the MQT Core Python package.
-This move allows us to make `qiskit` a fully optional dependency and entirely rely on the MQT Core IR for representing circuits.
-Additionally, the `mqt-core` Python package now ships all its C++ libraries as shared libraries so that these need not be fetched or built as part of the build process.
-This was tricky to achieve cross-platform, and you can find some more backstory in the corresponding [PR](https://github.com/munich-quantum-toolkit/qmap/pulls/418).
+The major change in this major release is the move to the MQT Core Python
+package.
+This move allows us to make `qiskit` a fully optional dependency
+and entirely rely on the MQT Core IR for representing circuits.
+Additionally, the `mqt-core` Python package now ships all its C++ libraries
+as shared libraries so that these need not be fetched or built
+as part of the build process.
+This was tricky to achieve cross-platform,
+and you can find some more backstory in the corresponding
+[PR](https://github.com/munich-quantum-toolkit/qmap/pulls/418).
We expect this integration to mature over the next few releases.
If you encounter any issues, please let us know.
-Support for `BackendV1` Qiskit backends has been removed in accordance with Qiskit's 2.0 release dropping support for these backends.
-If you still require support for these backends, please use the last version of MQT QMAP that supports them, which is `2.8.0`.
-However, we strongly recommend that you upgrade to Qiskit 2.0 or higher and use the new `BackendV2` interface.
+Support for `BackendV1` Qiskit backends has been removed in accordance with
+Qiskit's 2.0 release dropping support for these backends.
+If you still require support for these backends,
+please use the last version of MQT QMAP that supports them, which is `2.8.0`.
+However, we strongly recommend that you upgrade to Qiskit 2.0 or higher
+and use the new `BackendV2` interface.
Teleportation support for the heuristic mapping has been removed.
-If you still require this feature, please use the last version of MQT QMAP that supports it, which is `2.8.0`.
+If you still require this feature,
+please use the last version of MQT QMAP that supports it, which is `2.8.0`.
-MQT Core itself dropped support for several parsers in `v3.0.0`, including the `.real`, `.qc`, `.tfc`, and `GRCS` parsers.
-The `.real` parser lives on as part of the [MQT SyReC] project. All others have been removed without replacement.
+MQT Core itself dropped support for several parsers in `v3.0.0`,
+including the `.real`, `.qc`, `.tfc`, and `GRCS` parsers.
+The `.real` parser lives on as part of the [MQT SyReC] project.
+All others have been removed without replacement.
Consequently, these input formats are no longer supported in MQT QMAP.
-MQT QMAP has moved to the [munich-quantum-toolkit](https://github.com/munich-quantum-toolkit) GitHub organization under https://github.com/munich-quantum-toolkit/qmap.
-While most links should be automatically redirected, please update any links in your code to point to the new location.
+MQT QMAP has moved to the
+[munich-quantum-toolkit](https://github.com/munich-quantum-toolkit) GitHub
+organization under .
+While most links should be automatically redirected,
+please update any links in your code to point to the new location.
All links in the documentation have been updated accordingly.
MQT QMAP now requires CMake 3.24 or higher.
-Most modern operating systems should have this version available in their package manager.
-Alternatively, CMake can be conveniently installed from PyPI using the [`cmake`](https://pypi.org/project/cmake/) package.
+Most modern operating systems should have this version available in their
+package manager.
+Alternatively, CMake can be conveniently installed from PyPI using the
+[`cmake`](https://pypi.org/project/cmake/) package.
diff --git a/docs/conf.py b/docs/conf.py
index 62fa6fe44..6ec53d8d4 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -55,17 +55,17 @@
templates_path = ["_templates"]
extensions = [
- "myst_nb",
"autoapi.extension",
+ "myst_nb",
+ "sphinx_copybutton",
+ "sphinx_design",
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
- "sphinx_copybutton",
- "sphinx_design",
- "sphinxext.opengraph",
"sphinx.ext.viewcode",
- "sphinxcontrib.inkscapeconverter",
"sphinxcontrib.bibtex",
+ "sphinxcontrib.inkscapeconverter",
+ "sphinxext.opengraph",
]
source_suffix = [".rst", ".md"]
@@ -162,6 +162,7 @@ def format_url(self, _e: Entry) -> HRef: # noqa: PLR6301
napoleon_numpy_docstring = False
# -- Options for HTML output -------------------------------------------------
+
html_theme = "furo"
html_static_path = ["_static"]
html_css_files = [
diff --git a/docs/contributing.md b/docs/contributing.md
index 1d3b59114..619dbaf3d 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -6,9 +6,8 @@
Thank you for your interest in contributing to MQT QMAP!
This document outlines the development guidelines and how to contribute.
-We use GitHub to
-[host code](https://github.com/munich-quantum-toolkit/qmap), to
-[track issues and feature requests][issues], as well as accept
+We use GitHub to [host code](https://github.com/munich-quantum-toolkit/qmap),
+to [track issues and feature requests][issues], as well as accept
[pull requests](https://github.com/munich-quantum-toolkit/qmap/pulls).
See
for a general introduction to working with GitHub and contributing to projects.
@@ -332,13 +331,11 @@ ctest --preset release
:::{tip}
If you want to disable configuring and building the C++ tests,
-you can pass {code}`-DBUILD_MQT_QMAP_TESTS=OFF` to the CMake
-configure step.
+you can pass {code}`-DBUILD_MQT_QMAP_TESTS=OFF` to the CMake configure step.
:::
Our CI pipeline on GitHub also collects code coverage information
-and uploads it to
-[Codecov](https://codecov.io/gh/munich-quantum-toolkit/qmap).
+and uploads it to [Codecov](https://codecov.io/gh/munich-quantum-toolkit/qmap).
Our goal is to have new contributions at least maintain the current code
coverage level, while striving for covering as much of the code as possible.
Try to write meaningful tests that actually test the correctness of the code
@@ -449,8 +446,7 @@ directory.
:::{tip}
To build only the Python bindings,
-pass {code}`-DBUILD_MQT_QMAP_BINDINGS=ON` to the CMake configure
-step.
+pass {code}`-DBUILD_MQT_QMAP_BINDINGS=ON` to the CMake configure step.
CMake will then try to find Python
and the necessary dependencies ({code}`nanobind`) on your system
and configure the respective targets.
@@ -464,13 +460,12 @@ configure step to point CMake to a specific Python installation.
:::
-The Python package itself lives in the {code}`python/mqt/qmap`
-directory.
+The Python package itself lives in the {code}`python/mqt/qmap` directory.
The package lives in the {code}`src/mqt/qmap` directory.
-We recommend using [{code}`nox`][nox]
-for development. {code}`nox` is a Python automation tool
+We recommend using [{code}`nox`][nox] for development.
+{code}`nox` is a Python automation tool
that allows you to define tasks in a {code}`noxfile.py` file
and then run them with a single command.
If you have not installed it yet,
@@ -577,15 +572,15 @@ prek run --all-files
The Python code is documented using
[Google-style docstrings](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings).
Every public function, class,
-and module should have a docstring that explains what it does
-and how to use it. {code}`ruff` will check for missing docstrings
-and will explicitly warn you if you forget to add one.
+and module should have a docstring that explains what it does and how to use it.
+{code}`ruff` will check for missing docstrings and will explicitly warn you
+if you forget to add one.
We heavily rely on [type hints](https://docs.python.org/3/library/typing.html)
to document the expected types of function arguments and return values.
For the compiled parts of the code base,
-we provide type hints in the form of stub files in the
-{code}`python/mqt/qmap` directory.
+we provide type hints in the form of stub files in the {code}`python/mqt/qmap`
+directory.
These stub files are auto-generated.
Do not edit them directly.
Instead, you can use the {code}`nox` session {code}`stubs` to regenerate them
@@ -772,8 +767,8 @@ minor or major release.
This does not mean that the dependency update itself is a breaking change
for MQT QMAP.
If you are sure that the dependency update does not introduce any breaking
-changes for MQT QMAP, you can remove the {code}`minor` or {code}`major`
-label from the PR.
+changes for MQT QMAP, you can remove the {code}`minor` or {code}`major` label
+from the PR.
This will ensure that the respective PR does not influence the type of an
upcoming release.
diff --git a/docs/index.md b/docs/index.md
index fee9d8690..243b05870 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -4,18 +4,38 @@
\begin{abstract}
```
-MQT QMAP is an open-source C++20 and Python library for mapping quantum circuits onto various hardware technologies developed as part of the _{doc}`Munich Quantum Toolkit (MQT) `_.
-
-This documentation provides a comprehensive guide to the MQT QMAP library, including {doc}`installation instructions `, demo notebooks, and detailed {doc}`API documentation `.
-The source code of MQT QMAP is publicly available on GitHub at [munich-quantum-toolkit/qmap](https://github.com/munich-quantum-toolkit/qmap), while pre-built binaries are available via [PyPI](https://pypi.org/project/mqt.qmap/) for all major operating systems and all modern Python versions.
+MQT QMAP is an open-source C++20 and Python library
+for mapping quantum circuits onto various hardware technologies developed
+as part of the _{doc}`Munich Quantum Toolkit (MQT) `_.
+
+This documentation provides a comprehensive guide to the MQT QMAP library,
+including {doc}`installation instructions `, demo notebooks,
+and detailed {doc}`API documentation `.
+The source code of MQT QMAP is publicly available on GitHub at
+[munich-quantum-toolkit/qmap](https://github.com/munich-quantum-toolkit/qmap),
+while pre-built binaries are available via
+[PyPI](https://pypi.org/project/mqt.qmap/) for all major operating systems and
+all modern Python versions.
MQT QMAP is fully compatible with Qiskit 1.0 and above.
-We recommend you to start with the {doc}`installation instructions ` or by reading our overview paper {cite:p}`wille2023qmap`.
-Then proceed to the {doc}`mapping page `, the {doc}`synthesis/optimization page `, the {doc}`neutral atom state preparation page `, or the {doc}`zoned neutral atom compiler `, and read the {doc}`reference documentation `.
-If you are interested in the theory behind MQT QMAP, have a look at the publications in the {doc}`publication list `.
-
-We appreciate any feedback and contributions to the project. If you want to contribute, you can find more information in the {doc}`Contribution ` guide.
-If you are having trouble with the installation or the usage of MQT QMAP, please let us know at our {doc}`Support ` page or by reaching out to us at [quantum.cda@xcit.tum.de](mailto:quantum.cda@xcit.tum.de).
+We recommend you to start with the
+{doc}`installation instructions ` or by reading our overview paper
+{cite:p}`wille2023qmap`.
+Then proceed to the {doc}`mapping page `,
+the {doc}`synthesis/optimization page `,
+the {doc}`neutral atom state preparation page `,
+or the {doc}`zoned neutral atom compiler `,
+and read the {doc}`reference documentation `.
+If you are interested in the theory behind MQT QMAP,
+have a look at the publications in the {doc}`publication list `.
+
+We appreciate any feedback and contributions to the project.
+If you want to contribute,
+you can find more information in the {doc}`Contribution ` guide.
+If you are having trouble with the installation or the usage of MQT QMAP,
+please let us know at our {doc}`Support ` page
+or by reaching out to us at
+[quantum.cda@xcit.tum.de](mailto:quantum.cda@xcit.tum.de).
````{only} latex
```{note}
diff --git a/docs/installation.md b/docs/installation.md
index f58cb2260..837a8a90e 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -4,9 +4,8 @@
# Installation
MQT QMAP is primarily developed as a C++20 library with Python bindings.
-The Python package is available on
-[PyPI](https://pypi.org/project/mqt.qmap/) and can be installed on all
-major operating systems with all
+The Python package is available on [PyPI](https://pypi.org/project/mqt.qmap/)
+and can be installed on all major operating systems with all
[officially supported Python versions](https://devguide.python.org/versions/).
:::::{tip}
@@ -68,6 +67,7 @@ python -m pip install mqt.qmap
:::
::::
+
In most cases, no compilation is required;
a platform-specific prebuilt wheel is downloaded and installed.
diff --git a/docs/mapping.md b/docs/mapping.md
index 608764c45..210592bba 100644
--- a/docs/mapping.md
+++ b/docs/mapping.md
@@ -11,14 +11,23 @@ mystnb:
%config InlineBackend.figure_formats = ['svg']
```
-
+```{only} html
+
+
+```
# Quantum Circuit Mapping
-Many quantum computing architectures limit the pairs of qubits that two-qubit operations can be applied to.
+Many quantum computing architectures limit the pairs of qubits
+that two-qubit operations can be applied to.
This is commonly described by a device's _coupling map_.
-To execute a generic quantum circuit (with arbitrary interactions between its qubits) on such an architecture, the circuit needs to be _mapped_.
-This involves _qubit allocation_, where logical qubits are assigned to physical qubits in an _initial layout_, and _routing_, where the original circuit is augmented with SWAP gates such that it adheres to the target device's _coupling map_.
+To execute a generic quantum circuit
+(with arbitrary interactions between its qubits)
+on such an architecture, the circuit needs to be _mapped_.
+This involves _qubit allocation_,
+where logical qubits are assigned to physical qubits in an _initial layout_,
+and _routing_, where the original circuit is augmented with SWAP gates such
+that it adheres to the target device's _coupling map_.
Consider the following circuit.
@@ -49,7 +58,8 @@ qc.measure_all()
qc.draw(output="mpl")
```
-Now assume this circuit shall be mapped to a $4$-qubit architecture defined by the following coupling map:
+Now assume this circuit shall be mapped to a $4$-qubit architecture defined by
+the following coupling map:

@@ -71,8 +81,12 @@ arch = Architecture(
)
```
-The quantum circuit `qc` can not be run directly on this architecture since it contains gates that act on qubits not connected on the device architecture.
-Naively inserting SWAP gates that permute the logical-to-physical qubit mapping on the fly may yield the following compiled circuit.
+The quantum circuit `qc` can not be run directly on this architecture
+since it contains gates that act on qubits not connected on the device
+architecture.
+Naively inserting SWAP gates
+that permute the logical-to-physical qubit mapping on the fly may yield the
+following compiled circuit.
```{code-cell} ipython3
---
@@ -109,22 +123,47 @@ qc1.measure_all()
qc1.draw(output="mpl")
```
-Over the course of the mapping, _four_ SWAP gates have been introduced to satisfy the connectivity constraints of the device's architecture.
-Since every additional gate increases the probability of errors, this is a very costly overhead for such a small circuit.
-
-Keeping the number of additionally introduced gates as small as possible is key for ensuring the successful execution of the quantum circuit. Finding an optimal mapping for a quantum circuit is an NP-hard problem Botea et al..
+Over the course of the mapping,
+_four_ SWAP gates have been introduced to satisfy the connectivity constraints
+of the device's architecture.
+Since every additional gate increases the probability of errors,
+this is a very costly overhead for such a small circuit.
+
+Keeping the number of additionally introduced gates as small as possible is key
+for ensuring the successful execution of the quantum circuit.
+Finding an optimal mapping
+for a quantum circuit is an NP-hard problem
+{cite:p}`boteaComplexityQuantumCircuit2018`.
_QMAP_ offers two dedicated techniques for tackling that problem:
-- An _exact_ mapping approach (based on {cite:p}`willeMappingQuantumCircuits2019`, {cite:p}`burgholzer2022limitingSearchSpace`) that guarantees (gate-optimal) solutions and is typically suitable for up to 8 qubits.
-- A _heuristic_ mapping approach (based on {cite:p}`zulehnerEfficientMethodologyMapping2019`, {cite:p}`hillmichExlpoitingQuantumTeleportation2021`) that allows to determine efficient mapping solutions in a scalable fashion for up to hundreds of qubits.
+- An _exact_ mapping approach
+ (based on {cite:p}`willeMappingQuantumCircuits2019`,
+ {cite:p}`burgholzer2022limitingSearchSpace`)
+ that guarantees (gate-optimal) solutions and is typically suitable
+ for up to 8 qubits.
+- A _heuristic_ mapping approach
+ (based on {cite:p}`zulehnerEfficientMethodologyMapping2019`,
+ {cite:p}`hillmichExlpoitingQuantumTeleportation2021`)
+ that allows to determine efficient mapping solutions in a scalable fashion
+ for up to hundreds of qubits.
## Exact Mapping
-The _exact mapper_ implemented in _QMAP_ maps quantum circuits using the _minimal_ number of SWAP gates.
-To this end, it encodes the mapping task as a MaxSAT problem and subsequently solves it using the [SMT solver Z3](https://github.com/Z3Prover/z3). Due to the NP-hardness of the mapping task, this approach is only scalable up to roughly eight qubits in most scenarios.
+The _exact mapper_ implemented in _QMAP_ maps quantum circuits using the
+_minimal_ number of SWAP gates.
+To this end, it encodes the mapping task as a MaxSAT problem
+and subsequently solves it using the
+[SMT solver Z3](https://github.com/Z3Prover/z3).
+Due to the NP-hardness of the mapping task,
+this approach is only scalable up to roughly eight qubits in most scenarios.
```{note}
-On directional architectures, it can be significantly cheaper to surround a CNOT gate with four Hadamard operations (effectively exchanging its control and target) instead of adding a SWAP gate. For these architectures, QMAP minimizes the number of additional SWAP and H gates.
+On directional architectures,
+it can be significantly cheaper to surround a CNOT gate with four Hadamard
+operations (effectively exchanging its control and target) instead of adding a
+SWAP gate.
+For these architectures,
+QMAP minimizes the number of additional SWAP and H gates.
```
Using the exact mapper is as simple as:
@@ -147,17 +186,24 @@ The resulting solution only requires _two_ SWAP gates for mapping the circuit.
```{note}
-The exact mapping method implemented in QMAP is optimal with respect to the number of additional SWAP gates needed for mapping a given circuit.
-It is not guaranteed to be optimal with respect to the number of additional gates needed for mapping a given circuit, e.g., any sequence of a SWAP gate and a CNOT gate acting on the same qubits can be simplified to just two CNOT gates.
-Such an optimization pass is conducted by default in the `compile_` function after the circuit has been mapped.
-However, this cost reduction is not accounted for in the SAT formulation at the moment.
+The exact mapping method implemented in QMAP is optimal with respect to the
+number of additional SWAP gates needed for mapping a given circuit.
+It is not guaranteed to be optimal with respect to the number of additional
+gates needed for mapping a given circuit, e.g., any sequence of a SWAP gate and
+a CNOT gate acting on the same qubits can be simplified to just two CNOT gates.
+Such an optimization pass is conducted by default in the `compile_` function
+after the circuit has been mapped.
+However, this cost reduction is not accounted
+for in the SAT formulation at the moment.
```
## Heuristic Mapping
-The _heuristic mapper_ implemented in _QMAP_ uses A\*-search to efficiently traverse the immense search space of the mapping problem.
+The _heuristic mapper_ implemented in _QMAP_ uses A\*-search to efficiently
+traverse the immense search space of the mapping problem.
It effectively trades optimality for runtime.
-This allows to reliably determine suitable mappings for circuits with up to hundreds of qubits.
+This allows to reliably determine suitable mappings
+for circuits with up to hundreds of qubits.
Using the heuristic mapper works completely analogous to the exact mapper.
```{code-cell} ipython3
@@ -171,4 +217,6 @@ print(f"Additional SWAPs: {res.output.swaps}")
print(f"Runtime: {res.time:f}")
```
-While this solution is not optimal anymore it only requires one more SWAP gate and even for such a small example the heuristic mapper is orders of magnitudes faster than the exact mapper.
+While this solution is not optimal anymore it only requires one more SWAP gate
+and even for such a small example the heuristic mapper is orders of magnitudes
+faster than the exact mapper.
diff --git a/docs/na_hybrid.md b/docs/na_hybrid.md
index f454ec378..8ce65f672 100644
--- a/docs/na_hybrid.md
+++ b/docs/na_hybrid.md
@@ -10,21 +10,32 @@ kernelspec:
%config InlineBackend.figure_formats = ['svg']
```
-
+```{only} html
+
+
+```
# Hybrid Neutral Atom Routing and Mapping
-Neutral-atom (NA) processors combine long-range, native multi-qubit interactions with high-fidelity atom transport.
-HyRoNA, the hybrid mapper in MQT QMAP, exploits both capabilities: it adaptively mixes gate-based routing (SWAP/BRIDGE)
-with atom transport to minimize latency and error. It pairs interaction-aware initial placement with fast,
-capability-specific cost models and an ASAP scheduler that respects hardware constraints, and it emits hardware-native
-programs plus optional animation files for visualization.
+Neutral-atom (NA) processors combine long-range,
+native multi-qubit interactions with high-fidelity atom transport.
+HyRoNA, the hybrid mapper in MQT QMAP, exploits both capabilities:
+it adaptively mixes gate-based routing (SWAP/BRIDGE) with atom transport to
+minimize latency and error.
+It pairs interaction-aware initial placement with fast,
+capability-specific cost models and an ASAP scheduler
+that respects hardware constraints,
+and it emits hardware-native programs plus optional animation files
+for visualization.
-Below, we show how to use the Hybrid NA Mapper from Python on a small GHZ example and how to tune a few key parameters.
+Below, we show how to use the Hybrid NA Mapper from Python on a small GHZ
+example and how to tune a few key parameters.
## Example: GHZ state on a hybrid NA architecture
-In this example, we prepare an 8-qubit GHZ state (similar to the [zoned compiler](na_zoned_compiler.md)) and map it to a hybrid NA architecture.
+In this example, we prepare an 8-qubit GHZ state
+(similar to the [zoned compiler](na_zoned_compiler.md))
+and map it to a hybrid NA architecture.
```{code-cell} ipython3
@@ -113,9 +124,12 @@ print(f"Loaded architecture: {arch.name} with {arch.num_qubits} qubits.")
### Map with HyRoNA
-Mapping translates the algorithm to hardware-native operations using a combination of routing with SWAP/BRIDGE gates and
-atom moves. What combination is used depends on the architecture capabilities and the mapper parameters.
-Here, we show two examples: first, we only use gate-based routing, then we let the mapper decide freely.
+Mapping translates the algorithm to hardware-native operations using a
+combination of routing with SWAP/BRIDGE gates and atom moves.
+What combination is used depends on the architecture capabilities
+and the mapper parameters.
+Here, we show two examples: first, we only use gate-based routing,
+then we let the mapper decide freely.
```{code-cell} ipython3
from mqt.core import load
@@ -137,10 +151,13 @@ mapper.map(circ) # optionally: mapper.map(circ, initial_mapping=InitialCircuitM
mapper.get_stats()
```
-Note, how we set `shuttling_weight` zero to disallow atom moves and only use SWAP gates for routing.
+Note, how we set `shuttling_weight` zero to disallow atom moves
+and only use SWAP gates for routing.
-The idea of the hybrid mapper is to mix both capabilities or to automatically select the best one.
-We now re-run the mapping with default parameters that allow both SWAPs and atom moves.
+The idea of the hybrid mapper is to mix both capabilities
+or to automatically select the best one.
+We now re-run the mapping with default parameters that allow both SWAPs
+and atom moves.
```{code-cell} ipython3
params_default = MapperParameters()
@@ -151,12 +168,14 @@ mapper.map(circ)
mapper.get_stats()
```
-Now the mapper uses atom moves only as they are the better option on this architecture where moves are unit fidelity and
-gates are noisy.
+Now the mapper uses atom moves only
+as they are the better option on this architecture where moves are unit fidelity
+and gates are noisy.
### Schedule the mapped circuit
-Scheduling orders the mapped operations as-soon-as-possible while respecting hardware constraints.
+Scheduling orders the mapped operations as-soon-as-possible
+while respecting hardware constraints.
```{code-cell} ipython3
# Schedule; set create_animation_csv=True to generate visualization data
@@ -165,7 +184,10 @@ results = mapper.schedule(verbose=False, create_animation_csv=False)
results
```
-You can retrieve the mapped scheduled circuit (extended QASM2) and, if desired, the variant with explicit AOD movements equivalent to the operations done on the hardware.
+You can retrieve the mapped scheduled circuit
+(extended QASM2)
+and, if desired, the variant with explicit AOD movements equivalent to the
+operations done on the hardware.
```{code-cell} ipython3
@@ -179,17 +201,24 @@ mapped_aod_qasm = mapper.get_mapped_qc_aod_qasm()
print("\n... AOD (converted) snippet ...\n" + "\n".join(mapped_aod_qasm.splitlines()[:30]) + "\n...")
```
-Here, the `q` register corresponds to the 5x5=25 coordinates of the architecture and no longer to the circuit qubits.
+Here, the `q` register corresponds to the 5x5=25 coordinates of the architecture
+and no longer to the circuit qubits.
The other registers are used for temporary storage and AOD control.
-The second variant shows explicit AOD movements that correspond to the atom moves done on hardware.
+The second variant shows explicit AOD movements
+that correspond to the atom moves done on hardware.
Here, the AODs can be activated, moved, and deactivated to shuttle atoms around.
-The first entry corresponds to the x-direction and the second to the y-direction; in each pair, the two numbers denote start and end coordinates.
+The first entry corresponds to the x-direction
+and the second to the y-direction; in each pair,
+the two numbers denote start and end coordinates.
### Export animation files (optional)
-HyRoNA can write animation output files that can be visualized with [MQT NAViz](https://github.com/munich-quantum-toolkit/naviz).
-Typically one has to accelerate the shuttling speed for better visualization by setting `shuttling_speed_factor`.
+HyRoNA can write animation output files
+that can be visualized with
+[MQT NAViz](https://github.com/munich-quantum-toolkit/naviz).
+Typically one has to accelerate the shuttling speed
+for better visualization by setting `shuttling_speed_factor`.
```{code-cell} ipython3
# Re-run scheduling with animation output enabled
@@ -200,8 +229,8 @@ _ = mapper.schedule(verbose=False, create_animation_csv=True, shuttling_speed_fa
mapper.save_animation_files("ghz8_hyrona_animation")
```
-This creates `.namachine` and `.naviz` files which can then be imported into
-MQT NAViz for visualization.
+This creates `.namachine` and `.naviz` files
+which can then be imported into MQT NAViz for visualization.

@@ -210,36 +239,49 @@ MQT NAViz for visualization.
HyRoNA exposes a concise set of parameters via `MapperParameters`:
- lookahead_depth: limited lookahead to peek at near-future layers
-- lookahead_weight_swaps / lookahead_weight_moves: balance gate-routing vs. atom motion during lookahead
+- lookahead_weight_swaps / lookahead_weight_moves:
+ balance gate-routing vs. atom motion during lookahead
- decay: decreases the incentive for repeatedly blocking the same qubits
-- gate_weight / shuttling_weight / shuttling_time_weight: cost-model weights for gates vs. transport
-- dynamic_mapping_weight: bias for enabling dynamic re-mapping (SWAP/MOVE) when beneficial
-- max_bridge_distance: limit for BRIDGE operations; use to avoid long-range chains
+- gate_weight / shuttling_weight / shuttling_time_weight:
+ cost-model weights for gates vs. transport
+- dynamic_mapping_weight:
+ bias for enabling dynamic re-mapping (SWAP/MOVE) when beneficial
+- max_bridge_distance: limit for BRIDGE operations;
+ use to avoid long-range chains
- initial_coord_mapping: strategy for hardware coordinate initialization
-For more details, please check the source code documentation of `MapperParameters`.
+For more details, please check the source code documentation of
+`MapperParameters`.
## Tips
-- Initial mapping: you can explicitly select the initial circuit-to-hardware mapping for `map` or `map_qasm_file` using
- `initial_mapping=InitialCircuitMapping.identity` or `InitialCircuitMapping.graph`.
+- Initial mapping: you can explicitly select the initial circuit-to-hardware
+ mapping for `map` or `map_qasm_file` using
+ `initial_mapping=InitialCircuitMapping.identity` or
+ `InitialCircuitMapping.graph`.
-- QASM input: instead of building a circuit in Qiskit, you can call `mapper.map_qasm_file("path/to/circuit.qasm")` and
- then `mapper.schedule(...)` as shown above.
+- QASM input: instead of building a circuit in Qiskit,
+ you can call `mapper.map_qasm_file("path/to/circuit.qasm")`
+ and then `mapper.schedule(...)` as shown above.
-- Architectures: the examples `rubidium_hybrid.json`, `rubidium_gate.json`, and `rubidium_shuttling.json` in
- `architectures/` cover different capability profiles and are a good starting point
+- Architectures: the examples `rubidium_hybrid.json`, `rubidium_gate.json`,
+ and `rubidium_shuttling.json` in `architectures/` cover different capability
+ profiles and are a good starting point
## Hybrid Synthesis Mapper
-The Hybrid Synthesis Mapper helps you compare and stitch together alternative circuit fragments while keeping track of the current mapping on the NA device.
+The Hybrid Synthesis Mapper helps you compare
+and stitch together alternative circuit fragments
+while keeping track of the current mapping on the NA device.
Below is a compact example that mirrors the unit test flow and shows how to:
- evaluate multiple candidate fragments and pick the best,
- append fragments,
- and retrieve mapped QASM as well as the AOD-annotated variant.
-First, we create the `HybridSynthesisMapper` and evaluate two candidate fragments (here, both are the same GHZ circuit as above for simplicity).
+First, we create the `HybridSynthesisMapper`
+and evaluate two candidate fragments
+(here, both are the same GHZ circuit as above for simplicity).
```{code-cell} ipython3
from mqt.qmap.hybrid_mapper import HybridSynthesisMapper
@@ -252,7 +294,8 @@ fidelities = synth.evaluate_synthesis_steps([circ, circ], also_map = False)
print("Fidelities of subcircuits:", fidelities )
```
-The fidelity return indicates how well the subcircuit can be appended to the circuit mapped to the hardware.
+The fidelity return indicates how well the subcircuit can be appended to the
+circuit mapped to the hardware.
You can then build up a larger program by appending fragments.
@@ -260,9 +303,11 @@ You can then build up a larger program by appending fragments.
synth.append_with_mapping(circ)
```
-This appends the circuit and maps it directly. This can be repeated for multiple fragments to always choose the best one.
+This appends the circuit and maps it directly.
+This can be repeated for multiple fragments to always choose the best one.
-Similar to the normal Hybrid Mapper, you can retrieve the mapped circuit and the AOD-annotated variant:
+Similar to the normal Hybrid Mapper,
+you can retrieve the mapped circuit and the AOD-annotated variant:
```{code-cell} ipython3
@@ -273,7 +318,9 @@ print("\n... Mapped QASM snippet ...\n" +
"\n...")
```
-One can also access the circuits which is constructed step-by-step in a unmapped state (e.g. to use a different mapper).
+One can also access the circuits
+which is constructed step-by-step in a unmapped state
+(e.g. to use a different mapper).
```{code-cell} ipython3
qasm_synth = synth.get_synthesized_qc_qasm()
@@ -284,4 +331,6 @@ print("\n... Synthesized QASM snippet ...\n" +
Here this corresponds simply to the input GHZ circuit.
-This workflow lets you mix candidate-generation (synthesis) with hardware-aware mapping and scheduling, while keeping a single source of truth for mapping state across fragments.
+This workflow lets you mix candidate-generation (synthesis) with hardware-aware
+mapping and scheduling, while keeping a single source of truth for mapping state
+across fragments.
diff --git a/docs/na_state_prep.md b/docs/na_state_prep.md
index f880920d7..18f9795cc 100644
--- a/docs/na_state_prep.md
+++ b/docs/na_state_prep.md
@@ -11,22 +11,37 @@ mystnb:
%config InlineBackend.figure_formats = ['svg']
```
-
+```{only} html
+
+
+```
# Neutral Atom Logical State Preparation
All quantum computers are prone to errors.
-This is the motivation of employing error correction during a quantum computation.
-To this end, a (logical) qubit on the algorithmic level is encoded into a shared and highly entangled state of multiple physical qubits.
-Before the actual computation can start, those physical qubits need to be prepared in a state that represents the logical zero state.
-
-For that, we provide a tool based on {cite:p}`stadeOptimalStatePreparation2024` that takes a state preparation circuit and generates an optimal sequence of operations tailored to the zoned neutral atom architecture.
-Thereby, the circuit consists of one initial layer of Hadamard gates on all qubits that initialize the physical qubits in the plus state.
-Those are followed by a set of entangling (CZ) gates that generate a so-called graph state.
-The final logical state is achieved by applying additional Hadamard gates on selected qubits.
-
-Below we demonstrate how the optimal schedule can be retrieved for the Steane-code, the smallest 2D color code.
-First, we create the state preparation circuit for the Steane-code as a `qiskit.QuantumCircuit`.
+This is the motivation of employing error correction during a quantum
+computation.
+To this end, a (logical) qubit on the algorithmic level is encoded into a shared
+and highly entangled state of multiple physical qubits.
+Before the actual computation can start,
+those physical qubits need to be prepared in a state
+that represents the logical zero state.
+
+For that, we provide a tool based on {cite:p}`stadeOptimalStatePreparation2024`
+that takes a state preparation circuit
+and generates an optimal sequence of operations tailored to the zoned neutral
+atom architecture.
+Thereby, the circuit consists of one initial layer of Hadamard gates on all
+qubits that initialize the physical qubits in the plus state.
+Those are followed by a set of entangling (CZ) gates
+that generate a so-called graph state.
+The final logical state is achieved by applying additional Hadamard gates on
+selected qubits.
+
+Below we demonstrate how the optimal schedule can be retrieved
+for the Steane-code, the smallest 2D color code.
+First, we create the state preparation circuit for the Steane-code
+as a `qiskit.QuantumCircuit`.
```{code-cell} ipython3
from qiskit import QuantumCircuit
@@ -52,7 +67,8 @@ qc.draw(output="mpl")
We solve the problem of optimal state preparation with an SMT solver (Z3).
Therefore, we encode the problem into an SMT-model.
-To construct the SMT model, the solver takes the entangling operations (CZ) as a list of qubit pairs.
+To construct the SMT model,
+the solver takes the entangling operations (CZ) as a list of qubit pairs.
```{code-cell} ipython3
from mqt.core import load
@@ -63,16 +79,24 @@ ops = get_ops_for_solver(circ, "z", 1) # We extract the 'Z' gates with '1' cont
ops
```
-Now, we are ready to initialize the solver and to generate the optimal sequence of operations.
-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.
-The entangling zone itself consists of three rows and the architecture model has three columns.
-Within each interaction site, atoms can be offset by two sites in every direction.
+Now, we are ready to initialize the solver
+and to generate the optimal sequence of operations.
+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.
+The entangling zone itself consists of three rows
+and the architecture model has three columns.
+Within each interaction site,
+atoms can be offset by two sites in every direction.
The considered architecture offers two AOD columns and three AOD rows.
We instruct the solver to generate a sequence consisting of four stages.
Thereby, we do not fix the number of transfer stages.
-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.
-For further details on the employed abstraction of the 2D plane in the solver, please refer to the corresponding article {cite:p}`stadeOptimalStatePreparation2024`.
+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.
+For further details on the employed abstraction of the 2D plane in the solver,
+please refer to the corresponding article
+{cite:p}`stadeOptimalStatePreparation2024`.
```{code-cell} ipython3
from mqt.qmap.na.state_preparation import NAStatePreparationSolver
@@ -81,8 +105,9 @@ solver = NAStatePreparationSolver(3, 7, 2, 3, 2, 2, 2, 2, 2, 4)
result = solver.solve(ops, 7, 4, None, False, True)
```
-To inspect the result, it can be exported to the human-readable JSON format by invoking the method `result.json()`
-In this example, we take another approach and generate code from the result.
+To inspect the result, it can be exported to the human-readable JSON format by
+invoking the method `result.json()` In this example, we take another approach
+and generate code from the result.
For that, we call the function `generate_code` with the respective arguments.
```{code-cell} ipython3
diff --git a/docs/na_zoned_compiler.md b/docs/na_zoned_compiler.md
index 8fdcfa4ab..220d92a94 100644
--- a/docs/na_zoned_compiler.md
+++ b/docs/na_zoned_compiler.md
@@ -13,32 +13,43 @@ mystnb:
# Zoned Neutral Atom Compiler
-Successful quantum computation requires advanced software, especially compilers that optimize quantum algorithms for
-hardware execution.
-Zoned neutral atom architectures execute operations in designated spatially separated zones.
-The zones facilitate higher coherence times and overall fidelity of the quantum computation.
-However, the zones also require the rearrangement of atoms during the quantum computation.
-MQT QMAP provides two tools to compile a quantum circuit to target-specific instructions for zoned quantum computing architectures based on neutral atoms:
-
-- a reuse-aware compiler based on {cite:p}`linReuseAwareCompilationZoned2025`, and
+Successful quantum computation requires advanced software,
+especially compilers that optimize quantum algorithms for hardware execution.
+Zoned neutral atom architectures execute operations in designated spatially
+separated zones.
+The zones facilitate higher coherence times
+and overall fidelity of the quantum computation.
+However, the zones also require the rearrangement of atoms during the quantum
+computation.
+MQT QMAP provides two tools to compile a quantum circuit to target-specific
+instructions for zoned quantum computing architectures based on neutral atoms:
+
+- a reuse-aware compiler based on {cite:p}`linReuseAwareCompilationZoned2025`,
+ and
- a routing-aware compiler based on {cite:p}`stadeRoutingAwarePlacement2025`.
:::{note}
-The second, i.e., routing-aware compiler also implements the reuse-aware compilation approach.
-Specifically, it exchanges the placement component of the reuse-aware compiler with a routing-aware placer.
-Hence, in the following, the first compiler is referred to as the _routing-agnostic compiler_ and the second one as the _routing-aware compiler_.
+The second, i.e., routing-aware compiler also implements the reuse-aware
+compilation approach.
+Specifically, it exchanges the placement component of the reuse-aware compiler
+with a routing-aware placer.
+Hence, in the following,
+the first compiler is referred to as the _routing-agnostic compiler_
+and the second one as the _routing-aware compiler_.
:::
## Example: GHZ State on Neutral Atom Architecture
-In this example, we will demonstrate how to use the zoned neutral atom compiler to generate a sequence of
-target-specific instructions for a quantum circuit.
-For this purpose, we employ a circuit that prepares a Greenberger-Horne-Zeilinger (GHZ) state of 8 qubits.
-Compared to the usual GHZ circuit that applies the CX-gates in a chain, this circuit applies the CX-gates in a tree-like
-manner.
-First, it brings one qubit into maximal superposition and then applies the first CX-gate as usual.
-Afterward, it applies two CX-gates in parallel controlled on the qubits already in superposition instead of applying them
-serially.
+In this example, we will demonstrate how to use the zoned neutral atom compiler
+to generate a sequence of target-specific instructions for a quantum circuit.
+For this purpose, we employ a circuit
+that prepares a Greenberger-Horne-Zeilinger (GHZ) state of 8 qubits.
+Compared to the usual GHZ circuit that applies the CX-gates in a chain,
+this circuit applies the CX-gates in a tree-like manner.
+First, it brings one qubit into maximal superposition
+and then applies the first CX-gate as usual.
+Afterward, it applies two CX-gates in parallel controlled on the qubits already
+in superposition instead of applying them serially.
```{code-cell} ipython3
from qiskit import QuantumCircuit
@@ -57,14 +68,17 @@ qc.cx(6, 7)
qc.draw(output="mpl")
```
-This circuit is not compatible with the native gate set of the zoned neutral atom architecture that consists of global
-ry-gates, local rz-gates, and controlled z-gates.
-The following circuit is equivalent to the previous one but decomposes the circuit into the native gate set of the
-zoned neutral atom architecture.
+This circuit is not compatible with the native gate set of the zoned neutral
+atom architecture that consists of global ry-gates, local rz-gates, and
+controlled z-gates.
+The following circuit is equivalent to the previous one
+but decomposes the circuit into the native gate set of the zoned neutral atom
+architecture.
```{note}
-Even though other single-qubit gates may not be supported by the hardware, the compiler can handle arbitrary
-single-qubit gates. It will translate them to generic u3 gates and include them in the output.
+Even though other single-qubit gates may not be supported by the hardware,
+the compiler can handle arbitrary single-qubit gates.
+It will translate them to generic u3 gates and include them in the output.
```
```{code-cell} ipython3
@@ -102,10 +116,12 @@ qc.append(global_ry(pi/4, 8), range(8))
qc.draw(output="mpl")
```
-On the considered architecture, the single-qubit gates, i.e., the global ry and local rz-gates can be executed everywhere.
-However, the controlled z-gates can only be executed between nearby atoms in the so-called entanglement zone.
-This entanglement zone is spatially separated from the storage zone, where all atoms not involved in a cz-gate are
-stored.
+On the considered architecture, the single-qubit gates, i.e.,
+the global ry and local rz-gates can be executed everywhere.
+However, the controlled z-gates can only be executed between nearby atoms in the
+so-called entanglement zone.
+This entanglement zone is spatially separated from the storage zone,
+where all atoms not involved in a cz-gate are stored.
```{image} images/zones.pdf
:alt: Zoned Neutral Atom Architecture
@@ -113,7 +129,8 @@ stored.
:align: center
```
-To find an optimized sequence of target-specific instructions, we use one of the zoned neutral atom compilers.
+To find an optimized sequence of target-specific instructions,
+we use one of the zoned neutral atom compilers.
Each compiler requires first a specification of the architecture.
```{code-cell} ipython3
@@ -156,10 +173,15 @@ compiler = RoutingAwareCompiler(arch)
```
Now, the created compiler can be used to compile the circuit from above.
-The output is in the `.naviz` format that can be read by the `MQT NAViz` tool
-at [github.com/cda-tum/mqt-naviz](https://github.com/cda-tum/mqt-naviz).
+The output is in the `.naviz` format
+that can be read by the `MQT NAViz` tool at
+[github.com/cda-tum/mqt-naviz](https://github.com/cda-tum/mqt-naviz).
This tool allows visualizing the resulting quantum computation.
-To import the architecture used for the compilation into MQT NAViz, you can use the [`to_namachine_file`](#mqt.qmap.na.zoned.ZonedNeutralAtomArchitecture.to_namachine_file) method to export the architecture to the `.namachine` format accepted by MQT NAViz.
+To import the architecture used for the compilation into MQT NAViz,
+you can use the
+{py:meth}`~mqt.qmap.na.zoned.ZonedNeutralAtomArchitecture.to_namachine_file`
+method to export the architecture to the `.namachine` format accepted by MQT
+NAViz.
```{code-cell} ipython3
from mqt.core import load
@@ -170,14 +192,18 @@ print(code)
```
```{note}
-The A* search in the placer of the routing-aware compiler is quite memory intensive.
-Right now, the maximum number of nodes considered in the A* search is limited to 50M.
-If this limit is hit, you will get an error message. You can freely adapt this limit
-by setting the argument `max_nodes` in the constructor of the `RoutingAwareCompiler`, see below.
+The A* search in the placer of the routing-aware compiler is quite memory
+intensive.
+Right now, the maximum number of nodes considered in the A* search is limited to
+50M.
+If this limit is hit, you will get an error message.
+You can freely adapt this limit by setting the argument `max_nodes` in the
+constructor of the `RoutingAwareCompiler`, see below.
```
Above, we have used the default settings for the compiler.
-However, the different stages of the compiler can also be configured, e.g., the deepening factor of the A\*-placer:
+However, the different stages of the compiler can also be configured, e.g.,
+the deepening factor of the A\*-placer:
```{code-cell} ipython3
compiler = RoutingAwareCompiler(arch, deepening_factor = 0.6)
diff --git a/docs/synthesis.md b/docs/synthesis.md
index 014ecfefa..ae04d1358 100644
--- a/docs/synthesis.md
+++ b/docs/synthesis.md
@@ -13,42 +13,69 @@ mystnb:
# Synthesis of Clifford Circuits
-Executing quantum circuits on a quantum computer requires compilation to representations that conform to all restrictions imposed by the device.
-Due to device's limited coherence times and gate fidelity, the compilation process has to be optimized as much as possible.
-To this end, an algorithm's description first has to be _synthesized_ using the device's gate library.
-In addition, circuits have to be _mapped_ to the target quantum device to satisfy its connectivity constraints.
-Even though Clifford circuits form a finite subgroup of all quantum circuits -- one that is not even universal for quantum computing -- the search space for these problems grows exponentially with respect to the number of considered qubits.
-
-The _Clifford synthesis approach_ in QMAP can be used to produce optimal Clifford circuits based on the methods proposed in {cite:p}`peham2023DepthOptimalSynthesis`.
-To this end, it encodes the underlying task as a satisfiability (SAT) problem and solves it using the [SMT solver Z3](https://github.com/Z3Prover/z3) in conjunction with a binary search scheme.
-
-The following gives a brief overview on Clifford circuits and how QMAP can be used for their synthesis.
+Executing quantum circuits on a quantum computer requires compilation to
+representations that conform to all restrictions imposed by the device.
+Due to device's limited coherence times and gate fidelity,
+the compilation process has to be optimized as much as possible.
+To this end, an algorithm's description first has to be _synthesized_ using the
+device's gate library.
+In addition, circuits have to be _mapped_ to the target quantum device to
+satisfy its connectivity constraints.
+Even though Clifford circuits form a finite subgroup of all quantum circuits --
+one that is not even universal for quantum computing -- the search space for
+these problems grows exponentially with respect to the number of considered
+qubits.
+
+The _Clifford synthesis approach_ in QMAP can be used to produce optimal
+Clifford circuits based on the methods proposed in
+{cite:p}`peham2023DepthOptimalSynthesis`.
+To this end, it encodes the underlying task as a satisfiability (SAT) problem
+and solves it using the [SMT solver Z3](https://github.com/Z3Prover/z3) in
+conjunction with a binary search scheme.
+
+The following gives a brief overview on Clifford circuits
+and how QMAP can be used for their synthesis.
## Clifford Circuits
-Clifford circuits, i.e., circuits generated from the set $\{H, S, \mathit{CNOT}\}$, form an important subclass of quantum circuits.
+Clifford circuits, i.e.,
+circuits generated from the set $\{H, S, \mathit{CNOT}\}$,
+form an important subclass of quantum circuits.
This is due to several factors
-- According to the Gottesman-Knill theorem, they can be simulated in polynomial time and space on classical computers using the _stabilizer_ formalism.
-- They can be used to describe several quantum phenomena such as superposition, entanglement, superdense coding, and teleportation.
+- According to the Gottesman-Knill theorem,
+ they can be simulated in polynomial time
+ and space on classical computers using the _stabilizer_ formalism.
+- They can be used to describe several quantum phenomena such as superposition,
+ entanglement, superdense coding, and teleportation.
- Many error correcting codes rely on them.
-Quantum states that can be obtained from the all-zero basis state $|0\dots 0\rangle$ by applying Clifford operations are called stabilizer states.
-The name originates from the fact that such a state is uniquely and efficiently described by the set of operators that generate the group of its stabilizers.
-Specifically, any _n_-qubit stabilizer state can be described by a set of _n_ Pauli strings $\pm P_{i,0}P_{i,1}P_{i,2}\dots P_{i,n-1}$, with $P_{i,j}\in\{I, X, Y, Z\}$ and $i, j\in 0,\dots, n-1$.
-Hence, two bits per qubit are needed to identify the Pauli operator, as well as one additional bit for the phase, which leads to a total of $n(2n+1)` bits needed to uniquely describe a particular stabilizer state.
-
-The stabilizer representation of a quantum state is conveniently described by a _tableau_:
-
-$$
- \begin{bmatrix}
- x_{0,0} & \cdots & x_{0,n-1} & z_{0,0} & \cdots & z_{0,n-1} & r_0 \\
- \vdots & \ddots & \vdots & \vdots & \ddots & \vdots & \vdots \\
- x_{n-1,0} & \cdots & x_{n-1,n-1} & z_{n-1,0} & \cdots & z_{n-1,n-1} & r_{n-1} \\
- \end{bmatrix}
-$$
+Quantum states that can be obtained from the all-zero basis state
+$|0\dots 0\rangle$ by applying Clifford operations are called stabilizer states.
+The name originates from the fact that such a state is uniquely
+and efficiently described by the set of operators
+that generate the group of its stabilizers.
+Specifically, any _n_-qubit stabilizer state can be described by a set of _n_
+Pauli strings $\pm P_{i,0}P_{i,1}P_{i,2}\dots P_{i,n-1}$, with
+$P_{i,j}\in\{I, X, Y, Z\}$ and $i, j\in 0,\dots, n-1$.
+Hence, two bits per qubit are needed to identify the Pauli operator,
+as well as one additional bit for the phase,
+which leads to a total of $n(2n+1)` bits needed to uniquely describe a
+particular stabilizer state.
+
+The stabilizer representation of a quantum state is conveniently described by a
+_tableau_:
+
+```{math}
+\begin{bmatrix}
+ x_{0,0} & \cdots & x_{0,n-1} & z_{0,0} & \cdots & z_{0,n-1} & r_0 \\
+ \vdots & \ddots & \vdots & \vdots & \ddots & \vdots & \vdots \\
+ x_{n-1,0} & \cdots & x_{n-1,n-1} & z_{n-1,0} & \cdots & z_{n-1,n-1} & r_{n-1} \\
+\end{bmatrix}
+```
-Here, the binary variables $x_{ij}$ and $z_{ij}$ specify whether the Pauli term $P_{i,j}$ is $X$ or $Z$, respectively.
+Here, the binary variables $x_{ij}$ and $z_{ij}$ specify
+whether the Pauli term $P_{i,j}$ is $X$ or $Z$, respectively.
Since $Y = iXZ$, setting $x_{ij} = z_{ij} = 1$ corresponds to $P_{i,j}=Y$.
Finally, $r_i$ describes whether the generator has a negative phase.
@@ -68,7 +95,7 @@ qc.draw(output="mpl")
Then, the corresponding stabilizer tableau is
-```
+```text
0 0 | 1 1 | 0
1 1 | 0 0 | 0
```
@@ -79,7 +106,10 @@ which corresponds to the stabilizers
stabilizers = ["+ZZ", "+XX"]
```
-The stabilizer tableau does not fix a unitary operator uniquely. As stated above, the stabilizers only fix the state that is obtained by applying a unitary to the all-zero basis state. The following circuit also produces the same state as the one above:
+The stabilizer tableau does not fix a unitary operator uniquely.
+As stated above, the stabilizers only fix the state
+that is obtained by applying a unitary to the all-zero basis state.
+The following circuit also produces the same state as the one above:
```{code-cell} ipython3
from qiskit import QuantumCircuit
@@ -96,17 +126,19 @@ qc_alt.draw(output="mpl")
But the first circuit has the unitary
-$$
+```{math}
\frac{1}{\sqrt{2}}\begin{bmatrix}1&0&1&0\\0&1&0&1\\0&1&0&-1\\1&0&-1&0\end{bmatrix}
-$$
+```
whereas the second circuit has the unitary
-$$
+```{math}
\frac{1}{\sqrt{2}}\begin{bmatrix}1&0&1&0\\0&-1&0&-1\\0&-1&0&1\\1&0&-1&0\end{bmatrix}
-$$
+```
-To fix the unitary one needs to also take the _destabilizers_ into account. The destabilizers are also Pauli strings that together with the stabilizers generate the entire Pauli group.
+To fix the unitary one needs to also take the _destabilizers_ into account.
+The destabilizers are also Pauli strings
+that together with the stabilizers generate the entire Pauli group.
The destabilizers of the first circuit are
@@ -122,7 +154,8 @@ destabilizers_alt = ["-IX", "+ZI"]
## Using QMAP for Optimal Synthesis
-_QMAP_ can be used in a multitude of ways to efficiently synthesize Clifford circuits:
+_QMAP_ can be used in a multitude of ways to efficiently synthesize Clifford
+circuits:
### Starting from an initial circuit `qc`
@@ -142,12 +175,18 @@ qc_opt, results = optimize_clifford(circuit=qc, use_maxsat=True, include_destabi
qc_opt.draw(output="mpl")
```
-The `include_destabilizers` flag guarantees that the unitary of the circuit is preserved during optimization.
+The `include_destabilizers` flag guarantees
+that the unitary of the circuit is preserved during optimization.
-By default _QMAP_ generates optimal Clifford circuits with respect to the target metric.
+By default _QMAP_ generates optimal Clifford circuits with respect to the target
+metric.
This might lead to runtime problems when trying to optimize larger circuits.
-When optimizing for depth, _QMAP_ provides a heuristic that splits the circuits into several independent parts and optimizes them separately.
-This allows optimizing larger circuits while not guaranteeing that the depth-optimal circuit is synthesized.
+When optimizing for depth,
+_QMAP_ provides a heuristic
+that splits the circuits into several independent parts
+and optimizes them separately.
+This allows optimizing larger circuits while not guaranteeing
+that the depth-optimal circuit is synthesized.
The heuristic synthesizer can be used as follows:
@@ -177,9 +216,11 @@ qc_opt, results = optimize_clifford(
qc_opt.draw(output="mpl")
```
-The parameter `split_size` determines how many layers of the circuit are optimized individually.
+The parameter `split_size` determines how many layers of the circuit are
+optimized individually.
-In this example the synthesized circuit does not have optimal depth as can be checked by running the optimal synthesis method:
+In this example the synthesized circuit does not have optimal depth
+as can be checked by running the optimal synthesis method:
```{code-cell} ipython3
from qiskit import QuantumCircuit
@@ -221,6 +262,9 @@ qc_synth, results = synthesize_clifford(tableau)
qc_synth.draw(output="mpl")
```
-The synthesis method offers lots of configuration options to fine-tune the synthesis procedure, e.g., changing the target metric.
+The synthesis method offers lots of configuration options to fine-tune the
+synthesis procedure, e.g., changing the target metric.
-See {func}`~mqt.qmap.plugins.qiskit.clifford_synthesis.synthesize_clifford` and {func}`~mqt.qmap.plugins.qiskit.clifford_synthesis.optimize_clifford` for more information.
+See {func}`~mqt.qmap.plugins.qiskit.clifford_synthesis.synthesize_clifford`
+and {func}`~mqt.qmap.plugins.qiskit.clifford_synthesis.optimize_clifford`
+for more information.
diff --git a/docs/tooling.md b/docs/tooling.md
index 1d534fe33..41ffe48af 100644
--- a/docs/tooling.md
+++ b/docs/tooling.md
@@ -3,8 +3,7 @@
# Tooling
-This page summarizes the main tools, software,
-and standards used in MQT QMAP.
+This page summarizes the main tools, software, and standards used in MQT QMAP.
It serves as a quick reference for new contributors
and users who want to understand the project's ecosystem.
diff --git a/eval/na/zoned/README.md b/eval/na/zoned/README.md
index 9be6747c2..471beb79a 100644
--- a/eval/na/zoned/README.md
+++ b/eval/na/zoned/README.md
@@ -1,7 +1,9 @@
# MQT QMAP's Zoned Neutral Atom Compiler Evaluation
-This document describes how to use the evaluation script for the zoned neutral atom compiler.
-The script automates the process of running QMAP on a set of benchmark circuits and collecting performance metrics.
+This document describes how to use the evaluation script
+for the zoned neutral atom compiler.
+The script automates the process of running QMAP on a set of benchmark circuits
+and collecting performance metrics.
## Prerequisites
@@ -11,7 +13,8 @@ Before running the evaluation script, ensure you have the following installed:
## Usage
-The main evaluation script is `eval_ids_relaxed_routing.py`. You can run it from the repository root via:
+The main evaluation script is `eval_ids_relaxed_routing.py`.
+You can run it from the repository root via:
```bash
eval/na/zoned/eval_ids_relaxed_routing.py
@@ -19,6 +22,9 @@ The main evaluation script is `eval_ids_relaxed_routing.py`. You can run it from
## Output
-The script produces a CSV file named `results.csv` in the directory of the script.
-Additionally, all input circuits are written to the `in` directory as QASM files.
-Furthermore, the compiled files are written to the `out` directory ordered by compiler and settings.
+The script produces a CSV file named `results.csv` in the directory of the
+script.
+Additionally, all input circuits are written to the `in` directory
+as QASM files.
+Furthermore, the compiled files are written to the `out` directory ordered by
+compiler and settings.