From 12f1995cfd6a9c8317d6720f23f218fd3c831909 Mon Sep 17 00:00:00 2001 From: "mqt-app[bot]" <219534693+mqt-app[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 14:16:20 +0000 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=93=9D=20Update=20templated=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/CONTRIBUTING.md | 3 +- .github/SECURITY.md | 10 +- .github/SUPPORT.md | 16 +- .github/pull_request_template.md | 6 +- .github/release-drafter.yml | 2 +- AGENTS.md | 78 ++-- docs/ai_usage.md | 158 +++++--- docs/contributing.md | 673 +++++++++++++++++++++---------- docs/installation.md | 374 ++++++++++------- docs/tooling.md | 26 +- 10 files changed, 889 insertions(+), 457 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8846eab503..ebc1408a80 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -4,4 +4,5 @@ # Contributing Thank you for your interest in contributing to MQT Core! -An extensive contribution guide is available in our [documentation](https://mqt.readthedocs.io/projects/core/en/latest/contributing.html). +An extensive contribution guide is available in our +[documentation](https://mqt.readthedocs.io/projects/core/en/latest/contributing.html). diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 14b2096acf..d9a6e695b9 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -9,14 +9,16 @@ Security updates are applied only to the most recent releases. ## Reporting a Vulnerability -To report vulnerabilities, you can privately report a potential security issue -via the GitHub security vulnerabilities feature. This can be done here: +To report vulnerabilities, +you can privately report a potential security issue via the GitHub security +vulnerabilities feature. +This can be done here: -https://github.com/munich-quantum-toolkit/core/security/advisories + Please do **not** open a public issue about a potential security vulnerability. You can find more details on the security vulnerability feature in the GitHub documentation here: -https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability + diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index 25daeb8c9b..6d0caf4d60 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -3,17 +3,23 @@ # Support -If you are stuck with a problem using MQT Core or have questions, please get in touch at our [Issues] or [Discussions]. +If you are stuck with a problem using MQT Core or have questions, +please get in touch at our [Issues] or [Discussions]. We'd love to help. You can save time by following this procedure when reporting a problem: - Do try to solve the problem on your own first. -- Search through past [Issues] and [Discussions] to see if someone else already had the same problem. -- Before filing a bug report, try to create a minimal reproducible example (MRE) that reproduces the problem. - It is much easier to identify the cause for the problem if a handful of lines suffice to show that something is not working. +- Search through past [Issues] and [Discussions] to see + if someone else already had the same problem. +- Before filing a bug report, + try to create a minimal reproducible example (MRE) + that reproduces the problem. + It is much easier to identify the cause for the problem + if a handful of lines suffice to show that something is not working. -You can also always reach us at [quantum.cda@xcit.tum.de](mailto:quantum.cda@xcit.tum.de). +You can also always reach us at +[quantum.cda@xcit.tum.de](mailto:quantum.cda@xcit.tum.de). [Issues]: https://github.com/munich-quantum-toolkit/core/issues [Discussions]: https://github.com/munich-quantum-toolkit/core/discussions diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f986cb3cb7..69000717d7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,7 +4,11 @@ Please include a summary of the change and, if applicable, which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -Fixes #(issue) + +Fixes #(issue) ## Checklist diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 29cc23d664..20820f5ce5 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -54,7 +54,7 @@ categories: - "github-actions" - "pre-commit" - "submodules" -change-template: "- $TITLE ([#$NUMBER]($URL)) ([**@$AUTHOR**](https://github.com/$AUTHOR))" +change-template: "- $TITLE ([#$NUMBER]($URL)) (**@$AUTHOR**)" change-title-escapes: '\<*_&' exclude-labels: - "skip-changelog" diff --git a/AGENTS.md b/AGENTS.md index fde2ce07cf..38cb3ef9c6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,16 +5,19 @@ ## C++ -- Configure: `cmake -S . -B build_cpp -DCMAKE_BUILD_TYPE=Release` -- Build: `cmake --build build_cpp --config Release` -- Test: `ctest --test-dir build_cpp -C Release` -- Single test binary: `./build_cpp/test/path/to/binary` -- For debug builds, replace `Release` with `Debug`. +- Configure: `cmake --preset release` +- Build: `cmake --build --preset release` +- Test: `ctest --preset release` +- Single test binary: `./build/release/test/path/to/binary` +- For debug builds, replace `release` with `debug`. +- For more presets, see `CMakePresets.json`. ## Python -- Set up build and test dependencies: `uv sync --inexact --only-group build --only-group test` -- Install package without build isolation (fast rebuilds): `uv sync --inexact --no-dev --no-build-isolation-package mqt-core` +- Set up build and test dependencies: + `uv sync --inexact --only-group build --only-group test` +- Install package without build isolation (fast rebuilds): + `uv sync --inexact --no-dev --no-build-isolation-package mqt-core` - Run tests: `uv run --no-sync pytest` - Nox test shortcuts: `uvx nox -s tests`, `uvx nox -s minimums` - Python 3.14 variants: `uvx nox -s tests-3.14`, `uvx nox -s minimums-3.14` @@ -22,7 +25,7 @@ ## Documentation - Sources: `docs/` -- Build MLIR docs: `cmake --build build_cpp --target mlir-doc --config Release` +- Build MLIR docs: `cmake --build --preset release --target mlir-doc` - Build docs locally: `uvx nox --non-interactive -s docs` - Link check: `uvx nox -s docs -- -b linkcheck` @@ -34,11 +37,14 @@ ### C++ -- Targets Linux (glibc 2.28+), macOS (11.0+), and Windows on x86_64 and arm64 architectures +- Targets Linux (glibc 2.28+), macOS (11.0+), + and Windows on x86_64 and arm64 architectures - C++20 - CMake 3.24+ -- `FetchContent` for dependency management (configured in `cmake/ExternalDependencies.cmake`) -- `clang-format` and `clang-tidy` for formatting/linting (see `.clang-format` and `.clang-tidy`) +- `FetchContent` for dependency management + (configured in `cmake/ExternalDependencies.cmake`) +- `clang-format` and `clang-tidy` for formatting/linting + (see `.clang-format` and `.clang-tidy`) - LLVM 22.1+ for building MLIR code - GoogleTest for unit tests (located in `test/` and `mlir/unittests/`) @@ -66,35 +72,57 @@ ### General - MUST run `uvx nox -s lint` after every batch of changes. - This runs the full `prek` hook set from `.pre-commit-config.yaml` (including `ruff`, `typos`, `ty`, formatting, and metadata checks). + This runs the full `prek` hook set from `.pre-commit-config.yaml` + (including `ruff`, `typos`, `ty`, formatting, and metadata checks). All hooks must pass before submitting. -- MUST add or update tests for every code change, even if not explicitly requested. +- MUST add or update tests for every code change, + even if not explicitly requested. - MUST follow existing code style by checking neighboring files for patterns. -- MUST update `CHANGELOG.md` and `UPGRADING.md` when changes are user-facing, breaking, or otherwise noteworthy. -- MUST include a commit footer attribution in the form `Assisted-by: [Model Name] via [Tool Name]` (example: `Assisted-by: Claude Sonnet 4.6 via GitHub Copilot`) if AI tools are used to prepare a commit. -- NEVER modify files that start with "This file has been generated from an external template. Please do not modify it directly." - These files are managed by [the MQT templates action](https://github.com/munich-quantum-toolkit/templates) and changes will be overwritten. +- MUST update `CHANGELOG.md` and `UPGRADING.md` when changes are user-facing, + breaking, or otherwise noteworthy. +- MUST include a commit footer attribution in the form + `Assisted-by: [Model Name] via [Tool Name]` (example: + `Assisted-by: Claude Sonnet 4.6 via GitHub Copilot`) if AI tools are used to + prepare a commit. +- NEVER modify files that start with "This file has been generated from an + external template. + Please do not modify it directly." + These files are managed by + [the MQT templates action](https://github.com/munich-quantum-toolkit/templates) + and changes will be overwritten. - PREFER running targeted tests over the full test suite during development. ### C++ - MUST use Doxygen-style comments. - MUST use `#pragma once` for header guards. -- MUST regenerate stubs via `uvx nox -s stubs` when files in `bindings/` are added or modified. -- NEVER edit `.pyi` files in `python/mqt/core/` manually; they are auto-generated by nanobind stubgen. +- MUST regenerate stubs via `uvx nox -s stubs` + when files in `bindings/` are added or modified. +- NEVER edit `.pyi` files in `python/mqt/core/` manually; + they are auto-generated by nanobind stubgen. - PREFER C++20 STL features over custom implementations. -- PREFER LLVM data structures and methods in `mlir/` (`llvm::SmallVector`, `llvm::function_ref`, etc.) over the STL. +- PREFER LLVM data structures and methods in `mlir/` + (`llvm::SmallVector`, `llvm::function_ref`, etc.) over the STL. ### Python - MUST use Google-style docstrings -- PREFER running a single Python version over the full test suite during development. -- PREFER fixing reported warnings over suppressing them (e.g., with `# noqa` comments for ruff); only add ignore rules when necessary and document why. -- PREFER fixing typing issues reported by `ty` before adding suppression comments (`# ty: ignore[code]`); suppressions are sometimes necessary for incompletely typed libraries (e.g., Qiskit). +- PREFER running a single Python version over the full test suite during + development. +- PREFER fixing reported warnings over suppressing them + (e.g., with `# noqa` comments for ruff); + only add ignore rules when necessary and document why. +- PREFER fixing typing issues reported by `ty` + before adding suppression comments + (`# ty: ignore[code]`); + suppressions are sometimes necessary for incompletely typed libraries + (e.g., Qiskit). ## Self-Review Checklist - Did `uvx nox -s lint` pass without errors? - Are all changes covered by at least one automated test? -- Were Python stubs regenerated via `uvx nox -s stubs` if bindings were modified? -- Are `CHANGELOG.md` and `UPGRADING.md` updated when changes are user-facing, breaking, or otherwise noteworthy? +- Were Python stubs regenerated via `uvx nox -s stubs` + if bindings were modified? +- Are `CHANGELOG.md` and `UPGRADING.md` updated when changes are user-facing, + breaking, or otherwise noteworthy? diff --git a/docs/ai_usage.md b/docs/ai_usage.md index 60404cbf99..149168dfee 100644 --- a/docs/ai_usage.md +++ b/docs/ai_usage.md @@ -3,10 +3,15 @@ # AI Usage Guidelines -We acknowledge that AI tools (Large Language Models, code completion engines like GitHub Copilot, etc.) have become helpful assistants for many developers. -We allow the use of these tools to assist with contributions, provided that their use is transparent, responsible, and that a **human remains in the loop** at all times. +We acknowledge that AI tools +(Large Language Models, code completion engines like GitHub Copilot, etc.) +have become helpful assistants for many developers. +We allow the use of these tools to assist with contributions, +provided that their use is transparent, responsible, +and that a **human remains in the loop** at all times. -This guide outlines our policy on AI-assisted contributions to ensure code quality, maintainability, and legal compliance. +This guide outlines our policy on AI-assisted contributions to ensure code +quality, maintainability, and legal compliance. ## Core Principles @@ -14,13 +19,17 @@ This guide outlines our policy on AI-assisted contributions to ensure code quali **You are responsible for every line of code you submit.** -Regardless of whether code was written by you or generated by an AI tool, you are the author and are fully accountable for the contribution. You must: +Regardless of whether code was written by you or generated by an AI tool, +you are the author and are fully accountable for the contribution. +You must: - Fully understand the code you are submitting. -- Be able to explain the reasoning behind the code and how it interacts with the rest of the codebase. +- Be able to explain the reasoning behind the code + and how it interacts with the rest of the codebase. - Verify that the code is correct, efficient, and follows our coding standards. -**Do not blindly copy-paste AI-generated code.** If you cannot explain it, do not submit it. +**Do not blindly copy-paste AI-generated code.** +If you cannot explain it, do not submit it. ### 2. Human in the Loop @@ -29,82 +38,139 @@ Regardless of whether code was written by you or generated by an AI tool, you ar When using AI tools, you must be the driver. The AI is the assistant. -- **Review:** You must read and review all AI-generated code or text before submitting it. -- **Edit:** AI-generated code often requires significant editing to meet project standards and correctness. -- **Verify:** Ensure the code actually solves the problem and doesn't introduce subtle bugs or security vulnerabilities. +- **Review:** You must read and review all AI-generated code or text + before submitting it. +- **Edit:** AI-generated code often requires significant editing to meet project + standards and correctness. +- **Verify:** Ensure the code actually solves the problem + and doesn't introduce subtle bugs or security vulnerabilities. ### 3. Communication -**Do not use AI tools to generate issue descriptions, pull request comments, or code reviews.** +**Do not use AI tools to generate issue descriptions, pull request comments, or +code reviews.** We value your personal input and communication. -LLMs are notoriously unreliable and can produce "smart-sounding" but incorrect or irrelevant claims ("hallucinations"). +LLMs are notoriously unreliable and can produce "smart-sounding" but incorrect +or irrelevant claims ("hallucinations"). Phrase your communications in your own words. -It is more important that we can follow your reasoning than that the text sounds "perfect". +It is more important that we can follow your reasoning than +that the text sounds "perfect". ### 4. Transparency and Disclosure -Transparency helps the community understand the role of these tools and develop best practices. +Transparency helps the community understand the role of these tools +and develop best practices. **We encourage you to disclose any AI assistance.** -This helps us understand how these tools are being used and identify potential issues. +This helps us understand how these tools are being used +and identify potential issues. You can disclose this information in the following ways: -- **Commit Messages**: Add a trailer to your commit message in the form `Assisted-by: [Model Name] via [Tool Name]` (example: `Assisted-by: Claude Sonnet 4.6 via GitHub Copilot`) -- **PR Description**: Mention the tool (name and version) and how it was used in the PR description. +- **Commit Messages**: Add a trailer to your commit message in the form + `Assisted-by: [Model Name] via [Tool Name]` (example: + `Assisted-by: Claude Sonnet 4.6 via GitHub Copilot`) +- **PR Description**: Mention the tool + (name and version) and how it was used in the PR description. ### 5. Licensing and Copyright -You are responsible for ensuring that your contribution does not violate any third-party licenses or copyrights. +You are responsible for ensuring +that your contribution does not violate any third-party licenses or copyrights. -- **Originality**: Your submission must be your own original work of authorship. -- **Training Data**: Be aware that some AI tools may generate code that is substantially similar to their training data. You must ensure that you have the right to contribute the generated code under [our license](https://github.com/munich-quantum-toolkit/core/blob/main/LICENSE.md). +- **Originality**: + Your submission must be your own original work of authorship. +- **Training Data**: Be aware that some AI tools may generate code + that is substantially similar to their training data. + You must ensure that you have the right to contribute the generated code under + [our license](https://github.com/munich-quantum-toolkit/core/blob/main/LICENSE). ## Extractive Contributions -Processing pull requests and comments for MQT Core requires significant maintainer time and energy. -Sending unreviewed AI output to open-source projects shifts the burden of verifying correctness from the contributor to the maintainer. -We classify such contributions as "extractive" because they consume more community resources than they provide in value. - -Our **golden rule** is that a contribution should be valuable enough to justify the review effort. -Nadia Eghbal captures this concept in her book _[Working in Public](https://press.stripe.com/working-in-public)_: - -> "When attention is being appropriated, producers need to weigh the costs and benefits of the transaction. To assess whether the appropriation of attention is net-positive, it's useful to distinguish between _extractive_ and _non-extractive_ contributions. Extractive contributions are those where the marginal cost of reviewing and merging that contribution is greater than the marginal benefit to the project's producers. In the case of a code contribution, it might be a pull request that's too complex or unwieldy to review, given the potential upside." — Nadia Eghbal - -Before AI tools became widespread, open-source project maintainers would often review all changes sent to the project simply because submitting a pull request was a sign of interest from a potential long-term contributor. -However, AI tools now allow the rapid generation of large volumes of code, which can easily overwhelm maintainers if submitted without careful review. -Our policy exists to ensure that maintainer time is spent on high-quality interactions rather than debugging AI-generated code. +Processing pull requests and comments +for MQT Core requires significant maintainer time and energy. +Sending unreviewed AI output to open-source projects shifts the burden of +verifying correctness from the contributor to the maintainer. +We classify such contributions as "extractive" +because they consume more community resources than they provide in value. + +Our **golden rule** is that a contribution should be valuable enough to justify +the review effort. +Nadia Eghbal captures this concept in her book +_[Working in Public](https://press.stripe.com/working-in-public)_: + +> "When attention is being appropriated, +> producers need to weigh the costs and benefits of the transaction. +> To assess whether the appropriation of attention is net-positive, +> it's useful to distinguish between _extractive_ +> and _non-extractive_ contributions. +> Extractive contributions are those where the marginal cost of reviewing +> and merging that contribution is greater than the marginal benefit to the +> project's producers. +> In the case of a code contribution, +> it might be a pull request that's too complex or unwieldy to review, +> given the potential upside." — Nadia Eghbal + +Before AI tools became widespread, +open-source project maintainers would often review all changes sent to the +project simply because submitting a pull request was a sign of interest from a +potential long-term contributor. +However, AI tools now allow the rapid generation of large volumes of code, +which can easily overwhelm maintainers if submitted without careful review. +Our policy exists to ensure +that maintainer time is spent on high-quality interactions rather than debugging +AI-generated code. ### Sustainable Open Source -The Munich Quantum Toolkit (MQT) is committed to remaining free, open-source, and permissively licensed. -We want to build a welcoming community where aspiring quantum software engineers can learn and grow. +The Munich Quantum Toolkit (MQT) is committed to remaining free, open-source, +and permissively licensed. +We want to build a welcoming community +where aspiring quantum software engineers can learn and grow. Reviewing contributions is a key part of this mentorship. -However, to keep the project sustainable, we must prioritize non-extractive contributions. -By thoroughly reviewing and understanding your AI-assisted code before submission, you ensure that your contribution is a net positive for the project. -This helps us maintain a healthy ecosystem where both the software and its contributors can thrive. +However, to keep the project sustainable, +we must prioritize non-extractive contributions. +By thoroughly reviewing and understanding your AI-assisted code +before submission, you ensure that your contribution is a net positive +for the project. +This helps us maintain a healthy ecosystem where both the software +and its contributors can thrive. ## Prohibited Uses -- **"Good First Issues"**: Do not use AI tools to solve issues labeled as "good first issue". These are intended as learning opportunities for new contributors. Automating them defeats the purpose. -- **Spam**: Do not use AI to generate low-quality or repetitive comments/reviews ("AI Slop"). -- **Unreviewed Code**: Submitting code that you, as a human, have not reviewed and tested yourself. +- **"Good First Issues"**: + Do not use AI tools to solve issues labeled as "good first issue". + These are intended as learning opportunities for new contributors. + Automating them defeats the purpose. +- **Spam**: Do not use AI to generate low-quality or repetitive comments/reviews + ("AI Slop"). +- **Unreviewed Code**: Submitting code that you, as a human, + have not reviewed and tested yourself. ## Summary -We want to foster a welcoming community where developers can learn and grow. AI tools can be great for productivity, but they should not replace critical thinking or the learning process. -If a maintainer judges that a contribution relies too heavily on unverified AI generation or lacks sufficient human understanding ("extractive contribution"), we may request that you revise it or close the PR. +We want to foster a welcoming community where developers can learn and grow. +AI tools can be great for productivity, +but they should not replace critical thinking or the learning process. +If a maintainer judges that a contribution relies too heavily on unverified AI +generation or lacks sufficient human understanding ("extractive contribution"), +we may request that you revise it or close the PR. --- -Parts of this guide were inspired by or adapted from the contribution guidelines of +Parts of this guide were inspired by +or adapted from the contribution guidelines of - [Astral], -- [Qiskit], -- [LLVM], including the sources therein, such as [Fedora Council Policy Proposal: Policy on AI-Assisted Contributions (fetched 2026-03-12)][fedora], which is licensed under the [Creative Commons Attribution 4.0 International License][cca]. - -with the help of Gemini 3 Pro (Preview). The links above serve as attribution. +- [Qiskit], and +- [LLVM], including the sources therein, such as + [Fedora Council Policy Proposal: Policy on AI-Assisted Contributions (fetched 2026-03-12)][fedora], + which is licensed under the + [Creative Commons Attribution 4.0 International License][cca], + +with the help of Gemini 3 Pro (Preview). +The links above serve as attribution. [Astral]: https://github.com/astral-sh/uv/blob/c89a78ec085077f6344b0439ddf07fdad7336310/CONTRIBUTING.md [Qiskit]: https://github.com/Qiskit/qiskit/blob/cd8701690723d3d9602fac63fe0bd7ea618799be/CONTRIBUTING.md#use-of-ai-tools diff --git a/docs/contributing.md b/docs/contributing.md index c199e67a2b..2d99a4c536 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -6,8 +6,12 @@ Thank you for your interest in contributing to MQT Core! This document outlines the development guidelines and how to contribute. -We use GitHub to [host code](https://github.com/munich-quantum-toolkit/core), to [track issues and feature requests][issues], as well as accept [pull requests](https://github.com/munich-quantum-toolkit/core/pulls). -See for a general introduction to working with GitHub and contributing to projects. +We use GitHub to +[host code](https://github.com/munich-quantum-toolkit/core), to +[track issues and feature requests][issues], as well as accept +[pull requests](https://github.com/munich-quantum-toolkit/core/pulls). +See +for a general introduction to working with GitHub and contributing to projects. ## Types of Contributions @@ -15,36 +19,45 @@ Pick the path that fits your time and interests: - 🐛 Report bugs: - Use the _🐛 Bug report_ template at . - Include steps to reproduce, expected vs. actual behavior, environment, and a minimal example. + Use the _🐛 Bug report_ template at + . + Include steps to reproduce, expected vs. actual behavior, environment, + and a minimal example. - 🛠️ Fix bugs: - Browse [issues][issues], especially those labeled "bug", "help wanted", or "good first issue". + Browse [issues][issues], especially those labeled "bug", "help wanted", + or "good first issue". Open a draft PR early to get feedback. - 💡 Propose features: - Use the _✨ Feature request_ template at . - Describe the motivation, alternatives considered, and (optionally) a small API sketch. + Use the _✨ Feature request_ template at + . + Describe the motivation, alternatives considered, + and (optionally) a small API sketch. - ✨ Implement features: Pick items labeled "feature" or "enhancement". - Coordinate in the issue first if the change is substantial; start with a draft PR. + Coordinate in the issue first if the change is substantial; + start with a draft PR. - 📝 Improve documentation: - Add or refine docstrings, tutorials, and examples; fix typos; clarify explanations. + Add or refine docstrings, tutorials, and examples; fix typos; + clarify explanations. Small documentation-only PRs are very welcome. - ⚡️ Performance and reliability: - Profile hot paths, add benchmarks, reduce allocations, deflake tests, and improve error messages. + Profile hot paths, add benchmarks, reduce allocations, deflake tests, + and improve error messages. - 📦 Packaging and tooling: - Improve build configuration, type hints/stubs, CI workflows, and platform wheels. + Improve build configuration, type hints/stubs, CI workflows, + and platform wheels. Incremental tooling fixes have a big impact. - 🙌 Community support: @@ -55,96 +68,135 @@ Pick the path that fits your time and interests: ## Guidelines Please adhere to the following guidelines to help the project grow sustainably. -Contributions that do not comply with these guidelines or violate our {doc}`AI Usage Guidelines ` may be rejected without further review. +Contributions that do not comply with these guidelines +or violate our {doc}`ai_usage` may be rejected without further review. ### Core Guidelines - ["Commit early and push often"](https://www.worklytics.co/blog/commit-early-push-often). -- Write meaningful commit messages, preferably using [gitmoji](https://gitmoji.dev) for additional context. +- Write meaningful commit messages, + preferably using [gitmoji](https://gitmoji.dev) for additional context. - Focus on a single feature or bug at a time and only touch relevant files. Split multiple features into separate contributions. - Add tests for new features to ensure they work as intended. - Document new features. - For user-facing changes, add a changelog entry; for breaking changes, update the upgrade guide. + For user-facing changes, add a changelog entry; for breaking changes, + update the upgrade guide. For details, see {ref}`maintaining-changelog-upgrade-guide`. - Add tests for bug fixes to demonstrate the fix. - Document your code thoroughly and ensure it is readable. -- Keep your code clean by removing debug statements, leftover comments, and unrelated code. +- Keep your code clean by removing debug statements, leftover comments, + and unrelated code. - Check your code for style and linting errors before committing. - Follow the project's coding standards and conventions. -- Be open to feedback and willing to make necessary changes based on code reviews. +- Be open to feedback and willing to make necessary changes based on code + reviews. ### AI-assisted contributions -We acknowledge the utility of AI-based coding assistants (e.g., GitHub Copilot, ChatGPT) in modern software development. -However, their use requires a high degree of responsibility and transparency to maintain code quality and licensing compliance. +We acknowledge the utility of AI-based coding agents +(e.g., Claude Code, OpenAI Codex, or GitHub Copilot) +in modern software development. +However, their use requires a high degree of responsibility +and transparency to maintain code quality and licensing compliance. -Please carefully read and follow our dedicated {doc}`AI Usage Guidelines ` before submitting any AI-assisted contribution. -In short: **You are responsible for every line of code you submit**, and a **human must always be in the loop**. +Please carefully read and follow our dedicated {doc}`ai_usage` +before submitting any AI-assisted contribution. +In short: **You are responsible for every line of code you submit**, +and a **human must always be in the loop**. We require disclosure of AI tool usage in your PR description. +If you use an agent, it will automatically read the provided {code}`AGENTS.md`, +which contains context and instructions to help the agent work on MQT Core. +For Claude Code, create a symlink with {code}`ln -s AGENTS.md CLAUDE.md` +so Claude picks up the same file. + ### Pull Request Workflow - Create PRs early. Work-in-progress PRs are welcome; mark them as drafts on GitHub. -- Use a clear title, reference related issues by number, and describe the changes. +- Use a clear title, reference related issues by number, + and describe the changes. Follow the PR template; only omit the issue reference if not applicable. -- CI runs on all supported platforms and Python versions to build, test, format, and lint. +- CI runs on all supported platforms and Python versions to build, test, format, + and lint. All checks must pass before merging. -- When ready, convert the draft to a regular PR and request a review from a maintainer. +- When ready, convert the draft to a regular PR + and request a review from a maintainer. If unsure, ask in PR comments. - If you are a first-time contributor, mention a maintainer in a comment to request a review. -- If your PR gets a "Changes requested" review, address the feedback and push updates to the same branch. + If you are a first-time contributor, + mention a maintainer in a comment to request a review. +- If your PR gets a "Changes requested" review, + address the feedback and push updates to the same branch. Do not close and reopen a new PR. Respond to comments to signal that you have addressed the feedback. - Do not resolve review comments yourself; the reviewer will do so once satisfied. -- If the reviewer suggested changes with explicit code suggestions as part of the comments, apply these directly using the GitHub UI. - This attributes the changes to the reviewer and automatically resolves the respective comments (this is an exception to the rule above). - If there are multiple suggestions that you want to apply at once, you can batch them into a single commit. - Go to the "Files changed" tab of the PR, and then click "Add suggestion to batch" for each suggestion you want to include. + Do not resolve review comments yourself; + the reviewer will do so once satisfied. +- If the reviewer suggested changes with explicit code suggestions + as part of the comments, apply these directly using the GitHub UI. + This attributes the changes to the reviewer + and automatically resolves the respective comments + (this is an exception to the rule above). + If there are multiple suggestions that you want to apply at once, + you can batch them into a single commit. + Go to the "Files changed" tab of the PR, + and then click "Add suggestion to batch" + for each suggestion you want to include. Once you are done selecting suggestions, click "Commit suggestions". Only apply suggestions manually if using the GitHub UI is not feasible. - Re-request a review after pushing changes that address feedback. - Do not squash commits locally; maintainers typically squash on merge. - Avoid rebasing or force-pushing before reviews; you may rebase after addressing feedback if desired. + Avoid rebasing or force-pushing before reviews; + you may rebase after addressing feedback if desired. ### Working with CodeRabbit -We use [CodeRabbit](https://www.coderabbit.ai/) for automated code review on pull requests. -We use this tool to ease the workload on our maintainers and to counteract the trend of sloppy AI-assisted contributions. -Note that having your PR reviewed by CodeRabbit does **not** count as an AI-assisted contribution for the purpose of the disclosure requirement mentioned above. +We often use [CodeRabbit](https://www.coderabbit.ai/) +for the initial review of PRs. +We use this tool to ease the workload on our maintainers +and to counteract the trend of sloppy AI-assisted contributions. + +Once your PR is ready, an initial review by CodeRabbit can be requested via +{code}`@coderabbitai full review`. +Just post this command as a PR comment on GitHub. +Any subsequent reviews can be requested via {code}`@coderabbitai review`. -To get the most out of it and help the project maintain its high ambitions for code quality, please follow these practices: +To get the most out of it and help the project maintain its high ambitions +for code quality, please follow these practices: -- **Review the review**: - Do not take CodeRabbit's suggestions as absolute truth. - LLMs can be overly defensive and conservative, leading to overcomplicated code. - Treat its comments as suggestions: consider them, but feel free to disagree and explain why. -- **Draft PRs**: - CodeRabbit runs on every push to non-draft PRs. - If you are still experimenting, mark your PR as a draft so that the automated review only runs when you are ready for feedback. +- **Review the review**: Do not take CodeRabbit's suggestions as absolute truth. + LLMs can be overly defensive and conservative, + leading to overcomplicated code. + Treat its comments as suggestions: consider them, + but feel free to disagree and explain why. - **Respond to comments**: Do not simply resolve CodeRabbit's comments without answering them. It learns from your replies and improves over time. If a suggestion does not apply, take a moment to explain why in a reply. - **Avoid multiple AI review bots**: - CodeRabbit performs significantly worse when other AI review bots (e.g., GitHub Copilot) are active on the same PR. - For the best results, do not tag Copilot unless you have already iterated with CodeRabbit and want an extra pass. + CodeRabbit performs significantly worse when other AI review bots + (e.g., GitHub Copilot) are active on the same PR. + For the best results, do not tag Copilot + unless you have already iterated with CodeRabbit and want an extra pass. - **Engage CodeRabbit in discussions**: - When team members are discussing code in PR comments, CodeRabbit stays silent by default. - Tag {code}`@coderabbitai` to engage it in the conversation and get its feedback on the specific points being discussed. - In particular, when you tag another person in a comment, ensure to also tag CodeRabbit. - Otherwise, you will just get an automatic "It seems like the humans are having a chat" response from CodeRabbit anyway, which does not add much value. + When team members are discussing code in PR comments, + CodeRabbit stays silent by default. + Tag {code}`@coderabbitai` to engage it in the conversation + and get its feedback on the specific points being discussed. + In particular, when you tag another person in a comment, + ensure to also tag CodeRabbit. + Otherwise, you will just get an automatic "It seems like the humans are having + a chat" response from CodeRabbit anyway, which does not add much value. - **Let CodeRabbit resolve comments**: - Wait until after the next push before considering resolving CodeRabbit's comments manually. - CodeRabbit will automatically resolve comments that it thinks have been addressed by your changes. + Wait until after the next push + before considering resolving CodeRabbit's comments manually. + CodeRabbit will automatically resolve comments + that it thinks have been addressed by your changes. Sometimes, it gets stuck, at which point you may resolve it manually. -- **Manual review on drafts**: - You can trigger a full review on a draft PR by commenting with {code}`@coderabbitai full review`. -- **Continuing after reviews are paused**: - CodeRabbit has a default threshold for the number of reviews it performs on a PR before pausing further reviews to avoid spamming. - If you want to resume reviews, you can ask CodeRabbit to resume by commenting with {code}`@coderabbitai resume`. - Note that this will not trigger a review immediately; it will just allow CodeRabbit to perform reviews on the next push or manual trigger. + +Note that having your PR reviewed by CodeRabbit does **not** count +as an AI-assisted contribution +for the purpose of the disclosure requirement mentioned above. ## Get Started 🎉 @@ -155,179 +207,274 @@ We will guide you through the process. ## Installation -Check out our {ref}`installation guide for developers ` for instructions on how to set up your development environment. +Check out our {ref}`installation guide for developers ` +for instructions on how to set up your development environment. ## Working on the C++ Library -Building the project requires a C++20-capable [C++ compiler](https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers) and [CMake](https://cmake.org/) 3.24 or newer. -As of August 2025, our CI pipeline on GitHub continuously tests the library across the following matrix of systems and compilers: +Building the project requires a C++20-capable +[C++ compiler](https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers) +and [CMake](https://cmake.org/) 3.24 or newer. +As of August 2025, our CI pipeline on GitHub continuously tests the library +across the following matrix of systems and compilers: -- {code}`ubuntu-24.04`: {code}`Release` and {code}`Debug` builds using {code}`gcc` +- {code}`ubuntu-24.04`: {code}`Release` + and {code}`Debug` builds using {code}`gcc` - {code}`ubuntu-24.04-arm`: {code}`Release` build using {code}`gcc` -- {code}`macos-15`: {code}`Release` and {code}`Debug` builds using {code}`AppleClang` -- {code}`macos-15-intel`: {code}`Release` build using {code}`AppleClang` -- {code}`windows-2025`: {code}`Release` and {code}`Debug` builds using {code}`msvc` +- {code}`macos-26`: {code}`Release` + and {code}`Debug` builds using {code}`AppleClang` +- {code}`macos-26-intel`: {code}`Release` build using {code}`AppleClang` +- {code}`windows-2025`: {code}`Release` + and {code}`Debug` builds using {code}`msvc` - {code}`windows-11-arm`: {code}`Release` build using {code}`msvc` -To access the latest build logs, visit the [GitHub Actions page](https://github.com/munich-quantum-toolkit/core/actions/workflows/ci.yml). +To access the latest build logs, visit the +[GitHub Actions page](https://github.com/munich-quantum-toolkit/core/actions/workflows/ci.yml). -Additionally, we regularly run extensive tests with an even wider matrix of compilers and operating systems. +Additionally, we regularly run extensive tests with an even wider matrix of +compilers and operating systems. We are not aware of any issues with other compilers or operating systems. If you encounter any problems, please [open an issue][issues] and let us know. ### Configure and Build :::{tip} -We recommend using an IDE like [CLion][clion] or [Visual Studio Code][vscode] for development. -Both IDEs have excellent support for CMake projects and provide a convenient way to run CMake and build the project. -If you prefer to work on the command line, the following instructions will guide you through the process. +We recommend using an IDE like [CLion][clion] or [Visual Studio Code][vscode] +for development. +Both IDEs have excellent support for CMake projects +and provide a convenient way to run CMake and build the project. +If you prefer to work on the command line, +the following instructions will guide you through the process. ::: -Our projects use CMake as the main build configuration tool. +This project uses CMake as the main build configuration tool. +To standardize the configuration, we provide +[CMake presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html). + Building a project using CMake is a two-stage process. First, CMake needs to be _configured_ by calling: ```console -$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release +cmake --preset release ``` -This tells CMake to - -- search the current directory {code}`.` (passed via {code}`-S`) for a {code}`CMakeLists.txt` file, -- process it into a directory {code}`build` (passed via {code}`-B`), and -- configure a {code}`Release` build (passed via {code}`-DCMAKE_BUILD_TYPE`) as opposed to, e.g., a {code}`Debug` build. +Under the hood, this effectively calls +`cmake -S . -B build/release -DCMAKE_BUILD_TYPE=Release` and configures a +{code}`Release` build. +A {code}`Debug` build can be requested by using the {code}`debug` preset. +If you are on Windows, use the `release-windows` and `debug-windows` presets. After configuring CMake, the project can be _built_ by calling: ```console -$ cmake --build build --config Release +cmake --build --preset release ``` -This builds the project in the {code}`build` directory (passed via {code}`--build`). -Some operating systems and development environments explicitly require a configuration to be set, which is why the {code}`--config` flag is also passed to the build command. -The flag {code}`--parallel ` may be added to trigger a parallel build. +This command is equivalent to `cmake --build build/release --config Release`. +The flag {code}`--parallel ` may be added to trigger a +parallel build. Building the project this way generates -- the main project libraries in the {code}`build/src` directory and -- some test executables in the {code}`build/test` directory. +- the main project libraries in the {code}`build/release/src` directory and +- some test executables in the {code}`build/release/test` directory. :::{note} -This project uses CMake's [{code}`FetchContent`](https://cmake.org/cmake/help/latest/module/FetchContent.html) module to download and build its dependencies. -Because of this, the first time you configure the project, you will need an active internet connection to fetch the required libraries. +This project uses CMake's +[{code}`FetchContent`](https://cmake.org/cmake/help/latest/module/FetchContent.html) +module to download and build its dependencies. +Because of this, the first time you configure the project, +you will need an active internet connection to fetch the required libraries. However, there are several ways to bypass these downloads: - **Use system-installed dependencies**: - If the dependencies are already installed on your system and Find-modules exist for them, {code}`FetchContent` will use those versions instead of downloading them. -- **Provide a local copy**: - If you have local copies of the dependencies (from a previous build or another project), you can point {code}`FetchContent` to them by passing the [{code}`-DFETCHCONTENT_SOURCE_DIR_`](https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_SOURCE_DIR_%3CuppercaseName%3E) flag to your CMake configure step. - The {code}`` should be replaced with the name of the dependency as specified in the project's CMake files. + If the dependencies are already installed on your system + and Find-modules exist for them, + {code}`FetchContent` will use those versions instead of downloading them. +- **Provide a local copy**: If you have local copies of the dependencies + (from a previous build or another project), + you can point {code}`FetchContent` to them by passing the + [{code}`-DFETCHCONTENT_SOURCE_DIR_`](https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_SOURCE_DIR_%3CuppercaseName%3E) + flag to your CMake configure step. + The {code}`` should be replaced with the name of the dependency + as specified in the project's CMake files. - **Use project-specific options**: - Some projects provide specific CMake options to use a system-wide dependency instead of downloading it. + Some projects provide specific CMake options to use a system-wide dependency + instead of downloading it. Check the project's documentation or CMake files for these types of flags. ::: ### Running the C++ Tests and Code Coverage -We use the [GoogleTest](https://google.github.io/googletest/primer.html) framework for unit testing of the C++ library. -All tests are contained in the {code}`test` directory, which is further divided into subdirectories for different parts of the library. -You are expected to write tests for any new features you implement and ensure that all tests pass. +We use the [GoogleTest](https://google.github.io/googletest/primer.html) +framework for unit testing of the C++ library. +All tests are contained in the {code}`test` directory, +which is further divided into subdirectories for different parts of the library. +You are expected to write tests for any new features you implement and ensure +that all tests pass. Our CI pipeline on GitHub will also run the tests and check for any failures. -It will also collect code coverage information and upload it to [Codecov](https://codecov.io/gh/munich-quantum-toolkit/core). -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 and not just exercise the code paths. -Most IDEs like [CLion][clion] or [Visual Studio Code][vscode] provide a convenient way to run the tests directly from the IDE. -If you prefer to run the tests from the command line, you can use CMake's test runner [CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html). -To run the tests, run the following command from the main project directory after building the project as described above: +Most IDEs like [CLion][clion] +or [Visual Studio Code][vscode] provide a convenient way to run the tests +directly from the IDE. +If you prefer to run the tests from the command line, +you can use CMake's test runner +[CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html). +To run the tests, run the following command from the main project directory +after building the project as described above: ```console -$ ctest -C Release --test-dir build +ctest --preset release ``` :::{tip} -If you want to disable configuring and building the C++ tests, you can pass {code}`-DBUILD_MQT_CORE_TESTS=OFF` to the CMake configure step. +If you want to disable configuring and building the C++ tests, +you can pass {code}`-DBUILD_MQT_CORE_TESTS=OFF` to the CMake +configure step. ::: -### C++ Code Formatting and Linting +Our CI pipeline on GitHub also collects code coverage information +and uploads it to +[Codecov](https://codecov.io/gh/munich-quantum-toolkit/core). +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 +and not just exercise the code paths. -This project mostly follows the [LLVM Coding Standard](https://llvm.org/docs/CodingStandards.html), which is a set of guidelines for writing C++ code. -To ensure the quality of the code and that it conforms to these guidelines, we use: +If you want to enable coverage locally, you can use the `coverage` preset: -- [`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/), a static analysis tool that checks for common mistakes in C++ code, and -- [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html), a tool that automatically formats C++ code according to a given style guide. - -Common IDEs like [CLion][clion] or [Visual Studio Code][vscode] have plugins that can automatically run {code}`clang-tidy` on the code and automatically format it with {code}`clang-format`. +```console +cmake --preset coverage +cmake --build --preset coverage +ctest --preset coverage +``` -- If you are using CLion, you can configure the project to use the {code}`.clang-tidy` and {code}`.clang-format` files in the project root directory. -- If you are using Visual Studio Code, you can install the [clangd extension](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd). +### C++ Code Formatting and Linting -They will automatically execute {code}`clang-tidy` on your code and highlight any issues. +This project mostly follows the +[LLVM Coding Standard](https://llvm.org/docs/CodingStandards.html), which is a +set of guidelines for writing C++ code. +To ensure the quality of the code and that it conforms to these guidelines, +we use: + +- [`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/), + a static analysis tool that checks for common mistakes in C++ code, and +- [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html), + a tool that automatically formats C++ code according to a given style guide. + +Common IDEs like [CLion][clion] or [Visual Studio Code][vscode] have plugins +that can automatically run {code}`clang-tidy` on the code +and automatically format it with {code}`clang-format`. + +- If you are using CLion, + you can configure the project to use the {code}`.clang-tidy` + and {code}`.clang-format` files in the project root directory. +- If you are using [Visual Studio Code][vscode], you can install the + [clangd extension](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd). + +They will automatically execute {code}`clang-tidy` on your code +and highlight any issues. In many cases, they also provide quick-fixes for these issues. -Furthermore, they provide a command to automatically format your code according to the given style. +Furthermore, they provide a command to automatically format your code according +to the given style. :::{note} -After configuring CMake, you can run {code}`clang-tidy` on a file by calling the following command: +After configuring CMake with the `lint` preset, +you can run {code}`clang-tidy` on a file by calling the following command: ```console -$ clang-tidy -- -I +clang-tidy -- -I ``` -Here, {code}`` is the file you want to analyze and {code}`` is the path to the {code}`include` directory of the project. +Here, {code}`` is the file you want to analyze +and {code}`` is the path to the {code}`include` +directory of the project. ::: -Our {code}`pre-commit` configuration also includes {code}`clang-format`. -If you have installed {code}`pre-commit`, it will automatically run {code}`clang-format` on your code before each commit. -If you do not have {code}`pre-commit` set up, the [pre-commit.ci](https://pre-commit.ci) bot will run {code}`clang-format` on your code and automatically format it according to the style guide. +Our [{code}`prek`][prek] configuration also includes {code}`clang-format`. +If you have installed {code}`prek`, +it will automatically run {code}`clang-format` on your code before each commit. +If you do not have {code}`prek` set up, +the [pre-commit.ci](https://pre-commit.ci) bot will run {code}`clang-format` on +your code and automatically format it according to the style guide. :::{tip} -Remember to pull the changes back into your local repository after the bot has formatted your code to avoid merge conflicts. +Remember to pull the changes back into your local repository +after the bot has formatted your code to avoid merge conflicts. ::: -Our CI pipeline will also run {code}`clang-tidy` over the changes in your PR and report any issues it finds. -Due to technical limitations, the workflow can only post PR comments if the changes are not coming from a fork. -If you are working on a fork, you can still see the {code}`clang-tidy` results either in the GitHub Actions logs, on the workflow summary page, or in the "Files changed" tab of the PR. +Our CI pipeline will also run {code}`clang-tidy` over the changes in your PR +and report any issues it finds. +Due to technical limitations, +the workflow can only post PR comments +if the changes are not coming from a fork. +If you are working on a fork, +you can still see the {code}`clang-tidy` results either in the GitHub Actions +logs, on the workflow summary page, or in the "Files changed" tab of the PR. ### C++ Documentation -Historically, the C++ part of the code base has not been sufficiently documented. -Given the substantial size of the code base, we have set ourselves the goal to improve the documentation over time. -We expect any new additions to the code base to be documented using [Doxygen](https://www.doxygen.nl/index.html) comments. -When touching existing code, we encourage you to add Doxygen comments to the code you touch or refactor. +Historically, the C++ part of the code base has not been sufficiently +documented. +Given the substantial size of the code base, +we have set ourselves the goal to improve the documentation over time. +We expect any new additions to the code base to be documented using +[Doxygen](https://www.doxygen.nl/index.html) comments. +When touching existing code, +we encourage you to add Doxygen comments to the code you touch or refactor. -For some tips on how to write good Doxygen comments, see the [Doxygen Manual](https://www.doxygen.nl/manual/docblocks.html). +For some tips on how to write good Doxygen comments, +see the [Doxygen Manual](https://www.doxygen.nl/manual/docblocks.html). -The C++ API documentation is integrated into the overall documentation that we host on ReadTheDocs using the [breathe](https://breathe.readthedocs.io/en/latest/) extension for Sphinx. -See {ref}`working-on-documentation` for more information on how to build the documentation. +The C++ API documentation is integrated into the overall documentation +that we host on ReadTheDocs using the +[breathe](https://breathe.readthedocs.io/en/latest/) extension for Sphinx. +See {ref}`working-on-documentation` +for more information on how to build the documentation. ## Working on the Python Package -We use [{code}`nanobind`](https://nanobind.readthedocs.io/) to expose large parts of the C++ core library to Python. -This allows us to keep the performance-critical parts of the code in C++ while providing a convenient interface for Python users. -All code related to C++-Python bindings is contained in the {code}`bindings` directory. +We use [{code}`nanobind`](https://nanobind.readthedocs.io/) to expose large +parts of the C++ core library to Python. +This allows us to keep the performance-critical parts of the code in C++ +while providing a convenient interface for Python users. +All code related to C++-Python bindings is contained in the {code}`bindings` +directory. :::{tip} -To build only the Python bindings, pass {code}`-DBUILD_MQT_CORE_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. -In [CLion][clion], you can enable an option to pass the current Python interpreter to CMake. -Go to {code}`Preferences` -> {code}`Build, Execution, Deployment` -> {code}`CMake` -> {code}`Python Integration` and check the box {code}`Pass Python Interpreter to CMake`. -Alternatively, you can pass {code}`-DPython_ROOT_DIR=` to the configure step to point CMake to a specific Python installation. +To build only the Python bindings, +pass {code}`-DBUILD_MQT_CORE_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. +In [CLion][clion], you can enable an option to pass the current Python +interpreter to CMake. +Go to {code}`Preferences` -> {code}`Build, Execution, Deployment` -> +{code}`CMake` -> {code}`Python Integration` and check the box +{code}`Pass Python Interpreter to CMake`. +Alternatively, you can pass {code}`-DPython_ROOT_DIR=` to the +configure step to point CMake to a specific Python installation. ::: -The Python package itself lives in the {code}`python/mqt/core` directory. +The Python package itself lives in the {code}`python/mqt/core` +directory. The package lives in the {code}`src/mqt/core` directory. -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, see our {ref}`installation guide for developers `. +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, +see our {ref}`installation guide for developers `. We define some convenient {code}`nox` sessions in our {code}`noxfile.py`: @@ -341,122 +488,159 @@ These are explained in more detail in the following sections. ## Running the Python Tests -The Python code is tested by unit tests using the [{code}`pytest`](https://docs.pytest.org/en/latest/) framework. +The Python code is tested by unit tests using the +[{code}`pytest`](https://docs.pytest.org/en/latest/) framework. The corresponding test files can be found in the {code}`test/python` directory. A {code}`nox` session is provided to conveniently run the Python tests. ```console -$ nox -s tests +nox -s tests ``` -This command automatically builds the project and runs the tests on all supported Python versions. -For each Python version, it will create a virtual environment (in the {code}`.nox` directory) and install the project into it. -We take extra care to install the project without build isolation so that rebuilds are typically very fast. +This command automatically builds the project +and runs the tests on all supported Python versions. +For each Python version, it will create a virtual environment +(in the {code}`.nox` directory) and install the project into it. +We take extra care to install the project without build isolation so +that rebuilds are typically very fast. -If you only want to run the tests on a specific Python version, you can pass the desired Python version to the {code}`nox` command. +If you only want to run the tests on a specific Python version, +you can pass the desired Python version to the {code}`nox` command. ```console -$ nox -s tests-3.14 +nox -s tests-3.14 ``` :::{note} -If you do not want to use {code}`nox`, you can also run the tests directly using {code}`pytest`. -This requires that you have the project and its test dependencies installed in your virtual environment (e.g., by running {code}`uv sync`). +If you do not want to use {code}`nox`, +you can also run the tests directly using {code}`pytest`. +This requires that you have the project +and its test dependencies installed in your virtual environment +(e.g., by running {code}`uv sync`). ```console -(.venv) $ pytest +pytest ``` ::: -We provide an additional nox session {code}`minimums` that makes use of {code}`uv`'s {code}`--resolution=lowest-direct` flag to install the lowest possible versions of the direct dependencies. -This ensures that the project can still be built and the tests pass with the minimum required versions of the dependencies. +We provide an additional nox session {code}`minimums` +that makes use of {code}`uv`'s {code}`--resolution=lowest-direct` flag to +install the lowest possible versions of the direct dependencies. +This ensures that the project can still be built +and the tests pass with the minimum required versions of the dependencies. ```console -$ nox -s minimums +nox -s minimums ``` ## Python Code Formatting and Linting -The Python code is formatted and linted using a collection of [{code}`pre-commit`][pre-commit] hooks. +The Python code is formatted and linted using a collection of pre-commit hooks. This collection includes -- [ruff][ruff], an extremely fast Python linter and formatter written in Rust, and +- [ruff][ruff], an extremely fast Python linter and formatter written in Rust, + and - [ty][ty], Astral's type checker for Python. -The hooks can be installed by running the following command in the root directory: +The hooks can be installed by running the following command in the root +directory: ```console -$ prek install +prek install ``` -This will install the hooks in the {code}`.git/hooks` directory of the repository. +This will install the hooks in the {code}`.git/hooks` directory of the +repository. The hooks will be executed whenever you commit changes. You can also run the {code}`nox` session {code}`lint` to run the hooks manually. ```console -$ nox -s lint +nox -s lint ``` :::{note} -If you do not want to use {code}`nox`, you can also run the hooks manually by using {code}`prek`. +If you do not want to use {code}`nox`, +you can also run the hooks manually by using [{code}`prek`][prek]. ```console -$ prek run --all-files +prek run --all-files ``` ::: ## Python Documentation -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. - -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/core` directory. +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. + +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/core` 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 automatically. +Instead, you can use the {code}`nox` session {code}`stubs` to regenerate them +automatically. ```console nox -s stubs ``` -The Python API documentation is integrated into the overall documentation that we host on ReadTheDocs using the -[{code}`sphinx-autoapi`](https://sphinx-autoapi.readthedocs.io/en/latest/) extension for Sphinx. +The Python API documentation is integrated into the overall documentation +that we host on ReadTheDocs using the +[{code}`sphinx-autoapi`](https://sphinx-autoapi.readthedocs.io/en/latest/) +extension for Sphinx. (working-on-documentation)= ## Working on the Documentation -The documentation is written in [MyST](https://myst-parser.readthedocs.io/en/latest/index.html) (a flavor of Markdown) and built using [Sphinx](https://www.sphinx-doc.org/en/master/). +The documentation is written in +[MyST](https://myst-parser.readthedocs.io/en/latest/index.html) (a flavor of +Markdown) and built using [Sphinx](https://www.sphinx-doc.org/en/master/). The documentation source files can be found in the {code}`docs/` directory. -On top of the API documentation, we provide a set of tutorials and examples that demonstrate how to use the library. -These are written in Markdown using [myst-nb](https://myst-nb.readthedocs.io/en/latest/), which allows executing Python code blocks in the documentation. -The code blocks are executed during the documentation build process, and the output is included in the documentation. -This allows us to provide up-to-date examples and tutorials that are guaranteed to work with the latest version of the library. +On top of the API documentation, +we provide a set of tutorials and examples +that demonstrate how to use the library. +These are written in Markdown using +[myst-nb](https://myst-nb.readthedocs.io/en/latest/), which allows executing +Python code blocks in the documentation. +The code blocks are executed during the documentation build process, +and the output is included in the documentation. +This allows us to provide up-to-date examples and tutorials +that are guaranteed to work with the latest version of the library. You can build the documentation using the {code}`nox` session {code}`docs`. ```console -$ nox -s docs +nox -s docs ``` -This will install all dependencies for building the documentation in an isolated environment, build the Python package, and then build the documentation. +This will install all dependencies +for building the documentation in an isolated environment, +build the Python package, and then build the documentation. It will then host the documentation on a local web server for you to view. :::{note} -If you do not want to use {code}`nox`, you can also build the documentation directly using {code}`sphinx-build`. -This requires that you have the project and its documentation dependencies installed in your virtual environment (e.g., by running {code}`uv sync`). +If you do not want to use {code}`nox`, +you can also build the documentation directly using {code}`sphinx-build`. +This requires that you have the project +and its documentation dependencies installed in your virtual environment +(e.g., by running {code}`uv sync`). ```console -(.venv) $ sphinx-build -b html docs/ docs/_build +sphinx-build -b html docs/ docs/_build ``` The docs can then be found in the {code}`docs/_build` directory. @@ -468,31 +652,50 @@ The docs can then be found in the {code}`docs/_build` directory. If something goes wrong, the CI pipeline will notify you. Here are some tips for finding the cause of certain failures: -- If any of the {code}`CI / 🇨‌ Test` checks fail, this indicates build errors or test failures in the C++ part of the code base. +- If any of the {code}`CI / 🇨‌ Test` checks fail, + this indicates build errors or test failures in the C++ part of the code base. Look through the respective logs on GitHub for any error or failure messages. -- If any of the {code}`CI / 🐍 Test` checks fail, this indicates build errors or test failures in the Python part of the code base. +- If any of the {code}`CI / 🐍 Test` checks fail, + this indicates build errors + or test failures in the Python part of the code base. Look through the respective logs on GitHub for any error or failure messages. -- If any of the {code}`codecov/\*` checks fail, this means that your changes are not appropriately covered by tests or that the overall project coverage decreased too much. +- If any of the {code}`codecov/\*` checks fail, + this means that your changes are not appropriately covered by tests or + that the overall project coverage decreased too much. Ensure that you include tests for all your changes in the PR. -- If {code}`cpp-linter` comments on your PR with a list of warnings, these have been raised by {code}`clang-tidy` when checking the C++ part of your changes for warnings or style guideline violations. - The individual messages frequently provide helpful suggestions on how to fix the warnings. - If you don't see any messages, but the {code}`🇨‌ Lint / 🚨 Lint` check is red, click on the {code}`Details` link to see the full log of the check and a step summary. - -- If the {code}`pre-commit.ci` check fails, some of the {code}`pre-commit` checks failed and could not be fixed automatically by the _pre-commit.ci_ bot. - The individual log messages frequently provide helpful suggestions on how to fix the warnings. - -- If the {code}`docs/readthedocs.org:\*` check fails, the documentation could not be built properly. +- If {code}`cpp-linter` comments on your PR with a list of warnings, + these have been raised by {code}`clang-tidy` + when checking the C++ part of your changes for warnings + or style guideline violations. + The individual messages frequently provide helpful suggestions on how to fix + the warnings. + If you don't see any messages, but the {code}`🇨‌ Lint / 🚨 Lint` check is red, + click on the {code}`Details` link to see the full log of the check + and a step summary. + +- If the {code}`pre-commit.ci` check fails, + some of the {code}`prek` checks failed + and could not be fixed automatically by the + [pre-commit.ci](https://pre-commit.ci) bot. + The individual log messages frequently provide helpful suggestions on how to + fix the warnings. + +- If the {code}`docs/readthedocs.org:\*` check fails, + the documentation could not be built properly. Inspect the corresponding log file for any errors. (maintaining-changelog-upgrade-guide)= ## Maintaining the Changelog and Upgrade Guide -MQT Core adheres to [Semantic Versioning], with the exception that minor releases may include breaking changes. -To inform users about changes to the project, we maintain a {doc}`changelog ` and an {doc}`upgrade guide `. +MQT Core adheres to [Semantic Versioning], +with the exception that minor releases may include breaking changes. +To inform users about changes to the project, +we maintain a {doc}`changelog ` +and an {doc}`upgrade guide `. If your PR includes noteworthy changes, please update the changelog. The format is based on a mixture of [Keep a Changelog] and [Common Changelog]. @@ -508,63 +711,87 @@ There are the following categories: When updating the changelog, follow these guidelines: - Add a changelog entry for every user-facing change in your PR. -- Write entries in the imperative mood (e.g., "Add support for X" or "Fix bug in Y"). +- Write entries in the imperative mood + (e.g., "Add support for X" or "Fix bug in Y"). - A single PR may result in multiple changelog entries. -- Entries in each category are sorted by merge time, with the latest PR appearing first. +- Entries in each category are sorted by merge time, + with the latest PR appearing first. - Each entry links to the PR and all contributing authors. The links are defined at the bottom of the file. - If this is your first contribution to this project, do not forget to add a link to your GitHub profile. - -If your PR introduces major or breaking changes, or if you think additional context would help users, please also add a section to the upgrade guide. -The upgrade guide is intended to provide a general overview of significant changes in a more descriptive and prose-oriented form than the changelog. -Use it to explain how users may need to adapt their usage of MQT Core, highlight new workflows, or clarify the impact of important updates. -Feel free to write in a style that is helpful and accessible for users seeking to understand the broader implications of recent changes. + If this is your first contribution to this project, + do not forget to add a link to your GitHub profile. + +If your PR introduces major or breaking changes, +or if you think additional context would help users, +please also add a section to the upgrade guide. +The upgrade guide is intended to provide a general overview of significant +changes in a more descriptive and prose-oriented form than the changelog. +Use it to explain how users may need to adapt their usage of MQT Core, +highlight new workflows, or clarify the impact of important updates. +Feel free to write in a style that is helpful and accessible +for users seeking to understand the broader implications of recent changes. ## Releasing a New Version -When it is time to release a new version of MQT Core, create a PR that prepares the release. +When it is time to release a new version of MQT Core, +create a PR that prepares the release. This PR should: - add new version titles in both the changelog and the upgrade guide, - add the release date to the changelog entry for the new version, - update the version links at the bottom of both files, -- review and streamline all changelog and upgrade guide entries for clarity and consistency, +- review and streamline all changelog and upgrade guide entries for clarity + and consistency, - ensure that all links (to PRs, authors, etc.) are defined and correct, -- double-check that the changelog comprehensively covers all changes since the last release and that nothing is missing, -- review the upgrade guide to ensure it covers all major or breaking changes and provides helpful context, and -- if the upgrade guide contains a section relevant to the release, add a reference to it in the changelog. - -Before merging the PR preparing the release, check the GitHub release draft generated by the Release Drafter for unlabelled PRs. -Unlabelled PRs would appear at the top of the release draft below the main heading. -If you missed updating labels before merging, you can still update them and re-run the Release Drafter afterward. +- double-check that the changelog comprehensively covers all changes + since the last release and that nothing is missing, +- review the upgrade guide to ensure it covers all major or breaking changes + and provides helpful context, and +- if the upgrade guide contains a section relevant to the release, + add a reference to it in the changelog. + +Before merging the PR preparing the release, +check the GitHub release draft generated by the Release Drafter +for unlabelled PRs. +Unlabelled PRs would appear at the top of the release draft below the main +heading. +If you missed updating labels before merging, +you can still update them and re-run the Release Drafter afterward. Furthermore, check whether the version number in the release draft is correct. -The version number in the release draft is dictated by the presence of certain labels on the PRs involved in a release. +The version number in the release draft is dictated by the presence of certain +labels on the PRs involved in a release. By default, a patch release will be created. -If any PR has the {code}`minor` or {code}`major` label, a minor or major release will be created, respectively. +If any PR has the {code}`minor` or {code}`major` label, +a minor or major release will be created, respectively. :::{note} -Sometimes, Dependabot or Renovate will tag a PR updating a dependency with a {code}`minor` or {code}`major` label because the dependency update itself is a minor or major release. -This does not mean that the dependency update itself is a breaking change for MQT Core. -If you are sure that the dependency update does not introduce any breaking changes for MQT Core, 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. +Sometimes, Dependabot or Renovate will tag a PR updating a dependency with a +{code}`minor` or {code}`major` label because the dependency update itself is a +minor or major release. +This does not mean that the dependency update itself is a breaking change +for MQT Core. +If you are sure that the dependency update does not introduce any breaking +changes for MQT Core, 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. ::: Once everything is in order, you can merge the PR preparing the release. -Afterward, navigate to the [Releases page](https://github.com/munich-quantum-toolkit/core/releases) on GitHub, edit the release draft if necessary, and publish the release. +Afterward, navigate to the +[Releases page](https://github.com/munich-quantum-toolkit/core/releases) on +GitHub, edit the release draft if necessary, and publish the release. - [clion]: https://www.jetbrains.com/clion/ -[ty]: https://docs.astral.sh/ty/ +[vscode]: https://code.visualstudio.com/ [nox]: https://nox.thea.codes/en/stable/ -[issues]: https://github.com/munich-quantum-toolkit/core/issues -[pipx]: https://pypa.github.io/pipx/ -[pre-commit]: https://pre-commit.com/ +[prek]: https://prek.j178.dev [ruff]: https://docs.astral.sh/ruff/ -[uv]: https://docs.astral.sh/uv/ -[vscode]: https://code.visualstudio.com/ +[ty]: https://docs.astral.sh/ty/ +[issues]: https://github.com/munich-quantum-toolkit/core/issues [Keep a Changelog]: https://keepachangelog.com/en/1.1.0/ [Common Changelog]: https://common-changelog.org [Semantic Versioning]: https://semver.org/spec/v2.0.0.html diff --git a/docs/installation.md b/docs/installation.md index 73bbb886f8..2c658e5d4d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -4,33 +4,42 @@ # Installation MQT Core is primarily developed as a C++20 library with Python bindings. -The Python package is available on [PyPI](https://pypi.org/project/mqt.core/) and can be installed on all major operating systems with all [officially supported Python versions](https://devguide.python.org/versions/). +The Python package is available on +[PyPI](https://pypi.org/project/mqt.core/) and can be installed on all +major operating systems with all +[officially supported Python versions](https://devguide.python.org/versions/). :::::{tip} :name: uv-recommendation We recommend using [{code}`uv`][uv]. -It is a fast Python package and project manager by [Astral](https://astral.sh/) (creators of [{code}`ruff`][ruff]). -It can replace {code}`pip` and {code}`virtualenv`, automatically manages virtual environments, installs packages, and can install Python itself. +It is a fast Python package and project manager by [Astral](https://astral.sh/) +(creators of [{code}`ruff`][ruff]). +It can replace {code}`pip` and {code}`virtualenv`, +automatically manages virtual environments, installs packages, +and can install Python itself. It is significantly faster than {code}`pip`. If you do not have {code}`uv` installed, install it with: ::::{tab-set} -:::{tab-item} macOS and Linux + +:::{tab-item} Linux and macOS ```console -$ curl -LsSf https://astral.sh/uv/install.sh | sh +curl -LsSf https://astral.sh/uv/install.sh | sh ``` ::: -:::{tab-item} Windows + +:::{tab-item} Windows (PowerShell) ```console -$ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" +powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` ::: + :::: See the [uv documentation][uv] for more information. @@ -44,7 +53,7 @@ See the [uv documentation][uv] for more information. :sync: uv ```console -$ uv pip install mqt.core +uv pip install mqt.core ``` ::: @@ -53,24 +62,28 @@ $ uv pip install mqt.core :sync: pip ```console -(.venv) $ python -m pip install mqt.core +python -m pip install mqt.core ``` ::: + :::: -In most cases, no compilation is required; a platform-specific prebuilt wheel is downloaded and installed. +In most cases, no compilation is required; +a platform-specific prebuilt wheel is downloaded and installed. Verify the installation: ```console -(.venv) $ python -c "import mqt.core; print(mqt.core.__version__)" +python -c "import mqt.core; print(mqt.core.__version__)" ``` This prints the installed package version. ## Building from Source for Performance -To get the best performance and enable platform-specific optimizations not available in portable wheels, we recommend building the library from source: +To get the best performance +and enable platform-specific optimizations not available in portable wheels, +we recommend building the library from source: ::::{tab-set} :sync-group: installer @@ -79,7 +92,7 @@ To get the best performance and enable platform-specific optimizations not avail :sync: uv ```console -$ uv pip install mqt.core --no-binary mqt.core +uv pip install mqt.core --no-binary mqt.core ``` ::: @@ -88,16 +101,21 @@ $ uv pip install mqt.core --no-binary mqt.core :sync: pip ```console -(.venv) $ pip install mqt.core --no-binary mqt.core +pip install mqt.core --no-binary mqt.core ``` ::: + :::: -This requires a C++20-capable [C++ compiler](https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers) and [CMake](https://cmake.org/) 3.24 or newer. + +This requires a C++20-capable +[C++ compiler](https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers) +and [CMake](https://cmake.org/) 3.24 or newer. ## Integrating MQT Core into Your Project -To use the MQT Core Python package in your project, add it as a dependency in your {code}`pyproject.toml` or {code}`setup.py`. +To use the MQT Core Python package in your project, +add it as a dependency in your {code}`pyproject.toml` or {code}`setup.py`. This ensures the package is installed when your project is installed. ::::{tab-set} @@ -105,7 +123,7 @@ This ensures the package is installed when your project is installed. :::{tab-item} {code}`uv` _(recommended)_ ```console -$ uv add mqt.core +uv add mqt.core ``` ::: @@ -134,19 +152,28 @@ setup( ``` ::: + :::: -If you want to integrate the C++ library directly into your project, you can either +If you want to integrate the C++ library directly into your project, +you can either -- add it as a [{code}`git` submodule][git-submodule] and build it as part of your project, or -- install MQT Core on your system and use CMake's {code}`find_package()` command to locate it, or -- use CMake's [{code}`FetchContent`][FetchContent] module to combine both approaches. +- add it as a [{code}`git` submodule][git-submodule] and build it + as part of your project, or +- install MQT Core on your system + and use CMake's {code}`find_package()` command to locate it, or +- use CMake's [{code}`FetchContent`][FetchContent] module to combine both + approaches. ::::{tab-set} + :::{tab-item} {code}`FetchContent` -This is the recommended approach because it lets you detect installed versions of MQT Core and only downloads the library if it is not available on the system. -Furthermore, CMake's [{code}`FetchContent`][FetchContent] module provides flexibility in how the library is integrated into the project. +This is the recommended approach +because it lets you detect installed versions of MQT Core +and only downloads the library if it is not available on the system. +Furthermore, CMake's [{code}`FetchContent`][FetchContent] module provides +flexibility in how the library is integrated into the project. ```cmake include(FetchContent) @@ -177,15 +204,19 @@ FetchContent_MakeAvailable(${FETCH_PACKAGES}) :::{tab-item} {code}`git-submodule` -Adding the library as a [{code}`git` submodule][git-submodule] is a simple approach. -However, {code}`git` submodules can be cumbersome, especially when working with multiple branches or versions of the library. -First, add the submodule to your project (e.g., in the {code}`external` directory): +Adding the library as a [{code}`git` submodule][git-submodule] is a simple +approach. +However, {code}`git` submodules can be cumbersome, +especially when working with multiple branches or versions of the library. +First, add the submodule to your project +(e.g., in the {code}`external` directory): ```console -$ git submodule add https://github.com/munich-quantum-toolkit/core.git external/mqt-core +git submodule add https://github.com/munich-quantum-toolkit/core.git external/mqt-core ``` -Then add the following line to your {code}`CMakeLists.txt` to make the library's targets available in your project: +Then add the following line to your {code}`CMakeLists.txt` to make the library's +targets available in your project: ```cmake add_subdirectory(external/mqt-core) @@ -198,14 +229,15 @@ add_subdirectory(external/mqt-core) You can install MQT Core on your system after building it from source: ```console -$ git clone https://github.com/munich-quantum-toolkit/core.git mqt-core -$ cd mqt-core -$ cmake -S . -B build -$ cmake --build build -$ cmake --install build +git clone https://github.com/munich-quantum-toolkit/core.git mqt-core +cd mqt-core +cmake -S . -B build +cmake --build build +cmake --install build ``` -Then, in your project's {code}`CMakeLists.txt`, use {code}`find_package()` to locate the installed library: +Then, in your project's {code}`CMakeLists.txt`, +use {code}`find_package()` to locate the installed library: ```cmake find_package(mqt-core REQUIRED) @@ -223,134 +255,166 @@ Set up a reproducible development environment for MQT Core. This is the recommended starting point for both bug fixes and new features. For detailed guidelines and workflows, see {doc}`contributing`. -1. Get the code: +1. Get the code: + + ::::{tab-set} + + :::{tab-item} External Contribution + + If you do not have write access to the + [munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core) + repository, fork the repository on GitHub (see + ) and clone + your fork locally. + + ```console + git clone git@github.com:your_name_here/core.git mqt-core + ``` + + ::: + + :::{tab-item} Internal Contribution + + If you have write access to the + [munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core) + repository, clone the repository locally. + + ```console + git clone git@github.com/munich-quantum-toolkit/core.git mqt-core + ``` - ::::{tab-set} - :::{tab-item} External Contribution - If you do not have write access to the [munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core) repository, fork the repository on GitHub (see ) and clone your fork locally. + ::: - ```console - $ git clone git@github.com:your_name_here/core.git mqt-core - ``` + :::: - ::: - :::{tab-item} Internal Contribution - If you have write access to the [munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core) repository, clone the repository locally. +2. Change into the project directory: - ```console - $ git clone git@github.com/munich-quantum-toolkit/core.git mqt-core - ``` + ```console + cd mqt-core + ``` - ::: - :::: +3. Create a branch for local development: -2. Change into the project directory: + ```console + git checkout -b name-of-your-bugfix-or-feature + ``` - ```console - $ cd mqt-core - ``` + Now you can make your changes locally. -3. Create a branch for local development: +4. Install the project and its development dependencies: - ```console - $ git checkout -b name-of-your-bugfix-or-feature - ``` + We highly recommend using modern, fast tooling for the development workflow. + We recommend using [{code}`uv`][uv]. + If you don't have {code}`uv`, + follow the installation instructions in the recommendation above + (see {ref}`tip above `). + See the [uv documentation][uv] for more information. - Now you can make your changes locally. + ::::{tab-set} + :sync-group: installer -4. Install the project and its development dependencies: + :::{tab-item} {code}`uv` _(recommended)_ + :sync: uv - We highly recommend using modern, fast tooling for the development workflow. - We recommend using [{code}`uv`][uv]. - If you don't have {code}`uv`, follow the installation instructions in the recommendation above (see {ref}`tip above `). - See the [uv documentation][uv] for more information. + Install the project (including development dependencies) with [{code}`uv`][uv]: - ::::{tab-set} - :sync-group: installer + ```console + uv sync + ``` - :::{tab-item} {code}`uv` _(recommended)_ - :sync: uv - Install the project (including development dependencies) with [{code}`uv`][uv]: + ::: - ```console - $ uv sync - ``` + :::{tab-item} {code}`pip` + :sync: pip - ::: - :::{tab-item} {code}`pip` - :sync: pip - If you really don't want to use [{code}`uv`][uv], you can install the project and the development dependencies into a virtual environment using {code}`pip`. + If you really don't want to use [{code}`uv`][uv], you can install the project + and the development dependencies into a virtual environment using + {code}`pip`. - ```console - $ python -m venv .venv - $ source ./.venv/bin/activate - (.venv) $ python -m pip install -U pip - (.venv) $ python -m pip install -e . --group dev - ``` + ```console + python -m venv .venv + source ./.venv/bin/activate + python -m pip install -U pip + python -m pip install -e . --group dev + ``` - ::: - :::: + ::: -5. Install pre-commit hooks to ensure code quality: + :::: - The project uses [pre-commit] hooks for running linters and formatting tools on each commit. - These checks can be run manually via [{code}`nox`][nox], by running: +5. Install pre-commit hooks to ensure code quality: - ```console - $ nox -s lint - ``` + The project uses pre-commit hooks for running linters and formatting tools on each commit. + These checks can be run manually via [{code}`nox`][nox], by running: - They can also be run automatically on every commit via [{code}`prek`][prek] (recommended). - To set this up, install {code}`prek`, e.g., via: + ```console + nox -s lint + ``` - ::::{tab-set} - :::{tab-item} macOS and Linux + They can also be run automatically on every commit via [{code}`prek`][prek] (recommended). To set + this up, install {code}`prek`, e.g., via: - ```console - $ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/j178/prek/releases/latest/download/prek-installer.sh | sh - ``` + ::::{tab-set} - ::: - :::{tab-item} Windows + :::{tab-item} Linux and macOS - ```console - $ powershell -ExecutionPolicy ByPass -c "irm https://github.com/j178/prek/releases/latest/download/prek-installer.ps1 | iex" - ``` + ```console + curl --proto '=https' --tlsv1.2 -LsSf https://github.com/j178/prek/releases/latest/download/prek-installer.sh | sh + ``` - ::: + ::: - :::{tab-item} {code}`uv` + :::{tab-item} Windows (PowerShell) - ```console - $ uv tool install prek - ``` + ```console + powershell -ExecutionPolicy ByPass -c "irm https://github.com/j178/prek/releases/latest/download/prek-installer.ps1 | iex" + ``` - ::: - :::: + ::: - Then run: + :::{tab-item} {code}`uv` - ```console - $ prek install - ``` + ```console + uv tool install prek + ``` -6. If you plan to contribute to MQT Core, you will also need to install MLIR. - The section below describes how to do this. + ::: + + :::: + + Then run: + + ```console + prek install + ``` + +6. If you plan to contribute to MQT Core, + you will also need to install MLIR. + The section below describes how to do this. (setting-up-mlir)= ## Setting Up MLIR -MQT Core requires [MLIR](https://mlir.llvm.org/), which is part of the [LLVM](https://llvm.org/) project, to be available when building from source. -To successfully build MQT Core, you must make an installation of MLIR available to the C++ builds on your platform. +MQT Core requires [MLIR](https://mlir.llvm.org/), +which is part of the [LLVM](https://llvm.org/) project, +to be available when building from source. +To successfully build MQT Core, +you must make an installation of MLIR available to the C++ builds on your +platform. -We highly recommend using the prebuilt MLIR distribution provided by the [`portable-mlir-toolchain`] project. -These can be conveniently installed with the [`setup-mlir`] scripts as described below. +We highly recommend using the prebuilt MLIR distribution provided by the +[`portable-mlir-toolchain`] project. +These can be conveniently installed with the [`setup-mlir`] scripts +as described below. ### Downloading the MLIR Distribution -The [`setup-mlir`] repository provides installation scripts for all supported operating systems. -You must pass the LLVM version (e.g., `22.1.0`) and the installation prefix (directory) where MLIR should be extracted. +The [`setup-mlir`] repository provides installation scripts +for all supported operating systems. +You must pass the LLVM version +(e.g., `22.1.0`) +and the installation prefix (directory) where MLIR should be extracted. The scripts download a platform-specific archive. The only requirement is that the `tar` command is available on the system. @@ -358,92 +422,118 @@ The only requirement is that the `tar` command is available on the system. :name: tar-requirement `tar` is included by default on Windows 10 and Windows 11. -On older Windows versions, you can install it, for example, via [Chocolatey](https://chocolatey.org/): `choco install tar`. +On older Windows versions, you can install it, for example, +via [Chocolatey](https://chocolatey.org/): `choco install tar`. :::: ::::{tab-set} + :::{tab-item} Linux and macOS Run the Bash script with the desired LLVM version and installation path: + + ```console -$ curl -LsSf https://github.com/munich-quantum-software/setup-mlir/releases/latest/download/setup-mlir.sh | bash -s -- -v 22.1.0 -p /path/to/installation +curl -LsSf https://github.com/munich-quantum-software/setup-mlir/releases/latest/download/setup-mlir.sh | bash -s -- -v 22.1.0 -p /path/to/installation ``` -Replace `/path/to/installation` with the directory where the LLVM distribution should be installed (e.g., `/opt/llvm-22.1.0`). + + +Replace `/path/to/installation` with the directory +where the LLVM distribution should be installed (e.g., `/opt/llvm-22.1.0`). ::: -:::{tab-item} Windows + +:::{tab-item} Windows (PowerShell) Run the PowerShell script with the desired LLVM version and installation path: + + ```console -$ powershell -ExecutionPolicy ByPass -c "& ([scriptblock]::Create((irm https://github.com/munich-quantum-software/setup-mlir/releases/latest/download/setup-mlir.ps1))) -llvm_version 22.1.0 -install_prefix \path\to\installation" +powershell -ExecutionPolicy ByPass -c "& ([scriptblock]::Create((irm https://github.com/munich-quantum-software/setup-mlir/releases/latest/download/setup-mlir.ps1))) -llvm_version 22.1.0 -install_prefix \path\to\installation" ``` -Replace `\path\to\installation` with the directory where the LLVM distribution should be installed (e.g., `C:\llvm-22.1.0`). + + +Replace `\path\to\installation` with the directory +where the LLVM distribution should be installed (e.g., `C:\llvm-22.1.0`). For debug builds on Windows, add the `-use_debug` flag to the script invocation. ::: + :::: -For supported LLVM versions, commit hashes, and other options, see the [`setup-mlir`] repository and its [`version-manifest.json`](https://github.com/munich-quantum-software/setup-mlir/blob/main/version-manifest.json). +For supported LLVM versions, commit hashes, and other options, +see the [`setup-mlir`] repository and its +[`version-manifest.json`](https://github.com/munich-quantum-software/setup-mlir/blob/main/version-manifest.json). ::::{note} :name: mlir-build-note -If you want to build MLIR from source, you can follow the instructions in the [`portable-mlir-toolchain`] repository. -This is not recommended unless you need a specific configuration that is not available in the prebuilt distributions, as building MLIR from source can be complex and time-consuming. +If you want to build MLIR from source, +you can follow the instructions in the [`portable-mlir-toolchain`] repository. +This is not recommended unless you need a specific configuration +that is not available in the prebuilt distributions, +as building MLIR from source can be complex and time-consuming. :::: ### Making MLIR Available to the Build -After installing MLIR, point the build system to it by setting the CMake variable {code}`MLIR_DIR` to the **CMake configuration directory** of the installation: +After installing MLIR, point the build system to it by setting the CMake +variable {code}`MLIR_DIR` to the **CMake configuration directory** of the +installation: ```console -$ cmake -S . -B build -DMLIR_DIR=/path/to/installation/lib/cmake/mlir +cmake -S . -B build -DMLIR_DIR=/path/to/installation/lib/cmake/mlir ``` -Replace `/path/to/installation` with the actual path to the MLIR installation from the previous step. +Replace `/path/to/installation` with the actual path to the MLIR installation +from the previous step. -Alternatively, you can set the {code}`MLIR_DIR` environment variable to the same path before running CMake: +Alternatively, you can set the {code}`MLIR_DIR` environment variable to the same +path before running CMake: ::::{tab-set} + :::{tab-item} Linux and macOS ```console -$ export MLIR_DIR=/path/to/installation/lib/cmake/mlir +export MLIR_DIR=/path/to/installation/lib/cmake/mlir ``` ::: + :::{tab-item} Windows (PowerShell) ```console -$ $env:MLIR_DIR = "C:\path\to\installation\lib\cmake\mlir" +$env:MLIR_DIR = "C:\path\to\installation\lib\cmake\mlir" ``` ::: + :::: ### Disabling MLIR -If you do not need MLIR-based functionality, you can disable it by setting the {code}`BUILD_MQT_CORE_MLIR` option to {code}`OFF`. -This disables all MLIR-related features in MQT Core and removes the dependency on MLIR. +If you do not need MLIR-based functionality, +you can disable it by setting the {code}`BUILD_MQT_CORE_MLIR` option +to {code}`OFF`. +This disables all MLIR-related features in MQT Core +and removes the dependency on MLIR. ```console -$ cmake -S . -B build -DBUILD_MQT_CORE_MLIR=OFF +cmake -S . -B build -DBUILD_MQT_CORE_MLIR=OFF ``` [`setup-mlir`]: https://github.com/munich-quantum-software/setup-mlir/ [`portable-mlir-toolchain`]: https://github.com/munich-quantum-software/portable-mlir-toolchain/ - [FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html [git-submodule]: https://git-scm.com/docs/git-submodule [nox]: https://nox.thea.codes/en/stable/ -[pipx]: https://pypa.github.io/pipx/ -[pre-commit]: https://pre-commit.com/ [prek]: https://prek.j178.dev -[ruff]: https://docs.astral.sh/ruff/ [uv]: https://docs.astral.sh/uv/ +[ruff]: https://docs.astral.sh/ruff/ diff --git a/docs/tooling.md b/docs/tooling.md index 285c9de5af..fd1a9a33ef 100644 --- a/docs/tooling.md +++ b/docs/tooling.md @@ -3,8 +3,10 @@ # Tooling -This page summarizes the main tools, software, and standards used in MQT Core. -It serves as a quick reference for new contributors and users who want to understand the project's ecosystem. +This page summarizes the main tools, software, +and standards used in MQT Core. +It serves as a quick reference for new contributors +and users who want to understand the project's ecosystem. ## C++ @@ -24,12 +26,17 @@ It serves as a quick reference for new contributors and users who want to unders | **scikit-build-core** | Build backend for Python package. | [Documentation](https://scikit-build-core.readthedocs.io/en/latest/). | | **cibuildwheel** | Builds wheels for all supported platforms and Python versions. | [Documentation](https://cibuildwheel.pypa.io/en/stable/). Configured in {code}`pyproject.toml`. | -By using nanobind, we can take advantage of the [Stable ABI](https://docs.python.org/3/c-api/stable.html) for Python 3.12+. -This means that, starting from Python 3.12, we only need to build one wheel per platform, which can be used across all Python 3.12+ versions. +By using nanobind, we can take advantage of the +[Stable ABI](https://docs.python.org/3/c-api/stable.html) for Python 3.12+. +This means that, starting from Python 3.12, +we only need to build one wheel per platform, +which can be used across all Python 3.12+ versions. We still build separate wheels for older supported Python versions. -Additionally, we support the free-threading version of Python that is no longer marked experimental as of Python 3.14. -The corresponding wheels are built separately since there is no stable ABI for free-threading Python yet. +Additionally, we support the free-threading version of Python +that is no longer marked experimental as of Python 3.14. +The corresponding wheels are built separately since there is no stable ABI +for free-threading Python yet. ## MLIR @@ -50,7 +57,8 @@ The corresponding wheels are built separately since there is no stable ABI for f | **ty** | Fast Python type checker and language server. | [Documentation](https://docs.astral.sh/ty/). | | **pytest** | Testing framework for Python. | [Documentation](https://docs.pytest.org/). Run via {code}`nox -s tests` or {code}`uv run pytest`. | -The project adheres to modern standards and practices. For the Python ecosystem, we make use of the following standards: +The project adheres to modern standards and practices. +For the Python ecosystem, we make use of the following standards: | Standard | Description | Links / Notes | | ----------- | --------------------------------------------------------------- | --------------------------------------------------- | @@ -74,8 +82,8 @@ The project adheres to modern standards and practices. For the Python ecosystem, | ------------------ | ------------------------------------------- | ---------------------------------------------------------------------- | | **GitHub Actions** | CI workflows (build, test, lint, coverage). | [Reusable MQT Workflows] in {code}`.github/workflows/`; see [Actions]. | | **Codecov** | Code coverage reporting. | [Codecov] for this repo. | -| **CodeRabbit** | Automated code review on PRs. | [CodeRabbit](https://www.coderabbit.ai/). See {doc}`contributing`. | -| **pre-commit.ci** | Runs pre-commit in CI and can auto-fix. | [pre-commit.ci](https://pre-commit.ci). | +| **CodeRabbit** | Initial PR reviews. | [CodeRabbit](https://www.coderabbit.ai/). See {doc}`contributing`. | +| **pre-commit.ci** | Runs pre-commit hooks in CI and auto-fixes. | [pre-commit.ci](https://pre-commit.ci). | [Actions]: https://github.com/munich-quantum-toolkit/core/actions [Codecov]: https://codecov.io/gh/munich-quantum-toolkit/core From 70f56f944edcd24905ff9e1f2fcb48da74b5f0e8 Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:29:36 +0200 Subject: [PATCH 2/6] Replace prettier with rumdl --- .pre-commit-config.yaml | 11 +- .rumdl.toml | 18 ++ CHANGELOG.md | 502 +++++++++++++++++++++++----------- README.md | 87 ++++-- UPGRADING.md | 301 ++++++++++++++------ docs/contributing.md | 25 +- docs/dd_package.md | 343 ++++++++++++++++------- docs/dd_package_evaluation.md | 32 ++- docs/index.md | 26 +- docs/installation.md | 13 +- docs/mlir/index.md | 24 +- docs/mqt_core_ir.md | 157 +++++++---- docs/qdmi/ddsim_device.md | 31 ++- docs/qdmi/driver.md | 34 ++- docs/qdmi/index.md | 10 +- docs/qdmi/na_device.md | 21 +- docs/qdmi/qdmi_backend.md | 108 +++++--- docs/qir/index.md | 32 ++- docs/tooling.md | 3 +- docs/zx_package.md | 89 ++++-- paper/paper.md | 199 ++++++++------ 21 files changed, 1421 insertions(+), 645 deletions(-) create mode 100644 .rumdl.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee7cb1896a..3917071ee7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -107,9 +107,18 @@ repos: rev: v3.8.3 hooks: - id: prettier - types_or: [yaml, markdown, html, css, scss, javascript, json, json5] + types_or: [yaml, html, css, scss, javascript, json, json5] priority: 5 + ## Format Markdown files with rumdl + - repo: https://github.com/rvben/rumdl-pre-commit + rev: v0.2.10 + hooks: + - id: rumdl + priority: 5 + - id: rumdl-fmt + priority: 6 + ## Format CMake files with cmake-format - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 diff --git a/.rumdl.toml b/.rumdl.toml new file mode 100644 index 0000000000..11d983020d --- /dev/null +++ b/.rumdl.toml @@ -0,0 +1,18 @@ +[per-file-ignores] +# The PR template is not a Markdown document in that sense +"**/pull_request_template.md" = ["MD013", "MD041"] +# The docs files do not necessarily need to start with a top-level heading +"docs/**" = ["MD041"] +# The README starts with an image and may include HTML tags +"README.md" = ["MD033", "MD041"] + +[per-file-flavor] +"docs/**" = "myst" + +[MD013] +line-length = 80 +reflow = true +reflow-mode = "semantic-line-breaks" + +[MD060] +enabled = true diff --git a/CHANGELOG.md b/CHANGELOG.md index 0214758b81..1426b6d167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,43 +5,72 @@ All notable changes to this project will be documented in this file. The format is based on a mixture of [Keep a Changelog] and [Common Changelog]. -This project adheres to [Semantic Versioning], with the exception that minor releases may include breaking changes. +This project adheres to [Semantic Versioning], +with the exception that minor releases may include breaking changes. ## [Unreleased] ### Added -- ✨ Add QIR program format support to the DDSIM QDMI Device ([#1766]) ([**@rturrado**]) -- 🚸 Add [CMake presets] to provide a standardized and reproducible way to configure builds ([#1660]) ([**@denialhaag**]) -- ✨ Add a `quantum-loop-unroll` pass for unrolling for-loop operations containing quantum operations ([#1718]) ([**@MatthiasReumann**]) -- ✨ Add a `hadamard-lifting` pass for lifting Hadamard gates above Pauli gates ([#1605]) ([**@lirem101**], [**@burgholzer**]) -- ✨ Add a `merge-single-qubit-rotation-gates` pass for merging consecutive rotation gates using quaternions ([#1407], [#1674]) ([**@J4MMlE**], [**@denialhaag**], [**@MatthiasReumann**]) -- ✨ Add conversions between `jeff` and QCO ([#1479], [#1548], [#1565], [#1637], [#1676], [#1706], [#1776]) ([**@denialhaag**], [**@burgholzer**]) -- ✨ Add a `place-and-route` pass for mapping circuits to architectures with restricted topologies ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588], [#1600], [#1664], [#1709], [#1716], [#1748]) ([**@MatthiasReumann**], [**@burgholzer**]) +- ✨ Add QIR program format support to the DDSIM QDMI Device ([#1766]) + ([**@rturrado**]) +- 🚸 Add [CMake presets] to provide a standardized + and reproducible way to configure builds ([#1660]) ([**@denialhaag**]) +- ✨ Add a `quantum-loop-unroll` pass + for unrolling for-loop operations containing quantum operations ([#1718]) + ([**@MatthiasReumann**]) +- ✨ Add a `hadamard-lifting` pass + for lifting Hadamard gates above Pauli gates ([#1605]) + ([**@lirem101**], [**@burgholzer**]) +- ✨ Add a `merge-single-qubit-rotation-gates` pass + for merging consecutive rotation gates using quaternions ([#1407], [#1674]) + ([**@J4MMlE**], [**@denialhaag**], [**@MatthiasReumann**]) +- ✨ Add conversions between `jeff` and QCO + ([#1479], [#1548], [#1565], [#1637], [#1676], [#1706], [#1776]) + ([**@denialhaag**], [**@burgholzer**]) +- ✨ Add a `place-and-route` pass + for mapping circuits to architectures with restricted topologies + ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588], [#1600], [#1664], + [#1709], [#1716], [#1748]) ([**@MatthiasReumann**], [**@burgholzer**]) - ✨ Add initial infrastructure for new QC and QCO MLIR dialects - ([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1710], [#1717], [#1728], [#1730], [#1749], [#1751], [#1762], [#1765], [#1774], [#1781]) - ([**@burgholzer**], [**@denialhaag**], [**@taminob**], [**@DRovara**], [**@li-mingbao**], [**@Ectras**], [**@MatthiasReumann**], [**@simon1hofmann**]) + ([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], + [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], + [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], + [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], + [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], + [#1710], [#1717], [#1728], [#1730], [#1749], [#1751], [#1762], [#1765], + [#1774], [#1781]) ([**@burgholzer**], [**@denialhaag**], [**@taminob**], + [**@DRovara**], [**@li-mingbao**], [**@Ectras**], [**@MatthiasReumann**], + [**@simon1hofmann**]) ### Changed -- ⬆️ Update [munich-quantum-toolkit/workflows] to version `v2.0.1` ([#1660], [#1737]) ([**@denialhaag**]) -- ⬆️ Require LLVM 22.1 for C++ library builds ([#1549]) ([**@burgholzer**], [**@denialhaag**]) -- 📦 Build MLIR by default for C++ library builds ([#1356]) ([**@burgholzer**], [**@denialhaag**]) +- ⬆️ Update [munich-quantum-toolkit/workflows] to version `v2.0.1` + ([#1660], [#1737]) ([**@denialhaag**]) +- ⬆️ Require LLVM 22.1 for C++ library builds ([#1549]) + ([**@burgholzer**], [**@denialhaag**]) +- 📦 Build MLIR by default for C++ library builds ([#1356]) + ([**@burgholzer**], [**@denialhaag**]) ### Removed -- 🔥 Remove the density matrix support from the MQT Core DD package ([#1466]) ([**@burgholzer**]) -- 🔥 Remove `datastructures` (`ds`) (sub)library from MQT Core ([#1458]) ([**@burgholzer**]) +- 🔥 Remove the density matrix support from the MQT Core DD package ([#1466]) + ([**@burgholzer**]) +- 🔥 Remove `datastructures` (`ds`) (sub)library from MQT Core ([#1458]) + ([**@burgholzer**]) ## [3.6.1] - 2026-05-20 ### Changed -- 🚸 Improve native gate support for the Qiskit-to-OpenQASM3 conversion in the QDMI-Qiskit interface ([#1719]) ([**@burgholzer**]) +- 🚸 Improve native gate support + for the Qiskit-to-OpenQASM3 conversion in the QDMI-Qiskit interface ([#1719]) + ([**@burgholzer**]) ### Fixed -- 🏁 Fix dynamic loading of QDMI device DLLs on Windows when an absolute path is provided ([#1720]) ([**@burgholzer**]) +- 🏁 Fix dynamic loading of QDMI device DLLs on Windows + when an absolute path is provided ([#1720]) ([**@burgholzer**]) ## [3.6.0] - 2026-05-13 @@ -49,22 +78,29 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#360)._ ### Added -- 🚸 Add a measurement instruction to the default SC QDMI device ([#1694]) ([**@burgholzer**]) -- ✨ Add support for multi-controlled gates to the QDMI Qiskit backend converter ([#1694]) ([**@burgholzer**]) +- 🚸 Add a measurement instruction to the default SC QDMI device ([#1694]) + ([**@burgholzer**]) +- ✨ Add support for multi-controlled gates to the QDMI Qiskit backend converter + ([#1694]) ([**@burgholzer**]) ### Changed -- ♻️ Build all built-in QDMI devices as shared libraries ([#1694]) ([**@burgholzer**]) -- ⬆️ Update minimum supported Qiskit version to 1.1.0 ([#1694]) ([**@burgholzer**]) +- ♻️ Build all built-in QDMI devices + as shared libraries ([#1694]) ([**@burgholzer**]) +- ⬆️ Update minimum supported Qiskit version to 1.1.0 ([#1694]) + ([**@burgholzer**]) ### Fixed -- 🐛 Fix missing `nlohmann_json.natvis` in Windows component-based CMake installs ([#1702]) ([**@burgholzer**]) -- 🐛 Fix segfault in DD `sample` method when idle classical bits are present ([#1694]) ([**@burgholzer**]) +- 🐛 Fix missing `nlohmann_json.natvis` in Windows component-based CMake + installs ([#1702]) ([**@burgholzer**]) +- 🐛 Fix segfault in DD `sample` method + when idle classical bits are present ([#1694]) ([**@burgholzer**]) ### Removed -- 🔥 Remove shared library wrappers for QDMI devices ([#1694]) ([**@burgholzer**]) +- 🔥 Remove shared library wrappers + for QDMI devices ([#1694]) ([**@burgholzer**]) ## [3.5.1] - 2026-04-23 @@ -72,7 +108,8 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#351)._ ### Fixed -- 🐛 Fix malformed include directories in exported `nlohmann_json` CMake targets for component-based installs ([#1662]) ([**@burgholzer**]) +- 🐛 Fix malformed include directories in exported `nlohmann_json` CMake targets + for component-based installs ([#1662]) ([**@burgholzer**]) ## [3.5.0] - 2026-04-21 @@ -80,17 +117,24 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#350)._ ### Added -- ✨ Add support for multi-controlled gates to ZX package ([#1380]) ([**@keefehuang**], [**@denialhaag**]) -- ✨ Add Sampler and Estimator primitives to the QDMI-Qiskit interface ([#1507]) ([**@marcelwa**]) +- ✨ Add support for multi-controlled gates to ZX package ([#1380]) + ([**@keefehuang**], [**@denialhaag**]) +- ✨ Add Sampler and Estimator primitives to the QDMI-Qiskit interface ([#1507]) + ([**@marcelwa**]) ### Changed - ⬆️ Update `nanobind` to version 2.12.0 ([#1528]) - ⬆️ Update QDMI to `v1.3.0` ([#1652]) ([**@burgholzer**]) -- 📦 Switch to component-based installation for the MQT Core Python package ([#1596]) ([**@burgholzer**]) -- ⬆️ Update QDMI to latest version from stable `v1.2.x` branch ([#1593]) ([**@burgholzer**]) -- ⬆️ Update `clang-tidy` to version 22 ([#1564]) ([**@denialhaag**], [**@burgholzer**]) -- 👷 Build on `macos-26`/`macos-26-intel` by default and `macos-15`/`macos-15-intel` for extensive tests ([#1571]) ([**@denialhaag**]) +- 📦 Switch to component-based installation + for the MQT Core Python package ([#1596]) ([**@burgholzer**]) +- ⬆️ Update QDMI to latest version from stable `v1.2.x` branch ([#1593]) + ([**@burgholzer**]) +- ⬆️ Update `clang-tidy` to version 22 ([#1564]) + ([**@denialhaag**], [**@burgholzer**]) +- 👷 Build on `macos-26`/`macos-26-intel` by default + and `macos-15`/`macos-15-intel` + for extensive tests ([#1571]) ([**@denialhaag**]) ## [3.4.1] - 2026-02-01 @@ -98,15 +142,23 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#350)._ - ⬆️ Update `nanobind` to version 2.11.0 ([#1481]) ([**@denialhaag**]) - ⬆️ Update Boost to version 1.89.0 ([#1453]) ([**@burgholzer**]) -- ⬆️ Update QDMI to latest version from stable `v1.2.x` branch ([#1453]) ([**@burgholzer**]) +- ⬆️ Update QDMI to latest version from stable `v1.2.x` branch ([#1453]) + ([**@burgholzer**]) - ⬆️ Update `spdlog` to version 1.17.0 ([#1453]) ([**@burgholzer**]) -- ♻️ Use `llc` instead of random `clang` for compiling QIR test circuits to improve robustness and handle opaque pointers correctly across LLVM versions ([#1447]) ([**@burgholzer**]) -- ♻️ Extract singleton pattern into reusable template base class for QDMI devices and driver ([#1444]) ([**@ystade**], [**@burgholzer**]) -- 🚚 Reorganize QDMI code structure by moving devices into dedicated subdirectories and separating driver and common utilities ([#1444]) ([**@ystade**]) +- ♻️ Use `llc` instead of random `clang` + for compiling QIR test circuits to improve robustness + and handle opaque pointers correctly across LLVM versions ([#1447]) + ([**@burgholzer**]) +- ♻️ Extract singleton pattern into reusable template base class + for QDMI devices and driver ([#1444]) ([**@ystade**], [**@burgholzer**]) +- 🚚 Reorganize QDMI code structure by moving devices into dedicated + subdirectories and separating driver and common utilities ([#1444]) + ([**@ystade**]) ### Removed -- 🔥 No longer actively type check Python code with `mypy` and solely rely on `ty` ([#1437]) ([**@burgholzer**]) +- 🔥 No longer actively type check Python code with `mypy` + and solely rely on `ty` ([#1437]) ([**@burgholzer**]) ## [3.4.0] - 2026-01-08 @@ -114,77 +166,131 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#340)._ ### Added -- ✨ Return device handle from `add_dynamic_device_library` for direct backend creation ([#1381]) ([**@marcelwa**]) -- ✨ Add IQM JSON support for job submission in Qiskit-QDMI Backend ([#1375], [#1382]) ([**@marcelwa**], [**@burgholzer**]) -- ✨ Add authentication support for QDMI sessions with token, username/password, auth file, auth URL, and project ID parameters ([#1355]) ([**@marcelwa**]) -- ✨ Add a new QDMI device that represents a superconducting architecture featuring a coupling map ([#1328]) ([**@ystade**]) -- ✨ Add bi-directional iterator that traverses the def-use chain of a qubit value ([#1310]) ([**@MatthiasReumann**]) -- ✨ Add `OptionalDependencyTester` to lazily handle optional Python dependencies like Qiskit ([#1243]) ([**@marcelwa**], [**@burgholzer**]) -- ✨ Expose the QDMI job interface through FoMaC ([#1243]) ([**@marcelwa**], [**@burgholzer**]) -- ✨ Add Qiskit backend wrapper with job submission support for QDMI devices through a provider interface ([#1243], [#1385]) ([**@marcelwa**], [**@burgholzer**]) -- ✨ Support `QDMI_DEVICE_PROPERTY_SUPPORTEDPROGRAMFORMATS` in the NA QDMI Device and the DDSIM QDMI Device ([#1243]) ([**@marcelwa**], [**@burgholzer**]) -- ✨ Support `QDMI_DEVICE_JOB_PROPERTY_PROGRAM` in the NA QDMI Device ([#1243]) ([**@marcelwa**], [**@burgholzer**]) +- ✨ Return device handle from `add_dynamic_device_library` + for direct backend creation ([#1381]) ([**@marcelwa**]) +- ✨ Add IQM JSON support for job submission in Qiskit-QDMI Backend + ([#1375], [#1382]) ([**@marcelwa**], [**@burgholzer**]) +- ✨ Add authentication support for QDMI sessions with token, username/password, + auth file, auth URL, and project ID parameters ([#1355]) ([**@marcelwa**]) +- ✨ Add a new QDMI device + that represents a superconducting architecture featuring a coupling map + ([#1328]) ([**@ystade**]) +- ✨ Add bi-directional iterator + that traverses the def-use chain of a qubit value ([#1310]) + ([**@MatthiasReumann**]) +- ✨ Add `OptionalDependencyTester` to lazily handle optional Python + dependencies like Qiskit ([#1243]) ([**@marcelwa**], [**@burgholzer**]) +- ✨ Expose the QDMI job interface through FoMaC ([#1243]) + ([**@marcelwa**], [**@burgholzer**]) +- ✨ Add Qiskit backend wrapper with job submission support + for QDMI devices through a provider interface ([#1243], [#1385]) + ([**@marcelwa**], [**@burgholzer**]) +- ✨ Support `QDMI_DEVICE_PROPERTY_SUPPORTEDPROGRAMFORMATS` in the NA QDMI + Device and the DDSIM QDMI Device ([#1243]) ([**@marcelwa**], + [**@burgholzer**]) +- ✨ Support `QDMI_DEVICE_JOB_PROPERTY_PROGRAM` in the NA QDMI Device ([#1243]) + ([**@marcelwa**], [**@burgholzer**]) ### Changed -- 📦🏁 Build Windows x86 wheels on `windows-2025` runner for newer compiler ([#1415]) ([**@burgholzer**]) -- 👷 Build on `macos-15`/`windows-2025` by default and `macos-14`/`windows-2022` for extensive tests ([#1414]) ([**@burgholzer**]) -- 📦🍎 Build macOS arm64 wheels on macos-15 runner for newer compiler ([#1413]) ([**@burgholzer**]) -- ⚡ Improve uv build caching by removing unconditional `reinstall-package` and configuring dedicated `cache-keys` ([#1412]) ([**@burgholzer**]) -- 👨‍💻📦 Build `spdlog` and QDMI generators as shared libraries in Python package builds ([#1411], [#1403]) ([**@burgholzer**]) -- ♻️🏁 Remove Windows-specific restrictions for dynamic QDMI device library handling ([#1406]) ([**@burgholzer**]) -- ♻️ Migrate Python bindings from `pybind11` to `nanobind` ([#1383]) ([**@denialhaag**], [**@burgholzer**]) -- 📦️ Provide Stable ABI wheels for Python 3.12+ ([#1383]) ([**@burgholzer**], [**@denialhaag**]) -- 🚚 Create dedicated `mqt.core.na` submodule to closely follow the structure of other submodules ([#1383]) ([**@burgholzer**]) +- 📦🏁 Build Windows x86 wheels on `windows-2025` runner + for newer compiler ([#1415]) ([**@burgholzer**]) +- 👷 Build on `macos-15`/`windows-2025` by default and `macos-14`/`windows-2022` + for extensive tests ([#1414]) ([**@burgholzer**]) +- 📦🍎 Build macOS arm64 wheels on macos-15 runner + for newer compiler ([#1413]) ([**@burgholzer**]) +- ⚡ Improve uv build caching by removing unconditional `reinstall-package` + and configuring dedicated `cache-keys` ([#1412]) ([**@burgholzer**]) +- 👨‍💻📦 Build `spdlog` and QDMI generators + as shared libraries in Python package builds + ([#1411], [#1403]) ([**@burgholzer**]) +- ♻️🏁 Remove Windows-specific restrictions + for dynamic QDMI device library handling ([#1406]) ([**@burgholzer**]) +- ♻️ Migrate Python bindings from `pybind11` to `nanobind` ([#1383]) + ([**@denialhaag**], [**@burgholzer**]) +- 📦️ Provide Stable ABI wheels for Python 3.12+ ([#1383]) + ([**@burgholzer**], [**@denialhaag**]) +- 🚚 Create dedicated `mqt.core.na` submodule to closely follow the structure of + other submodules ([#1383]) ([**@burgholzer**]) - ✨ Add common definitions and utilities for QDMI ([#1355]) ([**@burgholzer**]) -- 🚚 Move `NA` QDMI device in its right place next to other QDMI devices ([#1355]) ([**@burgholzer**]) -- ♻️ Allow repeated loading of QDMI device library with potentially different session configurations ([#1355]) ([**@burgholzer**]) -- ♻️ Enable thread-safe reference counting for QDMI devices singletons ([#1355]) ([**@burgholzer**]) -- ♻️ Refactor `FoMaC` singleton to instantiable `Session` class with configurable authentication parameters ([#1355]) ([**@marcelwa**]) -- 👷 Stop testing on `ubuntu-22.04` and `ubuntu-22.04-arm` runners ([#1359]) ([**@denialhaag**], [**@burgholzer**]) -- 👷 Stop testing with `clang-19` and start testing with `clang-21` ([#1359]) ([**@denialhaag**], [**@burgholzer**]) -- 👷 Fix macOS tests with Homebrew Clang via new `munich-quantum-toolkit/workflows` version ([#1359]) ([**@denialhaag**], [**@burgholzer**]) -- 👷 Re-enable macOS tests with GCC by disabling module scanning ([#1359]) ([**@denialhaag**], [**@burgholzer**]) -- ♻️ Group circuit operations into scheduling units for MLIR routing ([#1301]) ([**@MatthiasReumann**]) -- 👷 Use `munich-quantum-software/setup-mlir` to set up MLIR ([#1294]) ([**@denialhaag**]) -- ♻️ Preserve tuple structure and improve site type clarity of the MQT NA Default QDMI Device ([#1299]) ([**@marcelwa**]) -- ♻️ Move DD package evaluation module to standalone script ([#1327]) ([**@burgholzer**]) +- 🚚 Move `NA` QDMI device in its right place next to other QDMI devices + ([#1355]) ([**@burgholzer**]) +- ♻️ Allow repeated loading of QDMI device library with potentially different + session configurations ([#1355]) ([**@burgholzer**]) +- ♻️ Enable thread-safe reference counting + for QDMI devices singletons ([#1355]) ([**@burgholzer**]) +- ♻️ Refactor `FoMaC` singleton to instantiable `Session` class with + configurable authentication parameters ([#1355]) ([**@marcelwa**]) +- 👷 Stop testing on `ubuntu-22.04` and `ubuntu-22.04-arm` runners ([#1359]) + ([**@denialhaag**], [**@burgholzer**]) +- 👷 Stop testing with `clang-19` and start testing with `clang-21` ([#1359]) + ([**@denialhaag**], [**@burgholzer**]) +- 👷 Fix macOS tests with Homebrew Clang via new + `munich-quantum-toolkit/workflows` version ([#1359]) ([**@denialhaag**], + [**@burgholzer**]) +- 👷 Re-enable macOS tests with GCC by disabling module scanning ([#1359]) + ([**@denialhaag**], [**@burgholzer**]) +- ♻️ Group circuit operations into scheduling units + for MLIR routing ([#1301]) ([**@MatthiasReumann**]) +- 👷 Use `munich-quantum-software/setup-mlir` to set up MLIR ([#1294]) + ([**@denialhaag**]) +- ♻️ Preserve tuple structure + and improve site type clarity of the MQT NA Default QDMI Device ([#1299]) + ([**@marcelwa**]) +- ♻️ Move DD package evaluation module to standalone script ([#1327]) + ([**@burgholzer**]) - ⬆️ Bump QDMI version to 1.2.0 ([#1243]) ([**@marcelwa**], [**@burgholzer**]) ### Fixed -- 🔧 Install all available QDMI device targets in Python package builds ([#1403]) ([**@burgholzer**]) -- 🐛 Fix operation validation in Qiskit backend to handle device-specific gate naming conventions ([#1384]) ([**@marcelwa**]) -- 🐛 Fix conditional branch handling when importing MLIR from `QuantumComputation` ([#1378]) ([**@lirem101**]) -- 🐛 Fix custom QDMI property and parameter handling in SC and NA devices ([#1355]) ([**@burgholzer**]) -- 🚨 Fix argument naming of `QuantumComputation` and `CompoundOperation` dunder methods for properly implementing the `MutableSequence` protocol ([#1338]) ([**@burgholzer**]) -- 🐛 Fix memory management in dynamic QDMI device by making it explicit ([#1336]) ([**@ystade**]) +- 🔧 Install all available QDMI device targets in Python package builds + ([#1403]) ([**@burgholzer**]) +- 🐛 Fix operation validation in Qiskit backend to handle device-specific gate + naming conventions ([#1384]) ([**@marcelwa**]) +- 🐛 Fix conditional branch handling + when importing MLIR from `QuantumComputation` ([#1378]) ([**@lirem101**]) +- 🐛 Fix custom QDMI property and parameter handling in SC + and NA devices ([#1355]) ([**@burgholzer**]) +- 🚨 Fix argument naming of `QuantumComputation` + and `CompoundOperation` dunder methods + for properly implementing the `MutableSequence` protocol ([#1338]) + ([**@burgholzer**]) +- 🐛 Fix memory management in dynamic QDMI device by making it explicit + ([#1336]) ([**@ystade**]) ### Removed - 🔥 Remove wheel builds for Python 3.13t ([#1371]) ([**@burgholzer**]) -- 🔥 Remove the `evaluation` extra from the MQT Core Python package ([#1327]) ([**@burgholzer**]) -- 🔥 Remove the `mqt-core-dd-compare` entry point from the MQT Core Python package ([#1327]) ([**@burgholzer**]) +- 🔥 Remove the `evaluation` extra from the MQT Core Python package ([#1327]) + ([**@burgholzer**]) +- 🔥 Remove the `mqt-core-dd-compare` entry point from the MQT Core Python + package ([#1327]) ([**@burgholzer**]) ## [3.3.3] - 2025-11-10 ### Added -- ✨ Add support for bridge gates for the neutral atom hybrid mapper ([#1293]) ([**@lsschmid**]) +- ✨ Add support for bridge gates + for the neutral atom hybrid mapper ([#1293]) ([**@lsschmid**]) ### Fixed -- 🐛 Revert change to `opTypeFromString()` signature made in [#1283] ([#1300]) ([**@denialhaag**]) +- 🐛 Revert change to `opTypeFromString()` signature made in [#1283] ([#1300]) + ([**@denialhaag**]) ## [3.3.2] - 2025-11-04 ### Added - ✨ Add DD-based simulator QDMI device ([#1287]) ([**@burgholzer**]) -- ✨ A `--reuse-qubits` pass implementing an advanced form of qubit reuse to reduce the qubit count of quantum circuits ([#1108]) ([**@DRovara**]) -- ✨ A `--lift-measurements` pass that attempts to move measurements up as much as possible, used for instance to enable better qubit reuse ([#1108]) ([**@DRovara**]) +- ✨ A `--reuse-qubits` pass implementing an advanced form of qubit reuse to + reduce the qubit count of quantum circuits ([#1108]) ([**@DRovara**]) +- ✨ A `--lift-measurements` pass that attempts to move measurements up as much + as possible, used for instance to enable better qubit reuse ([#1108]) + ([**@DRovara**]) - ✨ Add native support for `R(theta, phi)` gate ([#1283]) ([**@burgholzer**]) -- ✨ Add A\*-search-based routing algorithm to MLIR transpilation routines ([#1237], [#1271], [#1279]) ([**@MatthiasReumann**]) +- ✨ Add A\*-search-based routing algorithm to MLIR transpilation routines + ([#1237], [#1271], [#1279]) ([**@MatthiasReumann**]) ### Fixed @@ -195,7 +301,8 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#340)._ ### Fixed -- 🐛 Ensure `spdlog` dependency can be found from `mqt-core` install ([#1263]) ([**@burgholzer**]) +- 🐛 Ensure `spdlog` dependency can be found from `mqt-core` install ([#1263]) + ([**@burgholzer**]) ## [3.3.0] - 2025-10-13 @@ -204,60 +311,99 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#330)._ ### Added - 👷 Enable testing on Python 3.14 ([#1246]) ([**@denialhaag**]) -- ✨ Add dedicated `PlacementPass` to MLIR transpilation routines ([#1232]) ([**@MatthiasReumann**]) -- ✨ Add an NA-specific FoMaC implementation ([#1223], [#1236]) ([**@ystade**], [**@burgholzer**]) +- ✨ Add dedicated `PlacementPass` to MLIR transpilation routines ([#1232]) + ([**@MatthiasReumann**]) +- ✨ Add an NA-specific FoMaC implementation ([#1223], [#1236]) + ([**@ystade**], [**@burgholzer**]) - ✨ Enable import of BarrierOp into MQTRef ([#1224]) ([**@denialhaag**]) -- ✨ Add naive quantum program routing MLIR pass ([#1148]) ([**@MatthiasReumann**]) -- ✨ Add QIR runtime using DD-based simulation ([#1210]) ([**@ystade**], [**@burgholzer**]) -- ✨ Add SWAP reconstruction patterns to the newly-named `SwapReconstructionAndElision` MLIR pass ([#1207]) ([**@taminob**], [**@burgholzer**]) -- ✨ Add two-way conversions between MQTRef and QIR ([#1091]) ([**@li-mingbao**]) -- 🚸 Define custom assembly formats for MLIR operations ([#1209]) ([**@denialhaag**]) -- ✨ Add support for translating `IfElseOperation`s to the `MQTRef` MLIR dialect ([#1164]) ([**@denialhaag**], [**@burgholzer**]) -- ✨ Add MQT's implementation of a generic FoMaC with Python bindings ([#1150], [#1186], [#1223]) ([**@ystade**]) -- ✨ Add new MLIR pass `ElidePermutations` for SWAP gate elimination ([#1151]) ([**@taminob**]) -- ✨ Add new pattern to MLIR pass `GateElimination` for identity gate removal ([#1140]) ([**@taminob**]) -- ✨ Add Clifford block collection pass to `CircuitOptimizer` module ([#885]) ([**jannikpflieger**], [**@burgholzer**]) -- ✨ Add `isControlled()` method to the `UnitaryInterface` MLIR class ([#1157]) ([**@taminob**], [**@burgholzer**]) -- 📝 Integrate generated MLIR documentation ([#1147]) ([**@denialhaag**], [**@burgholzer**]) -- ✨ Add `IfElseOperation` to C++ library and Python package to support Qiskit's `IfElseOp` ([#1117]) ([**@denialhaag**], [**@burgholzer**], [**@lavanya-m-k**]) -- ✨ Add `allocQubit` and `deallocQubit` operations for dynamically working with single qubits to the MLIR dialects ([#1139]) ([**@DRovara**], [**@burgholzer**]) -- ✨ Add `qubit` operation for static qubit addressing to the MLIR dialects ([#1098], [#1116]) ([**@MatthiasReumann**]) +- ✨ Add naive quantum program routing MLIR pass ([#1148]) + ([**@MatthiasReumann**]) +- ✨ Add QIR runtime using DD-based simulation ([#1210]) + ([**@ystade**], [**@burgholzer**]) +- ✨ Add SWAP reconstruction patterns to the newly-named + `SwapReconstructionAndElision` MLIR pass ([#1207]) ([**@taminob**], + [**@burgholzer**]) +- ✨ Add two-way conversions between MQTRef + and QIR ([#1091]) ([**@li-mingbao**]) +- 🚸 Define custom assembly formats + for MLIR operations ([#1209]) ([**@denialhaag**]) +- ✨ Add support for translating `IfElseOperation`s to the `MQTRef` MLIR dialect + ([#1164]) ([**@denialhaag**], [**@burgholzer**]) +- ✨ Add MQT's implementation of a generic FoMaC with Python bindings + ([#1150], [#1186], [#1223]) ([**@ystade**]) +- ✨ Add new MLIR pass `ElidePermutations` + for SWAP gate elimination ([#1151]) ([**@taminob**]) +- ✨ Add new pattern to MLIR pass `GateElimination` + for identity gate removal ([#1140]) ([**@taminob**]) +- ✨ Add Clifford block collection pass to `CircuitOptimizer` module ([#885]) + ([**jannikpflieger**], [**@burgholzer**]) +- ✨ Add `isControlled()` method to the `UnitaryInterface` MLIR class ([#1157]) + ([**@taminob**], [**@burgholzer**]) +- 📝 Integrate generated MLIR documentation ([#1147]) + ([**@denialhaag**], [**@burgholzer**]) +- ✨ Add `IfElseOperation` to C++ library + and Python package to support Qiskit's `IfElseOp` ([#1117]) + ([**@denialhaag**], [**@burgholzer**], [**@lavanya-m-k**]) +- ✨ Add `allocQubit` and `deallocQubit` operations + for dynamically working with single qubits to the MLIR dialects ([#1139]) + ([**@DRovara**], [**@burgholzer**]) +- ✨ Add `qubit` operation for static qubit addressing to the MLIR dialects + ([#1098], [#1116]) ([**@MatthiasReumann**]) - ✨ Add MQT's implementation of a QDMI Driver ([#1010]) ([**@ystade**]) -- ✨ Add MQT's implementation of a QDMI Device for neutral atom-based quantum computing ([#996], [#1010], [#1100]) ([**@ystade**], [**@burgholzer**]) -- ✨ Add translation from `QuantumComputation` to the `MQTRef` MLIR dialect ([#1099]) ([**@denialhaag**], [**@burgholzer**]) +- ✨ Add MQT's implementation of a QDMI Device + for neutral atom-based quantum computing ([#996], [#1010], [#1100]) + ([**@ystade**], [**@burgholzer**]) +- ✨ Add translation from `QuantumComputation` to the `MQTRef` MLIR dialect + ([#1099]) ([**@denialhaag**], [**@burgholzer**]) - ✨ Add `reset` operations to the MLIR dialects ([#1106]) ([**@DRovara**]) ### Changed -- ♻️ Replace custom `AllocOp`, `DeallocOp`, `ExtractOp`, and `InsertOp` with MLIR-native `memref` operations ([#1211]) ([**@denialhaag**]) -- 🚚 Rename MLIR pass `ElidePermutations` to `SwapReconstructionAndElision` ([#1207]) ([**@taminob**]) +- ♻️ Replace custom `AllocOp`, `DeallocOp`, `ExtractOp`, + and `InsertOp` with MLIR-native `memref` operations ([#1211]) + ([**@denialhaag**]) +- 🚚 Rename MLIR pass `ElidePermutations` to `SwapReconstructionAndElision` + ([#1207]) ([**@taminob**]) - ⬆️ Require LLVM 21 for building the MLIR library ([#1180]) ([**@denialhaag**]) - ⬆️ Update to version 21 of `clang-tidy` ([#1180]) ([**@denialhaag**]) -- 🚚 Rename MLIR pass `CancelConsecutiveInverses` to `GateElimination` ([#1140]) ([**@taminob**]) -- 🚚 Rename `xxminusyy` to `xx_minus_yy` and `xxplusyy` to `xx_plus_yy` in MLIR dialects ([#1071]) ([**@BertiFlorea**], [**@denialhaag**]) -- 🚸 Add custom assembly format for operations in the MLIR dialects ([#1139]) ([**@burgholzer**]) -- 🚸 Enable `InferTypeOpInterface` in the MLIR dialects to reduce explicit type information ([#1139]) ([**@burgholzer**]) -- 🚚 Rename `check-quantum-opt` test target to `mqt-core-mlir-lit-test` ([#1139]) ([**@burgholzer**]) -- ♻️ Update the `measure` operations in the MLIR dialects to no longer support more than one qubit being measured at once ([#1106]) ([**@DRovara**]) -- 🚚 Rename `XXminusYY` to `XXminusYYOp` and `XXplusYY` to `XXplusYYOp` in MLIR dialects ([#1099]) ([**@denialhaag**]) +- 🚚 Rename MLIR pass `CancelConsecutiveInverses` to `GateElimination` ([#1140]) + ([**@taminob**]) +- 🚚 Rename `xxminusyy` to `xx_minus_yy` + and `xxplusyy` to `xx_plus_yy` in MLIR dialects ([#1071]) + ([**@BertiFlorea**], [**@denialhaag**]) +- 🚸 Add custom assembly format + for operations in the MLIR dialects ([#1139]) ([**@burgholzer**]) +- 🚸 Enable `InferTypeOpInterface` in the MLIR dialects to reduce explicit type + information ([#1139]) ([**@burgholzer**]) +- 🚚 Rename `check-quantum-opt` test target to `mqt-core-mlir-lit-test` + ([#1139]) ([**@burgholzer**]) +- ♻️ Update the `measure` operations in the MLIR dialects to no longer support + more than one qubit being measured at once ([#1106]) ([**@DRovara**]) +- 🚚 Rename `XXminusYY` to `XXminusYYOp` + and `XXplusYY` to `XXplusYYOp` in MLIR dialects ([#1099]) ([**@denialhaag**]) - 🚚 Rename `MQTDyn` MLIR dialect to `MQTRef` ([#1098]) ([**@MatthiasReumann**]) ### Removed - 🔥 Drop support for Python 3.9 ([#1181]) ([**@denialhaag**]) -- 🔥 Remove `ClassicControlledOperation` from C++ library and Python package ([#1117]) ([**@denialhaag**]) +- 🔥 Remove `ClassicControlledOperation` from C++ library + and Python package ([#1117]) ([**@denialhaag**]) ### Fixed -- 🐛 Fix CMake installation to make `find_package(mqt-core CONFIG)` succeed ([#1247]) ([**@burgholzer**], [**@denialhaag**]) -- 🏁 Fix stack overflows in OpenQASM layout parsing on Windows for large circuits ([#1235]) ([**@burgholzer**]) -- ✨ Add missing `StandardOperation` conversions in MLIR roundtrip pass ([#1071]) ([**@BertiFlorea**], [**@denialhaag**]) +- 🐛 Fix CMake installation to make `find_package(mqt-core CONFIG)` succeed + ([#1247]) ([**@burgholzer**], [**@denialhaag**]) +- 🏁 Fix stack overflows in OpenQASM layout parsing on Windows + for large circuits ([#1235]) ([**@burgholzer**]) +- ✨ Add missing `StandardOperation` conversions in MLIR roundtrip pass + ([#1071]) ([**@BertiFlorea**], [**@denialhaag**]) ## [3.2.1] - 2025-08-01 ### Fixed -- 🐛 Fix usage of `std::accumulate` by changing accumulator parameter from reference to value ([#1089]) ([**@denialhaag**]) +- 🐛 Fix usage of `std::accumulate` by changing accumulator parameter from + reference to value ([#1089]) ([**@denialhaag**]) - 🐛 Fix erroneous `contains` check in DD package ([#1088]) ([**@denialhaag**]) ## [3.2.0] - 2025-07-31 @@ -271,7 +417,8 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#320)._ ### Changed -- ✨ Expose enums to Python via `pybind11`'s new (`enum.Enum`-compatible) `py::native_enum` ([#1075]) ([**@denialhaag**]) +- ✨ Expose enums to Python via `pybind11`'s new (`enum.Enum`-compatible) + `py::native_enum` ([#1075]) ([**@denialhaag**]) - ⬆️ Require C++20 ([#897]) ([**@burgholzer**], [**@denialhaag**]) ## [3.1.0] - 2025-07-11 @@ -281,38 +428,57 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#310)._ ### Added - ✨ Add MLIR pass for merging rotation gates ([#1019]) ([**@denialhaag**]) -- ✨ Add functions to generate random vector DDs ([#975]) ([**@MatthiasReumann**]) -- ✨ Add function to approximate decision diagrams ([#908]) ([**@MatthiasReumann**]) +- ✨ Add functions to generate random vector DDs ([#975]) + ([**@MatthiasReumann**]) +- ✨ Add function to approximate decision diagrams ([#908]) + ([**@MatthiasReumann**]) - 📦 Add Windows ARM64 wheels ([#926]) ([**@burgholzer**]) - 📝 Add documentation page for MLIR ([#931]) ([**@ystade**]) -- ✨ Initial implementation of the mqtdyn Dialect ([#900]) ([**@DRovara**], [**@ystade**]) +- ✨ Initial implementation of the mqtdyn Dialect ([#900]) + ([**@DRovara**], [**@ystade**]) ### Fixed -- 🐛 Fix bug in MLIR roundtrip passes caused by accessing an invalidated iterator after erasure in a loop ([#932]) ([**@flowerthrower**]) -- 🐛 Add missing support for `sxdg` gates in Qiskit circuit import ([#930]) ([**@burgholzer**]) -- 🐛 Fix bug related to initialization of operations with duplicate operands ([#964]) ([**@ystade**]) -- 🐛 Open issue for Qiskit upstream test only when the test is actually failing not when it was cancelled ([#973]) ([**@ystade**]) -- 🐛 Fix parsing of `GPhase` in the `MQTOpt` MLIR dialect ([#1042]) ([**@ystade**], [**@DRovara**]) +- 🐛 Fix bug in MLIR roundtrip passes caused by accessing an invalidated + iterator after erasure in a loop ([#932]) ([**@flowerthrower**]) +- 🐛 Add missing support for `sxdg` gates in Qiskit circuit import ([#930]) + ([**@burgholzer**]) +- 🐛 Fix bug related to initialization of operations with duplicate operands + ([#964]) ([**@ystade**]) +- 🐛 Open issue for Qiskit upstream test only + when the test is actually failing not + when it was cancelled ([#973]) ([**@ystade**]) +- 🐛 Fix parsing of `GPhase` in the `MQTOpt` MLIR dialect ([#1042]) + ([**@ystade**], [**@DRovara**]) ### Changed -- ⬆️ Bump shared library ABI version from `3.0` to `3.1` ([#1047]) ([**@denialhaag**]) -- ♻️ Switch from reference counting to mark-and-sweep garbage collection in decision diagram package ([#1020]) ([**@MatthiasReumann**], [**burgholzer**], [**q-inho**]) -- ♻️ Move the C++ code for the Python bindings to the top-level `bindings` directory ([#982]) ([**@denialhaag**]) -- ♻️ Move all Python code (no tests) to the top-level `python` directory ([#982]) ([**@denialhaag**]) -- ⚡ Improve performance of getNqubits for StandardOperations ([#959]) ([**@ystade**]) -- ♻️ Move Make-State Functionality To StateGeneration ([#984]) ([**@MatthiasReumann**]) -- ♻️ Outsource definition of standard operations from MLIR dialects to reduce redundancy ([#933]) ([**@ystade**]) +- ⬆️ Bump shared library ABI version from `3.0` to `3.1` ([#1047]) + ([**@denialhaag**]) +- ♻️ Switch from reference counting to mark-and-sweep garbage collection in + decision diagram package ([#1020]) ([**@MatthiasReumann**], [**burgholzer**], + [**q-inho**]) +- ♻️ Move the C++ code for the Python bindings to the top-level `bindings` + directory ([#982]) ([**@denialhaag**]) +- ♻️ Move all Python code + (no tests) to the top-level `python` directory ([#982]) ([**@denialhaag**]) +- ⚡ Improve performance of getNqubits + for StandardOperations ([#959]) ([**@ystade**]) +- ♻️ Move Make-State Functionality To StateGeneration ([#984]) + ([**@MatthiasReumann**]) +- ♻️ Outsource definition of standard operations from MLIR dialects to reduce + redundancy ([#933]) ([**@ystade**]) - ♻️ Unify operands and results in MLIR dialects ([#931]) ([**@ystade**]) -- ⏪️ Restore support for (MLIR and) LLVM v19 ([#934]) ([**@flowerthrower**], [**@ystade**]) +- ⏪️ Restore support for (MLIR and) LLVM v19 ([#934]) + ([**@flowerthrower**], [**@ystade**]) - ⬆️ Update nlohmann_json to `v3.12.0` ([#921]) ([**@burgholzer**]) ## [3.0.2] - 2025-04-07 ### Added -- 📝 Add JOSS journal reference and citation information ([#913]) ([**@burgholzer**]) +- 📝 Add JOSS journal reference + and citation information ([#913]) ([**@burgholzer**]) - 📝 Add new links to Python package metadata ([#911]) ([**@burgholzer**]) ### Fixed @@ -323,7 +489,8 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#310)._ ### Fixed -- 🐛 Fix doxygen build on RtD to include C++ API docs ([#912]) ([**@burgholzer**]) +- 🐛 Fix doxygen build on RtD to include C++ API docs ([#912]) + ([**@burgholzer**]) ## [3.0.0] - 2025-04-06 @@ -331,13 +498,19 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#300)._ ### Added -- ✨ Ship shared C++ libraries with `mqt-core` Python package ([#662]) ([**@burgholzer**]) +- ✨ Ship shared C++ libraries with `mqt-core` Python package ([#662]) + ([**@burgholzer**]) - ✨ Add Python bindings for the DD package ([#838]) ([**@burgholzer**]) -- ✨ Add direct MQT `QuantumComputation` to Qiskit `QuantumCircuit` export ([#859]) ([**@burgholzer**]) +- ✨ Add direct MQT `QuantumComputation` to Qiskit `QuantumCircuit` export + ([#859]) ([**@burgholzer**]) - ✨ Support for Qiskit 2.0+ ([#860]) ([**@burgholzer**]) -- ✨ Add initial infrastructure for MLIR within the MQT ([#878], [#879], [#892], [#893], [#895]) ([**@burgholzer**], [**@ystade**], [**@DRovara**], [**@flowerthrower**], [**@BertiFlorea**]) +- ✨ Add initial infrastructure for MLIR within the MQT + ([#878], [#879], [#892], [#893], [#895]) + ([**@burgholzer**], [**@ystade**], [**@DRovara**], [**@flowerthrower**], + [**@BertiFlorea**]) - ✨ Add State Preparation Algorithm ([#543]) ([**@M-J-Hochreiter**]) -- 🚸 Add support for indexed identifiers to OpenQASM 3 parser ([#832]) ([**@burgholzer**]) +- 🚸 Add support for indexed identifiers to OpenQASM 3 parser ([#832]) + ([**@burgholzer**]) - 🚸 Allow indexed registers as operation arguments ([#839]) ([**@burgholzer**]) - 📝 Add documentation for the DD package ([#831]) ([**@burgholzer**]) - 📝 Add documentation for the ZX package ([#817]) ([**@pehamTom**]) @@ -345,26 +518,40 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#300)._ ### Changed -- **Breaking**: 🚚 MQT Core has moved to the [munich-quantum-toolkit] GitHub organization -- **Breaking**: ✨ Adopt [PEP 735] dependency groups ([#762]) ([**@burgholzer**]) -- **Breaking**: ♻️ Encapsulate the OpenQASM parser in its own library ([#822]) ([**@burgholzer**]) -- **Breaking**: ♻️ Replace `Config` template from DD package with constructor argument ([#886]) ([**@burgholzer**]) -- **Breaking**: ♻️ Remove template parameters from `MemoryManager` and adjacent classes ([#866]) ([**@rotmanjanez**]) -- **Breaking**: ♻️ Refactor algorithms to use factory functions instead of inheritance ([**@a9b7e70**]) ([**@burgholzer**]) -- **Breaking**: ♻️ Change pointer parameters to references in DD package ([#798]) ([**@burgholzer**]) -- **Breaking**: ♻️ Change registers from typedef to actual type ([#807]) ([**@burgholzer**]) -- **Breaking**: ♻️ Refactor `NAComputation` class hierarchy ([#846], [#877]) ([**@ystade**]) -- **Breaking**: ⬆️ Bump minimum required CMake version to `3.24.0` ([#879]) ([**@burgholzer**]) -- **Breaking**: ⬆️ Bump minimum required `uv` version to `0.5.20` ([#802]) ([**@burgholzer**]) +- **Breaking**: 🚚 MQT Core has moved to the [munich-quantum-toolkit] GitHub + organization +- **Breaking**: ✨ Adopt [PEP 735] dependency groups ([#762]) + ([**@burgholzer**]) +- **Breaking**: ♻️ Encapsulate the OpenQASM parser in its own library ([#822]) + ([**@burgholzer**]) +- **Breaking**: ♻️ Replace `Config` template from DD package with constructor + argument ([#886]) ([**@burgholzer**]) +- **Breaking**: ♻️ Remove template parameters from `MemoryManager` + and adjacent classes ([#866]) ([**@rotmanjanez**]) +- **Breaking**: ♻️ Refactor algorithms to use factory functions instead of + inheritance ([**@a9b7e70**]) ([**@burgholzer**]) +- **Breaking**: ♻️ Change pointer parameters to references in DD package + ([#798]) ([**@burgholzer**]) +- **Breaking**: ♻️ Change registers from typedef to actual type ([#807]) + ([**@burgholzer**]) +- **Breaking**: ♻️ Refactor `NAComputation` class hierarchy + ([#846], [#877]) ([**@ystade**]) +- **Breaking**: ⬆️ Bump minimum required CMake version to `3.24.0` ([#879]) + ([**@burgholzer**]) +- **Breaking**: ⬆️ Bump minimum required `uv` version to `0.5.20` ([#802]) + ([**@burgholzer**]) - 📝 Rework existing project documentation ([#789], [#842]) ([**@burgholzer**]) - 📄 Use [PEP 639] license expressions ([#847]) ([**@burgholzer**]) ### Removed -- **Breaking**: 🔥 Remove the `Teleportation` gate from the IR ([#882]) ([**@burgholzer**]) -- **Breaking**: 🔥 Remove parsers for `.real`, `.qc`, `.tfc`, and `GRCS` files ([#822]) ([**@burgholzer**]) +- **Breaking**: 🔥 Remove the `Teleportation` gate from the IR ([#882]) + ([**@burgholzer**]) +- **Breaking**: 🔥 Remove parsers for `.real`, `.qc`, `.tfc`, + and `GRCS` files ([#822]) ([**@burgholzer**]) - **Breaking**: 🔥 Remove tensor dump functionality ([#798]) ([**@burgholzer**]) -- **Breaking**: 🔥 Remove `extract_probability_vector` functionality ([#883]) ([**@burgholzer**]) +- **Breaking**: 🔥 Remove `extract_probability_vector` functionality ([#883]) + ([**@burgholzer**]) ### Fixed @@ -373,12 +560,16 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#300)._ - 🐛 Fix stripping of idle qubits ([#763]) ([**@burgholzer**]) - 🐛 Fix permutation handling in OpenQASM dump ([#810]) ([**@burgholzer**]) - 🐛 Fix out-of-bounds error in ZX `EdgeIterator` ([#758]) ([**@burgholzer**]) -- 🐛 Fix endianness in DCX and XX_minus_YY gate matrix definition ([#741]) ([**@burgholzer**]) -- 🐛 Fix needless dummy register in empty circuit construction ([#758]) ([**@burgholzer**]) +- 🐛 Fix endianness in DCX + and XX_minus_YY gate matrix definition ([#741]) ([**@burgholzer**]) +- 🐛 Fix needless dummy register in empty circuit construction ([#758]) + ([**@burgholzer**]) ## [2.7.0] - 2024-10-08 -_📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-toolkit/core/releases) for previous changelogs._ +_📚 Refer to the [GitHub Release +Notes](https://github.com/munich-quantum-toolkit/core/releases) for previous +changelogs._ @@ -549,7 +740,6 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool [#1186]: https://github.com/munich-quantum-toolkit/core/pull/1186 [#1181]: https://github.com/munich-quantum-toolkit/core/pull/1181 [#1180]: https://github.com/munich-quantum-toolkit/core/pull/1180 -[#1165]: https://github.com/munich-quantum-toolkit/core/pull/1165 [#1164]: https://github.com/munich-quantum-toolkit/core/pull/1164 [#1157]: https://github.com/munich-quantum-toolkit/core/pull/1157 [#1151]: https://github.com/munich-quantum-toolkit/core/pull/1151 @@ -650,7 +840,6 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool [**@li-mingbao**]: https://github.com/li-mingbao [**@lavanya-m-k**]: https://github.com/lavanya-m-k [**@taminob**]: https://github.com/taminob -[**@jannikpflieger**]: https://github.com/jannikpflieger [**@lsschmid**]: https://github.com/lsschmid [**@marcelwa**]: https://github.com/marcelwa [**@lirem101**]: https://github.com/lirem101 @@ -665,7 +854,6 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool [Keep a Changelog]: https://keepachangelog.com/en/1.1.0/ [Common Changelog]: https://common-changelog.org [Semantic Versioning]: https://semver.org/spec/v2.0.0.html -[GitHub Release Notes]: https://github.com/munich-quantum-toolkit/core/releases [munich-quantum-toolkit]: https://github.com/munich-quantum-toolkit [PEP 639]: https://peps.python.org/pep-0639/ [PEP 735]: https://peps.python.org/pep-0735/ diff --git a/README.md b/README.md index dfa95b3c67..4fdde16eaf 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,9 @@ # MQT Core - The Backbone of the Munich Quantum Toolkit (MQT) -MQT Core is an open-source C++20 and Python library for quantum computing that forms the backbone of the quantum software tools developed as part of the [_Munich Quantum Toolkit (MQT)_](https://mqt.readthedocs.io). +MQT Core is an open-source C++20 and Python library for quantum computing +that forms the backbone of the quantum software tools developed +as part of the [_Munich Quantum Toolkit (MQT)_](https://mqt.readthedocs.io).

@@ -33,12 +35,20 @@ MQT Core is an open-source C++20 and Python library for quantum computing that f - A dedicated ZX-diagram package for working with the ZX-calculus. - A QIR runtime based on the decision diagram package. -If you have any questions, feel free to create a [discussion](https://github.com/munich-quantum-toolkit/core/discussions) or an [issue](https://github.com/munich-quantum-toolkit/core/issues) on [GitHub](https://github.com/munich-quantum-toolkit/core). +If you have any questions, feel free to create a +[discussion](https://github.com/munich-quantum-toolkit/core/discussions) or an +[issue](https://github.com/munich-quantum-toolkit/core/issues) on +[GitHub](https://github.com/munich-quantum-toolkit/core). ## Contributors and Supporters -MQT Core is developed by the [Chair for Design Automation](https://www.cda.cit.tum.de/) at the [Technical University of Munich](https://www.tum.de/) and [MQSC](https://mq.sc). -Among others, it is part of the [Munich Quantum Software Stack (MQSS)](https://www.munich-quantum-valley.de/research/research-areas/mqss) ecosystem, which is being developed as part of the [Munich Quantum Valley (MQV)](https://www.munich-quantum-valley.de) initiative. +MQT Core is developed by the +[Chair for Design Automation](https://www.cda.cit.tum.de/) at the +[Technical University of Munich](https://www.tum.de/) and [MQSC](https://mq.sc). +Among others, it is part of the +[Munich Quantum Software Stack (MQSS)](https://www.munich-quantum-valley.de/research/research-areas/mqss) +ecosystem, which is being developed as part of the +[Munich Quantum Valley (MQV)](https://www.munich-quantum-valley.de) initiative.

@@ -55,17 +65,22 @@ Thank you to all the contributors who have helped make MQT Core a reality!

-The MQT will remain free, open-source, and permissively licensed—now and in the future. -We are firmly committed to keeping it open and actively maintained for the quantum computing community. +The MQT will remain free, open-source, and permissively licensed— +now and in the future. +We are firmly committed to keeping it open and actively maintained +for the quantum computing community. To support this endeavor, please consider: -- Starring and sharing our repositories: https://github.com/munich-quantum-toolkit -- Contributing code, documentation, tests, or examples via issues and pull requests +- Starring and sharing our repositories: https: + //github.com/munich-quantum-toolkit +- Contributing code, documentation, tests, + or examples via issues and pull requests - Citing the MQT in your publications (see [Cite This](#cite-this)) -- Citing our research in your publications (see [References](https://mqt.readthedocs.io/projects/core/en/latest/references.html)) +- Citing our research in your publications (see + [References](https://mqt.readthedocs.io/projects/core/en/latest/references.html)) - Using the MQT in research and teaching, and sharing feedback and use cases -- Sponsoring us on GitHub: https://github.com/sponsors/munich-quantum-toolkit +- Sponsoring us on GitHub:

@@ -94,26 +109,43 @@ qc.measure(range(2), range(2)) print(qc) ``` -**Detailed documentation and examples are available at [ReadTheDocs](https://mqt.readthedocs.io/projects/core).** +**Detailed documentation and examples are available at +[ReadTheDocs](https://mqt.readthedocs.io/projects/core).** ## System Requirements -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/core). -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 Core 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/core). +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 Core is compatible with all +[officially supported Python versions](https://devguide.python.org/versions/). The project relies on some external dependencies: -- [boost/multiprecision](https://github.com/boostorg/multiprecision): A library for multiprecision arithmetic (used in the ZX package). -- [nlohmann/json](https://github.com/nlohmann/json): A JSON library for modern C++. -- [google/googletest](https://github.com/google/googletest): A testing framework for C++ (only used in tests). +- [boost/multiprecision](https://github.com/boostorg/multiprecision): + A library for multiprecision arithmetic (used in the ZX package). +- [nlohmann/json](https://github.com/nlohmann/json): + A JSON library for modern C++. +- [google/googletest](https://github.com/google/googletest): + A testing framework for C++ (only used in tests). -CMake will automatically look for installed versions of these libraries. If it does not find them, they will be fetched automatically at configure time via the [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module (check out the documentation for more information on how to customize this behavior). +CMake will automatically look for installed versions of these libraries. +If it does not find them, +they will be fetched automatically at configure time via the +[FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) +module (check out the documentation for more information on how to customize +this behavior). -It is recommended (although not required) to have [GraphViz](https://www.graphviz.org) installed for visualization purposes. +It is recommended (although not required) to have +[GraphViz](https://www.graphviz.org) installed for visualization purposes. -If you want to use the ZX library, it is recommended (although not strictly necessary) to have [GMP](https://gmplib.org/) installed in your system. +If you want to use the ZX library, it is recommended +(although not strictly necessary) +to have [GMP](https://gmplib.org/) installed in your system. ## Cite This @@ -121,7 +153,8 @@ Please cite the work that best fits your use case. ### MQT Core (the tool) -When citing the software itself or results produced with it, cite the MQT Core paper: +When citing the software itself or results produced with it, +cite the MQT Core paper: ```bibtex @article{burgholzer2025MQTCore, @@ -140,7 +173,8 @@ When citing the software itself or results produced with it, cite the MQT Core p ### The MQT Compiler Collection -When citing the compilation framework built on MLIR, cite the MQT Compiler Collection paper: +When citing the compilation framework built on MLIR, +cite the MQT Compiler Collection paper: ```bibtex @article{MQTCompilerCollection2026, @@ -176,7 +210,12 @@ When discussing the overall MQT project or its ecosystem, cite the MQT Handbook: ## 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 543aa40488..57f56a5587 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,49 +1,74 @@ # 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] ### MLIR enabled by default for C++ builds -The MLIR-based functionality within MQT Core has long been experimental and opt-in. +The MLIR-based functionality within MQT Core has long been experimental +and opt-in. Starting with this release, MLIR is enabled by default for C++ library builds. -This means that LLVM 22.1+ (including MLIR) is now a required dependency for building MQT Core from source. - -We offer pre-built distributions for all supported platforms as part of the `setup-mlir` project at [munich-quantum-software/setup-mlir](https://github.com/munich-quantum-software/setup-mlir). -Please follow the instructions there to install the distribution for your platform. -You can then point CMake to the installation directory using the `-DMLIR_DIR=/path/to/mlir/installation/lib/cmake/mlir` option. - -The MLIR components can still be manually disabled by passing `-DBUILD_MQT_CORE_MLIR=OFF` to CMake. -MLIR is also not enabled for the Python package builds because no functionality depends on it yet. -This is expected to change in the future, when we expose the MLIR-based functionality via the Python package. +This means that LLVM 22.1+ +(including MLIR) is now a required dependency for building MQT Core from source. + +We offer pre-built distributions for all supported platforms +as part of the `setup-mlir` project at +[munich-quantum-software/setup-mlir](https://github.com/munich-quantum-software/setup-mlir). +Please follow the instructions there to install the distribution +for your platform. +You can then point CMake to the installation directory using the +`-DMLIR_DIR=/path/to/mlir/installation/lib/cmake/mlir` option. + +The MLIR components can still be manually disabled by passing +`-DBUILD_MQT_CORE_MLIR=OFF` to CMake. +MLIR is also not enabled for the Python package builds +because no functionality depends on it yet. +This is expected to change in the future, +when we expose the MLIR-based functionality via the Python package. Known limitations: -- Our pre-built distributions are incompatible with GCC on macOS. Use (Apple)Clang instead or compile LLVM from source using your preferred compiler. -- AppleClang 17+ is required to build MQT Core with MLIR enabled due to some C++20 features being used that are not yet properly supported by older versions. -- Our pre-built distributions are compiled in Release mode. On Windows, this leads to ABI incompatibilities with debug builds. Either build in Release mode or build LLVM from source in Debug mode to resolve this. +- Our pre-built distributions are incompatible with GCC on macOS. + Use (Apple)Clang instead + or compile LLVM from source using your preferred compiler. +- AppleClang 17+ is required to build MQT Core with MLIR enabled due to some + C++20 features being used that are not yet properly supported by older + versions. +- Our pre-built distributions are compiled in Release mode. + On Windows, this leads to ABI incompatibilities with debug builds. + Either build in Release mode + or build LLVM from source in Debug mode to resolve this. ### Removal of the density matrix support from the DD package The density matrix support within the DD package has been removed. This change was made to reduce the maintenance burden of the package. -Any libraries that depend on the density matrix functionality, such as [MQT DDSIM], need to implement it on their own or use an alternative solution. -In a related fashion, this PR also removes the noise operations from the MQT Core IR as they no longer serve a purpose. +Any libraries that depend on the density matrix functionality, +such as [MQT DDSIM], need to implement it on their own +or use an alternative solution. +In a related fashion, this PR also removes the noise operations from the MQT +Core IR as they no longer serve a purpose. ### Removal of the `datastructures` (sub)library The `datastructures` (sub)library has been removed from the MQT Core repository. Its functionality has only ever been used in [MQT QMAP] since its inception. -As a consequence, the code shall be moved to [MQT QMAP] once QMAP adopts an MQT Core version that includes this change. +As a consequence, the code shall be moved to [MQT QMAP] +once QMAP adopts an MQT Core version that includes this change. ### 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. -They assume that `MLIR_DIR` is defined in your environment and pointing to an MLIR installation. +They assume that `MLIR_DIR` is defined in your environment +and pointing to an MLIR installation. -On Unix systems, the `debug`, `release`, and `coverage` presets can be used to configure, build, and test MQT Core. +On Unix systems, the `debug`, `release`, +and `coverage` presets can be used to configure, build, and test MQT Core. ```console cmake --preset release @@ -51,33 +76,48 @@ cmake --build --preset release ctest --preset release ``` -Additionally, the `lint` preset can be used to configure and build MQT Core in preparation for a `clang-tidy` run. +Additionally, the `lint` preset can be used to configure +and build MQT Core in preparation for a `clang-tidy` run. If you are on Windows, use the `debug-windows` and `release-windows` presets. ## [3.6.0] The shared library ABI version (`SOVERSION`) is increased from `3.5` to `3.6`. -Thus, consuming libraries need to update their wheel repair configuration for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in the wheel repair step. +Thus, consuming libraries need to update their wheel repair configuration +for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in +the wheel repair step. ### Changes to builtin QDMI devices -The builtin QDMI devices (with prefixes `MQT_SC`, `MQT_NA`, and `MQT_DDSIM`) are now all built as shared libraries by default. -In turn, the shared library wrappers (with prefixes `MQT_SC_DYN` and `MQT_NA_DYN`) have been removed entirely. -MQT Core's QDMI driver will automatically load the shared libraries of the builtin devices if they are available in the library search path. -If you were previously using the statically builtin devices, no changes should be necessary as the shared libraries are now the default. -If you were previously using the shared library wrappers, you should switch to using the builtin devices instead, which are now shared libraries by default. +The builtin QDMI devices +(with prefixes `MQT_SC`, `MQT_NA`, and `MQT_DDSIM`) +are now all built as shared libraries by default. +In turn, the shared library wrappers +(with prefixes `MQT_SC_DYN` and `MQT_NA_DYN`) have been removed entirely. +MQT Core's QDMI driver will automatically load the shared libraries of the +builtin devices if they are available in the library search path. +If you were previously using the statically builtin devices, +no changes should be necessary as the shared libraries are now the default. +If you were previously using the shared library wrappers, +you should switch to using the builtin devices instead, +which are now shared libraries by default. ### Broader operation support in QDMI Qiskit converter -The QDMI Qiskit converter now supports a broader range of operations, including multi-controlled gates such as `mcx`, `mcz`, `mcrx`, and more. -As a consequence, these operations can now be directly used without requiring decomposition, for example, with the builtin `DDSIM` QDMI device. +The QDMI Qiskit converter now supports a broader range of operations, +including multi-controlled gates such as `mcx`, `mcz`, `mcrx`, and more. +As a consequence, these operations can now be directly used without requiring +decomposition, for example, with the builtin `DDSIM` QDMI device. ### Minimum supported Qiskit version From this release onwards, MQT Core requires Qiskit version 1.1.0 or higher. -This is due to the fact that we are relying on some fixes to Qiskit primitives that were introduced in that version. -If you are using MQT Core with Qiskit, please ensure that you have updated to Qiskit 1.1.0 or higher to avoid any compatibility issues. +This is due to the fact that we are relying on some fixes to Qiskit primitives +that were introduced in that version. +If you are using MQT Core with Qiskit, +please ensure that you have updated to Qiskit 1.1.0 +or higher to avoid any compatibility issues. ## [3.5.1] @@ -85,23 +125,32 @@ No breaking changes. ### Component-based CMake installs -Fixed exported `nlohmann_json` CMake metadata so `find_package(mqt-core CONFIG)` no longer propagates an invalid `.../COMPONENT` include directory in component-based installations. -Anyone relying on an installed version of `mqt-core` should update from 3.5.0 to 3.5.1. +Fixed exported `nlohmann_json` CMake metadata +so `find_package(mqt-core CONFIG)` no longer propagates an invalid +`.../COMPONENT` include directory in component-based installations. +Anyone relying on an installed version of `mqt-core` should update from 3.5.0 to +3.5.1. ## [3.5.0] The shared library ABI version (`SOVERSION`) is increased from `3.4` to `3.5`. -Thus, consuming libraries need to update their wheel repair configuration for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in the wheel repair step. +Thus, consuming libraries need to update their wheel repair configuration +for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in +the wheel repair step. ### `nanobind` updated to version 2.12.0 -This release updates the `nanobind` dependency to version 2.12.0, which includes an ABI bump. -Any existing code that uses the `mqt-core` Python bindings will need to be recompiled with the new `nanobind` version. +This release updates the `nanobind` dependency to version 2.12.0, +which includes an ABI bump. +Any existing code that uses the `mqt-core` Python bindings will need to be +recompiled with the new `nanobind` version. ## [3.4.0] The shared library ABI version (`SOVERSION`) is increased from `3.3` to `3.4`. -Thus, consuming libraries need to update their wheel repair configuration for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in the wheel repair step. +Thus, consuming libraries need to update their wheel repair configuration +for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in +the wheel repair step. ### Python wheels @@ -111,10 +160,13 @@ First, we have removed all wheels for Python 3.13t. Free-threading Python was introduced as an experimental feature in Python 3.13. It became stable in Python 3.14. -Second, for Python 3.12+, we are now providing Stable ABI wheels instead of separate version-specific wheels. +Second, for Python 3.12+, +we are now providing Stable ABI wheels instead of separate version-specific +wheels. This was enabled by migrating our Python bindings from `pybind11` to `nanobind`. -Both of these changes were made in the interest of conserving PyPI space and reducing CI/CD build times. +Both of these changes were made in the interest of conserving PyPI space +and reducing CI/CD build times. The full list of wheels now reads: - 3.10 @@ -124,8 +176,11 @@ The full list of wheels now reads: ### QDMI-Qiskit integration -This release introduces a Qiskit `BackendV2`-compatible interface to QDMI devices. -The `mqt.core.plugins.qiskit` module has been extended with `QDMIProvider`, `QDMIBackend`, and `QDMIJob` classes that allow running Qiskit circuits on QDMI-compliant devices. +This release introduces a Qiskit `BackendV2`-compatible interface to QDMI +devices. +The `mqt.core.plugins.qiskit` module has been extended with `QDMIProvider`, +`QDMIBackend`, and `QDMIJob` classes +that allow running Qiskit circuits on QDMI-compliant devices. Users can now execute Qiskit circuits directly on QDMI devices: @@ -138,17 +193,26 @@ job = backend.run(circuit, shots=1024) result = job.result() ``` -The backend automatically converts circuits to QASM, introspects device capabilities, validates circuits, and formats results. -The existing FoMaC interface (`mqt.core.fomac`) remains fully supported for direct, low-level access to QDMI devices. +The backend automatically converts circuits to QASM, +introspects device capabilities, validates circuits, and formats results. +The existing FoMaC interface (`mqt.core.fomac`) remains fully supported +for direct, low-level access to QDMI devices. Install with Qiskit support: `uv pip install "mqt-core[qiskit]"` -See the [Qiskit Backend documentation](https://mqt.readthedocs.io/projects/core/en/latest/qdmi/qiskit_backend.html) for details. +See the +[Qiskit Backend documentation](https://mqt.readthedocs.io/projects/core/en/latest/qdmi/qiskit_backend.html) +for details. ### Argument name changes in `QuantumComputation` and `CompoundOperation` dunder methods -Since we enabled `ty` for type checking, it revealed that some of the dunder methods of `QuantumComputation` and `CompoundOperation` had incorrect argument names, which would prevent these classes from properly implementing the `MutableSequence` protocol. -This release fixes these issues by renaming the arguments of the following methods: +Since we enabled `ty` for type checking, +it revealed that some of the dunder methods of `QuantumComputation` +and `CompoundOperation` had incorrect argument names, +which would prevent these classes from properly implementing the +`MutableSequence` protocol. +This release fixes these issues by renaming the arguments of the following +methods: - `QuantumComputation.__getitem__` - `QuantumComputation.__setitem__` @@ -161,23 +225,33 @@ This release fixes these issues by renaming the arguments of the following metho - `CompoundOperation.insert` - `CompoundOperation.append` -All index arguments are now named `index` instead of `idx` (or `i` or `slice`) and all values are now named `value` instead of `val` (or `op` or `ops`). +All index arguments are now named `index` instead of `idx` +(or `i` or `slice`) +and all values are now named `value` instead of `val` (or `op` or `ops`). ### DD Package evaluation -This release moves the DD Package evaluation functionality from within the `mqt.core` package to a dedicated script in the `eval` directory. -In the process, the `mqt-core-dd-compare` entry point as well as the `evaluation` extra have been removed. -The `eval/dd_evaluation.py` script acts as a drop-in replacement for the previous CLI entry point. -Since the `eval` directory is not part of the Python package, this functionality is only available via source installations or by cloning the repository. +This release moves the DD Package evaluation functionality from within the +`mqt.core` package to a dedicated script in the `eval` directory. +In the process, the `mqt-core-dd-compare` entry point as well +as the `evaluation` extra have been removed. +The `eval/dd_evaluation.py` script acts as a drop-in replacement +for the previous CLI entry point. +Since the `eval` directory is not part of the Python package, +this functionality is only available via source installations +or by cloning the repository. ## [3.3.0] The shared library ABI version (`SOVERSION`) is increased from `3.2` to `3.3`. -Thus, consuming libraries need to update their wheel repair configuration for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in the wheel repair step. +Thus, consuming libraries need to update their wheel repair configuration +for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in +the wheel repair step. ### IfElseOperation -This release introduces an `IfElseOperation` to the C++ library and the Python package to support Qiskit's `IfElseOp`. +This release introduces an `IfElseOperation` to the C++ library +and the Python package to support Qiskit's `IfElseOp`. The new operation replaces the `ClassicControlledOperation`. An `IfElseOperation` can be added to a `QuantumComputation` using `if_else()`. @@ -200,82 +274,131 @@ qc.if_(op_type=OpType.x, target=0, control_bit=0) Starting with this release, MQT Core no longer supports Python 3.9. This is in line with the scheduled end of life of the version. -As a result, MQT Core is no longer tested under Python 3.9 and no longer ships Python 3.9 wheels. +As a result, MQT Core is no longer tested under Python 3.9 +and no longer ships Python 3.9 wheels. ## [3.2.0] The shared library ABI version (`SOVERSION`) is increased from `3.1` to `3.2`. -Thus, consuming libraries need to update their wheel repair configuration for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in the wheel repair step. - -With this release, 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. +Thus, consuming libraries need to update their wheel repair configuration +for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in +the wheel repair step. + +With this release, 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. Some frameworks we plan to integrate with even require C++20 by now. -The `dd.BasisStates`, `ir.operations.ComparisonKind`, `ir.operations.Control.Type`, and `ir.operations.OpType` enums are now exposed via `pybind11`'s new `py::native_enum`, which makes them compatible with Python's `enum.Enum` class (PEP 435). +The `dd.BasisStates`, `ir.operations.ComparisonKind`, +`ir.operations.Control.Type`, +and `ir.operations.OpType` enums 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 `OpType("x")`, use `OpType.x`. ## [3.1.0] The shared library ABI version (`SOVERSION`) is increased from `3.0` to `3.1`. -Thus, consuming libraries need to update their wheel repair configuration for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in the wheel repair step. +Thus, consuming libraries need to update their wheel repair configuration +for `cibuildwheel` to ensure the `mqt-core` libraries are properly skipped in +the wheel repair step. -Even though this is not a breaking change, it is worth mentioning to developers of MQT Core 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. +Even though this is not a breaking change, +it is worth mentioning to developers of MQT Core 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. ### DD Package -The `makeZeroState`, `makeBasisState`, `makeGHZState`, `makeWState`, and `makeStateFromVector` methods have been refactored to functions taking the DD package as an argument. These functions reside in the `StateGeneration` header. Any existing code that uses these methods must replace the respective calls with their function counterpart. +The `makeZeroState`, `makeBasisState`, `makeGHZState`, `makeWState`, +and `makeStateFromVector` methods have been refactored to functions taking the +DD package as an argument. +These functions reside in the `StateGeneration` header. +Any existing code that uses these methods must replace the respective calls with +their function counterpart. ## [3.0.0] -This major release introduces several breaking changes, including the removal of deprecated features and the introduction of new APIs. -In preparation for this release, most direct dependents of MQT Core have been updated to use the new APIs. -The following sections 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 and the introduction of new APIs. +In preparation for this release, +most direct dependents of MQT Core have been updated to use the new APIs. +The following sections describe the most important changes +and how to adapt your code accordingly. We intend to provide a more comprehensive migration guide for future releases. ### Intermediate Representation (IR) -The OpenQASM parser has been encapsulated in its own library, which is now a dedicated target in the CMake build system. -Any use of `qc::QuantumComputation::import...` needs to be replaced with the respective `qasm3::Importer::load...` function. +The OpenQASM parser has been encapsulated in its own library, +which is now a dedicated target in the CMake build system. +Any use of `qc::QuantumComputation::import...` needs to be replaced with the +respective `qasm3::Importer::load...` function. -Several parsers have been removed, 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. +Several parsers have been removed, 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. -The `Teleportation` gate has been removed from the IR. This was a placeholder gate and was only used in a single method (in [MQT QMAP]), which is bound to be removed as part of [MQT QMAP] `v3.0.0`. +The `Teleportation` gate has been removed from the IR. +This was a placeholder gate and was only used in a single method +(in [MQT QMAP]), which is bound to be removed as part of [MQT QMAP] `v3.0.0`. -[MQT QCEC], [MQT QMAP], and [MQT DDSIM] have been updated to use the new API, which will be released in [MQT QCEC] `v3.0.0`, [MQT QMAP] `v3.0.0` and [MQT DDSIM] `v2.0.0`. +[MQT QCEC], [MQT QMAP], and [MQT DDSIM] have been updated to use the new API, +which will be released in [MQT QCEC] `v3.0.0`, +[MQT QMAP] `v3.0.0` and [MQT DDSIM] `v2.0.0`. ### DD Package -The DD package has undergone some initial refactoring to streamline the implementation and prepare it for future extensions. -The `Config` template has been removed in favor of a constructor that takes the configuration as a parameter. -Any existing code using `dd::Package<...>` needs to be updated to use `dd::Package` or `dd::Package(numQubits, ...)` instead. -The `MemoryManager` and adjacent classes have been refactored to remove the template parameters. -This should not have user-visible effects, but it is a breaking change nonetheless. -Depending libraries may now also use the `mqt-core` Python package to interact with the DD package. - -[MQT QCEC] and [MQT DDSIM] have been updated to use the new API, which will be released in [MQT QCEC] `v3.0.0` and [MQT DDSIM] `v2.0.0`. +The DD package has undergone some initial refactoring to streamline the +implementation and prepare it for future extensions. +The `Config` template has been removed in favor of a constructor +that takes the configuration as a parameter. +Any existing code using `dd::Package<...>` needs to be updated to use +`dd::Package` or `dd::Package(numQubits, ...)` instead. +The `MemoryManager` and adjacent classes have been refactored to remove the +template parameters. +This should not have user-visible effects, +but it is a breaking change nonetheless. +Depending libraries may now also use the `mqt-core` Python package to interact +with the DD package. + +[MQT QCEC] and [MQT DDSIM] have been updated to use the new API, +which will be released in [MQT QCEC] `v3.0.0` and [MQT DDSIM] `v2.0.0`. ### Neutral Atom Quantum Computing -The `NAComputation` class hierarchy has been refactored to use an MLIR-inspired design. This will act as a foundation for future extensions and improvements. +The `NAComputation` class hierarchy has been refactored to use an MLIR-inspired +design. +This will act as a foundation for future extensions and improvements. -[MQT QMAP] has been updated to use the new API, which will be released in [MQT QMAP] `v3.0.0`. +[MQT QMAP] has been updated to use the new API, +which will be released in [MQT QMAP] `v3.0.0`. ### General -MQT Core has moved to the [munich-quantum-toolkit](https://github.com/munich-quantum-toolkit) GitHub organization under https://github.com/munich-quantum-toolkit/core. -While most links should be automatically redirected, please update any links in your code to point to the new location. +MQT Core 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 Core now ships all its C++ libraries as shared libraries with the `mqt-core` Python package. -Depending packages can now solely rely on the Python package for obtaining the C++ libraries. -This is demonstrated in [MQT QCEC] `v3.0.0`, [MQT QMAP] `v3.0.0` and [MQT DDSIM] `v2.0.0`, which will be released in the near future. +MQT Core now ships all its C++ libraries +as shared libraries with the `mqt-core` Python package. +Depending packages can now solely rely on the Python package +for obtaining the C++ libraries. +This is demonstrated in [MQT QCEC] `v3.0.0`, +[MQT QMAP] `v3.0.0` and [MQT DDSIM] `v2.0.0`, +which will be released in the near future. MQT Core 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. It also requires the `uv` library version 0.5.20 or higher. diff --git a/docs/contributing.md b/docs/contributing.md index 2d99a4c536..981b536cd6 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -6,9 +6,8 @@ Thank you for your interest in contributing to MQT Core! This document outlines the development guidelines and how to contribute. -We use GitHub to -[host code](https://github.com/munich-quantum-toolkit/core), to -[track issues and feature requests][issues], as well as accept +We use GitHub to [host code](https://github.com/munich-quantum-toolkit/core), +to [track issues and feature requests][issues], as well as accept [pull requests](https://github.com/munich-quantum-toolkit/core/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_CORE_TESTS=OFF` to the CMake -configure step. +you can pass {code}`-DBUILD_MQT_CORE_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/core). +and uploads it to [Codecov](https://codecov.io/gh/munich-quantum-toolkit/core). 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_CORE_BINDINGS=ON` to the CMake configure -step. +pass {code}`-DBUILD_MQT_CORE_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,8 +460,7 @@ configure step to point CMake to a specific Python installation. ::: -The Python package itself lives in the {code}`python/mqt/core` -directory. +The Python package itself lives in the {code}`python/mqt/core` directory. The package lives in the {code}`src/mqt/core` directory. @@ -584,8 +579,8 @@ 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/core` directory. +we provide type hints in the form of stub files in the {code}`python/mqt/core` +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 Core. If you are sure that the dependency update does not introduce any breaking -changes for MQT Core, you can remove the {code}`minor` or {code}`major` -label from the PR. +changes for MQT Core, 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/dd_package.md b/docs/dd_package.md index 5ff1f2d1e7..d9b23f6750 100644 --- a/docs/dd_package.md +++ b/docs/dd_package.md @@ -13,19 +13,34 @@ mystnb: # MQT Core DD -MQT Core provides a fully-fledged, high-performance decision diagram package for quantum computing. -The resulting library allows for the efficient representation and manipulation of quantum states and operations. -If you are not yet familiar with decision diagrams as a data structure, you might want to start with the [introduction to quantum decision diagrams](#how-do-quantum-decision-diagrams-work) below. - -Throughout the MQT, this library enables many classical simulation, synthesis, or verification techniques. -While primarily developed in C++, the corresponding functionality is also exposed to Python users in the form of the {py:mod}`mqt.core.dd` module. -The following section provides an overview on how to work with decision diagrams in MQT Core from Python. +MQT Core provides a fully-fledged, +high-performance decision diagram package for quantum computing. +The resulting library allows for the efficient representation +and manipulation of quantum states and operations. +If you are not yet familiar with decision diagrams as a data structure, +you might want to start with the +[introduction to quantum decision diagrams](#how-do-quantum-decision-diagrams-work) +below. + +Throughout the MQT, this library enables many classical simulation, synthesis, +or verification techniques. +While primarily developed in C++, +the corresponding functionality is also exposed to Python users in the form of +the {py:mod}`mqt.core.dd` module. +The following section provides an overview on how to work with decision diagrams +in MQT Core from Python. ## Quickstart -In its simplest use case, the MQT Core DD package can be used as a classical circuit simulator using the -{py:func}`~mqt.core.dd.sample` function. -The underlying simulation approach supports mid-circuit measurements, reset operations, as well as classically-controlled operations. For example, the following code snippet demonstrates how to simulate the iterative quantum phase estimation algorithm shown in [the MQT Core IR Quickstart guide](mqt_core_ir). +In its simplest use case, +the MQT Core DD package can be used +as a classical circuit simulator using the {py: +func}`~mqt.core.dd.sample` function. +The underlying simulation approach supports mid-circuit measurements, +reset operations, as well as classically-controlled operations. +For example, the following code snippet demonstrates how to simulate the +iterative quantum phase estimation algorithm shown in +[the MQT Core IR Quickstart guide](mqt_core_ir). ```{code-cell} ipython3 from mqt.core.dd import sample @@ -121,19 +136,18 @@ generate_plot(counts, name, light=False) ``` ```{figure} fig-qpe-light.svg -:align: center -:width: 75% -:figclass: only-light -``` +:align: center :width: 75% :figclass: only-light ``` ```{figure} fig-qpe-dark.svg -:align: center -:width: 75% -:figclass: only-dark -``` +:align: center :width: 75% :figclass: only-dark ``` -The {py:func}`~mqt.core.dd.sample` function is a high-level interface to the decision diagram package that does not require any knowledge of the underlying data structure. -In a similar fashion, the {py:func}`~mqt.core.dd.simulate_statevector` and {py:func}`~mqt.core.dd.build_unitary` functions can be used to perform statevector simulation or to construct the unitary matrix representation of a quantum circuit, respectively. +The {py:func}`~mqt.core.dd.sample` function is a high-level interface to the +decision diagram package that does not require any knowledge of the underlying +data structure. +In a similar fashion, the {py:func}`~mqt.core.dd.simulate_statevector` and {py: +func}`~mqt.core.dd.build_unitary` functions can be used to perform statevector +simulation or to construct the unitary matrix representation of a quantum +circuit, respectively. ```{code-cell} ipython3 from mqt.core.dd import simulate_statevector @@ -157,11 +171,17 @@ with np.printoptions(precision=3, suppress=True): print(unitary) ``` -Both of these functions are inherently limited in their scalability due to the exponential growth of the resulting data structures. -MQT Core also allows one to work with decision diagrams directly, which is particularly useful for larger quantum circuits. -To this end, the {py:class}`~mqt.core.dd.DDPackage` class provides a low-level interface to the decision diagram package. -An instance of this class can be used to simulate quantum circuits (see {py:func}`~mqt.core.dd.simulate`), -construct unitary matrices (see {py:func}`~mqt.core.dd.build_functionality`), or perform other operations on decision diagrams. +Both of these functions are inherently limited in their scalability due to the +exponential growth of the resulting data structures. +MQT Core also allows one to work with decision diagrams directly, +which is particularly useful for larger quantum circuits. +To this end, the {py:class}`~mqt.core.dd.DDPackage` class provides a low-level +interface to the decision diagram package. +An instance of this class can be used to simulate quantum circuits +(see {py:func}`~mqt.core.dd.simulate`), +construct unitary matrices +(see {py:func}`~mqt.core.dd.build_functionality`), +or perform other operations on decision diagrams. ```{code-cell} ipython3 from mqt.core.dd import DDPackage, simulate @@ -171,9 +191,11 @@ zero_state_dd = dd.zero_state(qc.num_qubits) out_state_dd = simulate(qc, zero_state_dd, dd) ``` -If the [Graphviz](https://www.graphviz.org/) library is installed, the `graphviz` Python package can be used to visualize resulting -decision diagram via the {py:meth}`~mqt.core.dd.VectorDD.to_dot` method. -To directly, generate SVG files, the {py:meth}`~mqt.core.dd.VectorDD.to_svg` method can be used. +If the [Graphviz](https://www.graphviz.org/) library is installed, +the `graphviz` Python package can be used to visualize resulting decision +diagram via the {py:meth}`~mqt.core.dd.VectorDD.to_dot` method. +To directly, generate SVG files, the {py: +meth}`~mqt.core.dd.VectorDD.to_svg` method can be used. ```{code-cell} ipython3 --- @@ -187,23 +209,45 @@ import graphviz graphviz.Source(out_state_dd.to_dot()) ``` -The DD package provides list of additional functionality when it comes to working with decision diagrams. -Check out the full API documentation of the {py:class}`~mqt.core.dd.DDPackage` class for more details. +The DD package provides list of additional functionality +when it comes to working with decision diagrams. +Check out the full API documentation of the {py: +class}`~mqt.core.dd.DDPackage` class for more details. ## How do Quantum Decision Diagrams Work? -Decision diagrams were introduced in the 1980s as a data structure for the efficient representation and manipulation of Boolean functions {cite:p}`bryantGraphbasedAlgorithmsBoolean1986`. -This led to the emergence of a wide variety of decision diagrams, including BDDs, FBDDs, KFDDs, MTBDDs, and ZDDs (see, for example, {cite:p}`bryantSymbolicBooleanManipulation1992,wegenerBranchingProgramsBinary2000,gergovEfficientBooleanManipulation1994,drechslerEfficientRepresentationManipulation1994,baharAlgebraicDecisionDiagrams1993,minatoZerosuppressedBDDsSet1993`), which made them a crucial tool in the development of modern circuits and systems. -Because of their previous success, decision diagrams have been proposed for application in the realm of quantum computing {cite:p}`willeDecisionDiagramsQuantum2023,willeToolsQuantumComputing2022,millerQMDDDecisionDiagram2006,niemannQMDDsEfficientQuantum2016,zulehnerHowEfficientlyHandle2019,hongTensorNetworkBased2020,vinkhuijzenLIMDDDecisionDiagram2021`. -Particularly for design tasks like _simulation_ {cite:p}`viamontesImprovingGatelevelSimulation2003,zulehnerAdvancedSimulationQuantum2019,hillmichJustRealThing2020,burgholzerHybridSchrodingerFeynmanSimulation2021,vinkhuijzenLIMDDDecisionDiagram2021,hillmichApproximatingDecisionDiagrams2022,burgholzerSimulationPathsQuantum2022,grurlNoiseawareQuantumCircuit2023,matoMixeddimensionalQuantumCircuit2023,sanderHamiltonianSimulationDecision2023`, _synthesis_ {cite:p}`niemannEfficientSynthesisQuantum2014,abdollahiAnalysisSynthesisQuantum2006,soekenSynthesisReversibleCircuits2012,zulehnerOnepassDesignReversible2018,adarshSyReCSynthesizerMQT2022,matoMixeddimensionalQuditState2024`, and _verification_ {cite:p}`burgholzerAdvancedEquivalenceChecking2021,burgholzerRandomStimuliGeneration2021,burgholzerVerifyingResultsIBM2020,wangXQDDbasedVerificationMethod2008,smithQuantumLogicSynthesis2019,hongEquivalenceCheckingDynamic2021` of quantum circuits, they recently attracted great attention. - -The following sections provide a comprehensive guide for quantum computing with decision diagrams, including the representation of quantum states and operations and the fundamental operations on decision diagrams. +Decision diagrams were introduced in the 1980s as a data structure +for the efficient representation and manipulation of Boolean functions {cite: +p}`bryantGraphbasedAlgorithmsBoolean1986`. +This led to the emergence of a wide variety of decision diagrams, +including BDDs, FBDDs, KFDDs, MTBDDs, and ZDDs +(see, for example, {cite: +p}`bryantSymbolicBooleanManipulation1992,wegenerBranchingProgramsBinary2000,gergovEfficientBooleanManipulation1994,drechslerEfficientRepresentationManipulation1994,baharAlgebraicDecisionDiagrams1993,minatoZerosuppressedBDDsSet1993`), +which made them a crucial tool in the development of modern circuits and +systems. +Because of their previous success, +decision diagrams have been proposed +for application in the realm of quantum computing {cite: +p}`willeDecisionDiagramsQuantum2023,willeToolsQuantumComputing2022,millerQMDDDecisionDiagram2006,niemannQMDDsEfficientQuantum2016,zulehnerHowEfficientlyHandle2019,hongTensorNetworkBased2020,vinkhuijzenLIMDDDecisionDiagram2021`. +Particularly for design tasks like _simulation_ {cite: +p}`viamontesImprovingGatelevelSimulation2003,zulehnerAdvancedSimulationQuantum2019,hillmichJustRealThing2020,burgholzerHybridSchrodingerFeynmanSimulation2021,vinkhuijzenLIMDDDecisionDiagram2021,hillmichApproximatingDecisionDiagrams2022,burgholzerSimulationPathsQuantum2022,grurlNoiseawareQuantumCircuit2023,matoMixeddimensionalQuantumCircuit2023,sanderHamiltonianSimulationDecision2023`, +_synthesis_ +{cite:p}`niemannEfficientSynthesisQuantum2014,abdollahiAnalysisSynthesisQuantum2006,soekenSynthesisReversibleCircuits2012,zulehnerOnepassDesignReversible2018,adarshSyReCSynthesizerMQT2022,matoMixeddimensionalQuditState2024`, +and _verification_ +{cite:p}`burgholzerAdvancedEquivalenceChecking2021,burgholzerRandomStimuliGeneration2021,burgholzerVerifyingResultsIBM2020,wangXQDDbasedVerificationMethod2008,smithQuantumLogicSynthesis2019,hongEquivalenceCheckingDynamic2021` +of quantum circuits, they recently attracted great attention. + +The following sections provide a comprehensive guide +for quantum computing with decision diagrams, +including the representation of quantum states and operations +and the fundamental operations on decision diagrams. ### Representation of Quantum States First, we review how quantum states are represented using decision diagrams. To this end, we consider the simple case of a single-qubit system. -The state $\ket{\Psi}$ of such a system is described by two complex-valued, normalized amplitudes $\alpha_0$ and $\alpha_1$, that is, +The state $\ket{\Psi}$ of such a system is described by two complex-valued, +normalized amplitudes $\alpha_0$ and $\alpha_1$, that is, ```{math} :label: ssstate @@ -216,7 +260,9 @@ which is commonly represented as a statevector \ket{\Psi}\equiv \begin{bmatrix} \alpha_0 & \alpha_1 \end{bmatrix}^\top. ``` -A rather simple observation and consequence of [](ssstate) is that this vector can be equally split into a contribution of the $\ket{0}$ state ($\alpha_0$) and a contribution of the $\ket{1}$ state ($\alpha_1$), that is, +A rather simple observation and consequence of {eq}`ssstate` is +that this vector can be equally split into a contribution of the $\ket{0}$ state +($\alpha_0$) and a contribution of the $\ket{1}$ state ($\alpha_1$), that is, ```{math} :label: splitting @@ -239,13 +285,15 @@ The decision diagram representing $\ket{\Psi}$ has the structure :align: center ``` -It consists of a single _node_ with one _incoming edge_ that represents the entry point in the decision diagram, as well as two _successors_ that represent the split shown in [](#splitting) and end in a _terminal_ node (the black box). +It consists of a single _node_ with one _incoming edge_ +that represents the entry point in the decision diagram, +as well as two _successors_ that represent the split shown in {eq}`splitting` +and end in a _terminal_ node (the black box). The state's amplitudes are annotated at the respective edges. Edges without annotations correspond to an edge weight of 1. ````{admonition} Example _(Single-Qubit States)_ -:class: tip -Consider the computational basis states $\ket{0}$ and $\ket{1}$. +:class: tip Consider the computational basis states $\ket{0}$ and $\ket{1}$. Then, the corresponding decision diagrams have the structures ```{image} _static/dd-figure-02.svg @@ -269,7 +317,8 @@ and In each of the cases, one of the successors ends in the terminal node, while the other ends in a \emph{zero stub} (indicated by a black dot)---uncannily resembling the corresponding vector descriptions. ```` -Building off the intuition of a single-qubit state, we can move to larger systems. +Building off the intuition of a single-qubit state, +we can move to larger systems. ````{admonition} Example _(Multi-Qubit States)_ :class: tip @@ -278,7 +327,7 @@ Consider the following statevector of a three-qubit system: ```{math} \ket{\Psi} = \begin{bmatrix} \frac{1}{2\sqrt{2}} & \frac{1}{2\sqrt{2}} & \frac{1}{2} & 0 & \frac{1}{2\sqrt{2}} & \frac{1}{2\sqrt{2}} & \frac{1}{2} & 0\end{bmatrix}^T ``` -Then, $\ket{\Psi}$ can be recursively split into equally-sized parts similar to [](#splitting), i.e., +Then, $\ket{\Psi}$ can be recursively split into equally-sized parts similar to {eq}`splitting`, i.e., ```{math} \overbrace{ \overbrace{\begin{matrix} @@ -335,12 +384,18 @@ Each level of the decision diagram consists of decision nodes with corresponding These successors represent the path that leads to an amplitude where the local quantum system (corresponding to the _level_ of the node, annotated here with the labels) is in the $\ket{0}$ (left successor) or the $\ket{1}$ state (right successor). ```` -At this point, this has been just a one-to-one translation between the statevector and a fancy graphical representation. -The unique core feature of decision diagrams is that their graph structure allows redundant parts to be merged in the representation instead of being represented repeatedly. +At this point, this has been just a one-to-one translation between the +statevector and a fancy graphical representation. +The unique core feature of decision diagrams is +that their graph structure allows redundant parts to be merged in the +representation instead of being represented repeatedly. ````{admonition} Example _(Redundancy in Decision Diagrams)_ -:class: tip -Observe how, as in the previous example, the left and right successors of the top-level node (labeled $q_2$) lead to exactly the same structure (highlighted by dashed rectangles in [](#3qbdd)). +:class: tip Observe how, as in the previous example, +the left and right successors of the top-level node +(labeled $q_2$) +lead to exactly the same structure +(highlighted by dashed rectangles in {eq}`3qbdd`). As a result, the whole sub-diagram does not need to be represented twice, i.e., ```{image} _static/dd-figure-05.svg @@ -351,18 +406,30 @@ As a result, the whole sub-diagram does not need to be represented twice, i.e., From a memory perspective, this reduction alone has compressed the overall memory required to represent the state by 50\%. ```` -Identifying redundancies in these kinds of representations heavily depends on the use of what is referred to as a _normalization scheme_ for the decision diagram nodes {cite:p}`niemannQMDDsEfficientQuantum2016`. -Such a normalization scheme makes sure two decision diagram nodes that represent the same functionality do indeed have the same numerical structure. +Identifying redundancies in these kinds of representations heavily depends on +the use of what is referred to as a _normalization scheme_ for the decision +diagram nodes {cite:p}`niemannQMDDsEfficientQuantum2016`. +Such a normalization scheme makes sure two decision diagram nodes +that represent the same functionality do indeed have the same numerical +structure. In computer science, this property is called _canonicity_. -The most widely used and practically relevant normalization scheme is to normalize the outgoing edges of a node by dividing both weights by the norm of the vector containing both edge weights and adjusting the incoming edges accordingly {cite:p}`hillmichJustRealThing2020`. -This normalizes the sum of the squared magnitudes of the outgoing edge weights to $1$ and is consistent with quantum semantics, where basis states $\ket{0}$ and $\ket{1}$ are observed after measurement with probabilities that are squared magnitudes of the respective weights. -Normalization is recursively applied in a bottom-up fashion to ensure that every possible redundancy is caught. +The most widely used and practically relevant normalization scheme is to +normalize the outgoing edges of a node by dividing both weights by the norm of +the vector containing both edge weights and adjusting the incoming edges +accordingly {cite:p}`hillmichJustRealThing2020`. +This normalizes the sum of the squared magnitudes of the outgoing edge weights +to $1$ and is consistent with quantum semantics, where basis states $\ket{0}$ +and $\ket{1}$ are observed after measurement with probabilities that are squared +magnitudes of the respective weights. +Normalization is recursively applied in a bottom-up fashion to ensure +that every possible redundancy is caught. ````{admonition} Example _(Normalization of Decision Diagrams)_ :class: tip -Considering the decision diagram from the previous example, this results in the following _normalized_ and _reduced_ decision diagram: +Considering the decision diagram from the previous example, +this results in the following _normalized_ and _reduced_ decision diagram: ```{image} _static/dd-figure-06.svg :align: center @@ -375,23 +442,53 @@ If $q_1$ is in the $\ket{0}$ state (following the left successor), then $q_0$ ha If $q_1$ is in the $\ket{1}$ state (following the right successor), it is guaranteed that the remaining qubit is in the $\ket{0}$ state. ```` -Overall, statevectors are represented as decision diagrams conceptually equivalent to halving the vector in a recursive fashion until it is fully decomposed. -The key idea is to exploit the redundancies in the resulting diagrams to create a more compact representation. +Overall, statevectors are represented +as decision diagrams conceptually equivalent to halving the vector in a +recursive fashion until it is fully decomposed. +The key idea is to exploit the redundancies in the resulting diagrams to create +a more compact representation. Some interesting properties that are worth pointing out: -- Decision diagrams can be initialized in their compact form (as, for example, shown in the last example above). There is no need to create the maximally large decision diagram (as shown, for example, in [](#3qbdd)) at any point in a calculation. -- Determining a particular amplitude of the represented state corresponds to multiplying the edge weights along a single-path traversal from the top edge of the decision diagram (called its _root_) to a terminal node. -- The efficiency of decision diagrams is commonly measured by their _size_, that is, the number of nodes in the decision diagram---the smaller the number of nodes, the higher the compaction achieved by the data structure. Note that the terminal (node) is typically not counted towards the size of a decision diagram. -- Any product state naturally has a decision diagram consisting of a single node per site. However, a compact DD does not correlate with the state being trivial. Even entangled states such as the _GHZ state_ or the _W state_ have decision diagrams whose size (that is, the number of nodes) is linear in the number of qubits. -- DDs are not a "silver bullet." The worst-case size of decision diagrams, corresponding to states without redundancy, is still exponential in the number of qubits. More specifically, a maximally large decision diagram has $1+2^1+2^2+\dots+2^{n-1} = 2^n-1$ nodes. -- To reduce visual clutter in illustrations of decision diagrams, edge weights are commonly not explicitly annotated, but their magnitude and phase are reflected in the thickness and the color of the respective edge. - In addition, to make the correspondence of the individual levels in a decision diagram to a system's qubits more explicit, the nodes are frequently annotated with the qubit's index as an identifier. - See {cite:p}`willeVisualizingDecisionDiagrams2021` for further details on common techniques for visualization of decision diagrams. +- Decision diagrams can be initialized in their compact form + (as, for example, shown in the last example above). + There is no need to create the maximally large decision diagram + (as shown, for example, in {eq}`3qbdd`) at any point in a calculation. +- Determining a particular amplitude of the represented state corresponds to + multiplying the edge weights along a single-path traversal from the top edge + of the decision diagram (called its _root_) to a terminal node. +- The efficiency of decision diagrams is commonly measured by their _size_, + that is, the number of nodes in the decision diagram---the smaller the number + of nodes, the higher the compaction achieved by the data structure. + Note that the terminal (node) is typically not counted towards the size of a + decision diagram. +- Any product state naturally has a decision diagram consisting of a single node + per site. + However, a compact DD does not correlate with the state being trivial. + Even entangled states such as the _GHZ state_ + or the _W state_ have decision diagrams whose size + (that is, the number of nodes) is linear in the number of qubits. +- DDs are not a "silver bullet." + The worst-case size of decision diagrams, + corresponding to states without redundancy, + is still exponential in the number of qubits. + More specifically, a maximally large decision diagram has + $1+2^1+2^2+\dots+2^{n-1} = 2^n-1$ nodes. +- To reduce visual clutter in illustrations of decision diagrams, + edge weights are commonly not explicitly annotated, + but their magnitude and phase are reflected in the thickness + and the color of the respective edge. + In addition, to make the correspondence of the individual levels in a decision + diagram to a system's qubits more explicit, the nodes are frequently annotated + with the qubit's index as an identifier. + See {cite:p}`willeVisualizingDecisionDiagrams2021` + for further details on common techniques + for visualization of decision diagrams. ### Representation of Quantum Operations Quantum operations are fundamentally described by complex-valued matrices. -Matrix decision diagrams are a natural extension to vector decision diagrams by an additional dimension. +Matrix decision diagrams are a natural extension to vector decision diagrams by +an additional dimension. To this end, consider the base case of a $2\times 2$ matrix $U$, that is, ```{math} @@ -408,11 +505,12 @@ Then, the decision diagram representing this matrix has the structure ``` which again resembles the general structure of the matrix. -Note that $U_{ij}$ can be interpreted as the transformation of $\ket{j}$ to $\ket{i}$. +Note that $U_{ij}$ can be interpreted +as the transformation of $\ket{j}$ to $\ket{i}$. ````{admonition} Example _(Single-Qubit Operations)_ -:class: tip -The following shows decision diagram representations for selected \mbox{single-qubit} operations: +:class: tip The following shows decision diagram representations +for selected \mbox{single-qubit} operations: ```{image} _static/dd-figure-08.svg :align: center @@ -423,14 +521,23 @@ The last equivalence demonstrates how a common factor between the edge weights c ```` The generalization to larger matrices works analogously to the vector case. -To construct the decision diagram representing a matrix, the matrix is recursively divided into quarters, and the four elements correspond to the four successors of the node to represent that split. -As for vector decision diagrams, a normalization scheme is applied to ensure that the resulting data structure is canonical and redundancy can be exploited. -The conventional approach is to normalize all edge weights by the weight with the highest magnitude, selecting the leftmost one if multiple weights have the same magnitude. -It is important to note that this ensures that all complex numbers within the decision diagram have a magnitude of at most $1$, which is used for optimization purposes. +To construct the decision diagram representing a matrix, +the matrix is recursively divided into quarters, +and the four elements correspond to the four successors of the node to represent +that split. +As for vector decision diagrams, +a normalization scheme is applied to ensure +that the resulting data structure is canonical and redundancy can be exploited. +The conventional approach is to normalize all edge weights by the weight with +the highest magnitude, selecting the leftmost one if multiple weights have the +same magnitude. +It is important to note that this ensures +that all complex numbers within the decision diagram have a magnitude of at most +$1$, which is used for optimization purposes. ````{admonition} Example _(Matrix Decision Diagrams)_ -:class: tip -Consider the maximally-entangling two-qubit $R_{xx}$ rotation represented by the matrix +:class: tip Consider the maximally-entangling two-qubit $R_{xx}$ rotation +represented by the matrix ```{math} R_{xx} \Bigl(\theta = \frac{\pi}{2} \Bigl) = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 0 & 0 & -i \\ @@ -461,25 +568,45 @@ Similarly to the vector example above, exploiting redundancy has halved the over Again, some interesting properties to point out: -- Just as in the vector case, it is always possible to work with the reduced form of matrix decision diagrams right away, that is, without ever constructing the exponentially-sized, maximally-large diagram. -- A maximally-large matrix decision diagram for $n$ qubits has $\sum_{i=1}^n 4^{i-1} = \frac{(4^n -1)}{3}$ nodes. -- Decision diagrams are not limited to local interactions. Even long-range interactions between arbitrary qubits typically produce compact representations as decision diagrams. For example, any two-qubit interaction between arbitrary qubits can be represented as a decision diagram with at most $1+4(n-1)$ nodes---an exponential reduction. -- Decision diagrams are not limited to two-qubit interactions either. For example, controlled quantum gates with arbitrarily many controls (such as the multi-controlled Toffoli gate) give rise to decision diagrams with a linear number of nodes. +- Just as in the vector case, + it is always possible to work with the reduced form of matrix decision + diagrams right away, that is, without ever constructing the + exponentially-sized, maximally-large diagram. +- A maximally-large matrix decision diagram + for $n$ qubits has $\sum_{i=1}^n 4^{i-1} = \frac{(4^n -1)}{3}$ nodes. +- Decision diagrams are not limited to local interactions. + Even long-range interactions between arbitrary qubits typically produce + compact representations as decision diagrams. + For example, any two-qubit interaction between arbitrary qubits can be + represented as a decision diagram with at most $1+4(n-1)$ nodes---an + exponential reduction. +- Decision diagrams are not limited to two-qubit interactions either. + For example, controlled quantum gates with arbitrarily many controls + (such as the multi-controlled Toffoli gate) + give rise to decision diagrams with a linear number of nodes. ### Fundamental Operations on Decision Diagrams -Merely defining means for compactly representing any kind of state or operation does not yet allow one to perform efficient computations. -It is crucial to also define efficient means of working with or manipulating the resulting representations. -In the following, it is demonstrated how the most fundamental operations can be carried out within the decision-diagram formalism and how they scale. -The focus is mainly on how operations are realized on vectors, since the concepts extend from vectors to matrices in a straightforward fashion. - -The main concept throughout all of these schemes is to recursively break the respective operations down into subcomputations. -This decomposition then naturally matches the recursive decomposition of decision diagrams. -As such, operations generally scale with the number of nodes in the involved decision diagrams. +Merely defining means for compactly representing any kind of state +or operation does not yet allow one to perform efficient computations. +It is crucial to also define efficient means of working with +or manipulating the resulting representations. +In the following, it is demonstrated how the most fundamental operations can be +carried out within the decision-diagram formalism and how they scale. +The focus is mainly on how operations are realized on vectors, +since the concepts extend from vectors to matrices in a straightforward fashion. + +The main concept throughout all of these schemes is to recursively break the +respective operations down into subcomputations. +This decomposition then naturally matches the recursive decomposition of +decision diagrams. +As such, operations generally scale with the number of nodes in the involved +decision diagrams. #### Kronecker Product -The Kronecker product is necessary to create product states and to chain together local operations. +The Kronecker product is necessary to create product states +and to chain together local operations. For vectors, it can be expressed as @@ -495,7 +622,10 @@ For vectors, it can be expressed as \end{bmatrix}. ``` -In the decision-diagram formalism, this is one of the simplest operations to perform and is done by simply replacing the terminal nodes of the first decision diagram with the root node of the second decision diagram. +In the decision-diagram formalism, +this is one of the simplest operations to perform +and is done by simply replacing the terminal nodes of the first decision diagram +with the root node of the second decision diagram. In case of the above example, this has the following form: ```{image} _static/dd-figure-10.svg @@ -503,7 +633,8 @@ In case of the above example, this has the following form: :width: 60% ``` -As such, its complexity is linear in the number of nodes of the first decision diagram. +As such, its complexity is linear in the number of nodes of the first decision +diagram. #### Addition @@ -515,9 +646,14 @@ Standard vector addition can be recursively broken down according to \ket{\Psi} + \ket{\Phi} = \begin{bmatrix} \Psi_0 \\ \Psi_1 \end{bmatrix} + \begin{bmatrix} \Phi_0 \\ \Phi_1 \end{bmatrix} = w \begin{bmatrix} \alpha_0 \\ \alpha_1 \end{bmatrix} + w' \begin{bmatrix} \alpha'_0 \\ \alpha'_1 \end{bmatrix} = \begin{bmatrix} w \alpha_0 + w' \alpha'_0 \\ w \alpha_1 + w' \alpha'_1 \end{bmatrix}, ``` -where $w$ and $w'$ are common factors of the terms in $\ket{\Psi}$ and $\ket{\Phi}$, respectively. +where $w$ and $w'$ are common factors of the terms in $\ket{\Psi}$ +and $\ket{\Phi}$, respectively. -In the decision-diagram formalism, this corresponds to a simultaneous traversal of both decision diagrams from their roots to the terminal (multiplying edge weights along the way until the individual amplitudes are reached) and back again (accumulating the results of the recursive computations). +In the decision-diagram formalism, +this corresponds to a simultaneous traversal of both decision diagrams from +their roots to the terminal (multiplying edge weights along the way until the +individual amplitudes are reached) and back again (accumulating the results of +the recursive computations). More precisely, ```{image} _static/dd-figure-11.svg @@ -526,11 +662,13 @@ More precisely, ``` where the dashed nodes represent the respective successor decision diagrams. -Overall, this results in a complexity that is linear in the size of the larger decision diagram. +Overall, this results in a complexity +that is linear in the size of the larger decision diagram. #### Matrix-Vector Multiplication -Matrix-vector multiplication can be handled in a very similar fashion as addition. +Matrix-vector multiplication can be handled in a very similar fashion +as addition. Standard matrix-vector multiplication can be expressed as @@ -543,7 +681,8 @@ u_{10} & u_{11} \end{bmatrix} w' \begin{bmatrix} \alpha_0 \\ \alpha_1 \end{bmatr u_{01} \cdot \alpha_0 + u_{11} \cdot \alpha_1 \end{bmatrix} . ``` -This implies that a multiplication boils down to four smaller multiplications and two additions. +This implies that a multiplication boils down to four smaller multiplications +and two additions. In the decision-diagram formalism, this has the form ```{image} _static/dd-figure-12.svg @@ -551,12 +690,15 @@ In the decision-diagram formalism, this has the form :width: 90% ``` -where the dashed nodes again represent the respective successor decision diagrams. -Overall, this results in a complexity that scales with the product of the size of both decision diagrams. +where the dashed nodes again represent the respective successor decision +diagrams. +Overall, this results in a complexity +that scales with the product of the size of both decision diagrams. #### Inner Product -Computing the inner product of two vectors can be recursively broken down according to +Computing the inner product of two vectors can be recursively broken down +according to ```{math} @@ -565,8 +707,10 @@ Computing the inner product of two vectors can be recursively broken down accord = w^* \begin{bmatrix} \alpha^*_0 & \alpha^*_1 \end{bmatrix} w' \begin{bmatrix} \alpha'_0 \\ \alpha'_1 \end{bmatrix} = w^*w' (\alpha^*_0 \alpha'_0 + \alpha^*_1 \alpha'_0) ``` -This implies that the inner product boils down to two smaller inner product computations and adding the results. -As with the matrix-vector multiplication, this is done recursively for each level of the decision diagram. +This implies that the inner product boils down to two smaller inner product +computations and adding the results. +As with the matrix-vector multiplication, +this is done recursively for each level of the decision diagram. In the decision-diagram formalism, this has the following form ```{image} _static/dd-figure-13.svg @@ -574,4 +718,5 @@ In the decision-diagram formalism, this has the following form :width: 70% ``` -Overall, this results in a complexity that, just as in addition, scales linearly with the size of the larger decision diagram. +Overall, this results in a complexity that, just as in addition, +scales linearly with the size of the larger decision diagram. diff --git a/docs/dd_package_evaluation.md b/docs/dd_package_evaluation.md index 4af6374556..ef1d1ece32 100644 --- a/docs/dd_package_evaluation.md +++ b/docs/dd_package_evaluation.md @@ -8,18 +8,30 @@ mystnb: # Benchmarking the DD Package -MQT Core provides a benchmark suite to evaluate the performance of the DD package. -This can be especially helpful if you are working on the DD package and want to know how your changes affect its performance. +MQT Core provides a benchmark suite to evaluate the performance of the DD +package. +This can be especially helpful if you are working on the DD package +and want to know how your changes affect its performance. +++ ## Generating results -In order to generate benchmark data, MQT Core provides the `mqt-core-dd-eval` CMake target (which is made available by passing `-DBUILD_MQT_CORE_BENCHMARKS=ON` to CMake). This target will run the benchmark suite and generate a JSON file containing the results. To this end, the target takes a single argument which is used as a component in the resulting JSON filename. +In order to generate benchmark data, +MQT Core provides the `mqt-core-dd-eval` CMake target +(which is made available by passing `-DBUILD_MQT_CORE_BENCHMARKS=ON` to CMake). +This target will run the benchmark suite +and generate a JSON file containing the results. +To this end, the target takes a single argument which is used +as a component in the resulting JSON filename. +++ -After running the target, you will see a `results_.json` file in your build directory that contains all the data collected during the benchmarking process. An exemplary `results_.json` file might look like this (taken from the `eval` directory): +After running the target, +you will see a `results_.json` file in your build directory +that contains all the data collected during the benchmarking process. +An exemplary `results_.json` file might look like this +(taken from the `eval` directory): ```{code-cell} ipython3 import json @@ -33,13 +45,18 @@ with filepath.open(mode="r", encoding="utf-8") as f: print(json_formatted_str) ``` -To compare the performance of your newly proposed changes to the existing implementation, the benchmark script should be executed once based on the branch/commit you want to compare against and once in your new feature branch. Make sure to pass different arguments as different file names while running the target (e.g. `baseline` and `feature`). +To compare the performance of your newly proposed changes to the existing +implementation, the benchmark script should be executed once based on the +branch/commit you want to compare against and once in your new feature branch. +Make sure to pass different arguments as different file names +while running the target (e.g. `baseline` and `feature`). +++ ## Running the comparison -The MQT Core source code contains a script that can be used to compare the results of two runs of the benchmark suite. +The MQT Core source code contains a script +that can be used to compare the results of two runs of the benchmark suite. The script is located in `eval/dd_evaluation.py`. It uses PEP 723 inline script metadata to specify the script's dependencies. @@ -57,4 +74,5 @@ The comparison can be run from the command line via: ! ../eval/dd_evaluation.py ../eval/results_baseline.json ../eval/results_feature.json --dd --algorithm=bv --num_qubits=1024 ``` -This internally runs `uv run --script --quiet` on the respective benchmark script (including automatically installing any missing dependencies). +This internally runs `uv run --script --quiet` on the respective benchmark +script (including automatically installing any missing dependencies). diff --git a/docs/index.md b/docs/index.md index 2c22a87f73..a6a79a4617 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,11 +4,27 @@ \begin{abstract} ``` -MQT Core is an open-source C++20 and Python library for quantum computing that forms the backbone of the quantum software tools developed as part of the _{doc}`Munich Quantum Toolkit (MQT) `_. -To this end, MQT Core consists of multiple components that are used throughout the MQT, including a fully fledged intermediate representation (IR) for quantum computations, a state-of-the-art decision diagram (DD) package for quantum computing, and a state-of-the-art ZX-diagram package for working with the ZX-calculus. - -This documentation provides a comprehensive guide to the MQT Core library, including {doc}`installation instructions `, a {doc}`quickstart guide for the MQT Core IR `, its {doc}`decision diagram (DD) package `, and its {doc}`ZX-calculus package `, as well as detailed {doc}`API documentation `. -The source code of MQT Core is publicly available on GitHub at [munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core), while pre-built binaries are available via [PyPI](https://pypi.org/project/mqt.core/) for all major operating systems and all modern Python versions. +MQT Core is an open-source C++20 and Python library for quantum computing +that forms the backbone of the quantum software tools developed +as part of the _{doc}`Munich Quantum Toolkit (MQT) `_. +To this end, MQT Core consists of multiple components +that are used throughout the MQT, +including a fully fledged intermediate representation (IR) +for quantum computations, +a state-of-the-art decision diagram (DD) package for quantum computing, +and a state-of-the-art ZX-diagram package for working with the ZX-calculus. + +This documentation provides a comprehensive guide to the MQT Core library, +including {doc}`installation instructions `, +a {doc}`quickstart guide for the MQT Core IR `, +its {doc}`decision diagram (DD) package `, +and its {doc}`ZX-calculus package `, +as well as detailed {doc}`API documentation `. +The source code of MQT Core is publicly available on GitHub at +[munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core), +while pre-built binaries are available via +[PyPI](https://pypi.org/project/mqt.core/) for all major operating systems and +all modern Python versions. MQT Core is fully compatible with Qiskit 1.0 and above. ````{only} latex diff --git a/docs/installation.md b/docs/installation.md index 2c658e5d4d..581bd059ba 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -4,9 +4,8 @@ # Installation MQT Core is primarily developed as a C++20 library with Python bindings. -The Python package is available on -[PyPI](https://pypi.org/project/mqt.core/) and can be installed on all -major operating systems with all +The Python package is available on [PyPI](https://pypi.org/project/mqt.core/) +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.core ::: :::: + In most cases, no compilation is required; a platform-specific prebuilt wheel is downloaded and installed. @@ -388,8 +388,7 @@ For detailed guidelines and workflows, see {doc}`contributing`. prek install ``` -6. If you plan to contribute to MQT Core, - you will also need to install MLIR. +6. If you plan to contribute to MQT Core, you will also need to install MLIR. The section below describes how to do this. (setting-up-mlir)= @@ -518,8 +517,8 @@ $env:MLIR_DIR = "C:\path\to\installation\lib\cmake\mlir" ### Disabling MLIR If you do not need MLIR-based functionality, -you can disable it by setting the {code}`BUILD_MQT_CORE_MLIR` option -to {code}`OFF`. +you can disable it by setting the {code}`BUILD_MQT_CORE_MLIR` option to +{code}`OFF`. This disables all MLIR-related features in MQT Core and removes the dependency on MLIR. diff --git a/docs/mlir/index.md b/docs/mlir/index.md index fddf27e39b..1c4ddd12b3 100644 --- a/docs/mlir/index.md +++ b/docs/mlir/index.md @@ -1,6 +1,8 @@ # The MQT Compiler Collection -The MQT Compiler Collection (`mqt-cc`) is a blueprint for a future-proof quantum-classical compilation framework built on the Multi-Level Intermediate Representation (MLIR). +The MQT Compiler Collection (`mqt-cc`) is a blueprint +for a future-proof quantum-classical compilation framework built on the +Multi-Level Intermediate Representation (MLIR). For an overview, see {cite:p}`MQTCompilerCollection2026`. This page gives a technical introduction. @@ -8,12 +10,20 @@ It links to the API documentation for the MLIR infrastructure. We define multiple dialects, each with its dedicated purpose: -- The {doc}`QC dialect ` uses reference semantics and is designed as a compatibility dialect that simplifies translations from and to existing languages such as Qiskit, OpenQASM, or QIR. -- The {doc}`QCO dialect ` uses value semantics and is mainly designed for running optimizations. -- The {doc}`QTensor dialect ` adds support for one-dimensional tensors of qubits with linear typing and is used in the QCO dialect to represent collections of qubits such as registers. - -These dialects define various canonicalization and transformation passes that enable the compilation of quantum programs to native quantum hardware. -For interoperability, we provide {doc}`conversions ` between dialects. +- The {doc}`QC dialect ` uses reference semantics and is designed + as a compatibility dialect that simplifies translations from + and to existing languages such as Qiskit, OpenQASM, or QIR. +- The {doc}`QCO dialect ` uses value semantics and is mainly designed + for running optimizations. +- The {doc}`QTensor dialect ` adds support + for one-dimensional tensors of qubits with linear typing + and is used in the QCO dialect to represent collections of qubits such + as registers. + +These dialects define various canonicalization and transformation passes +that enable the compilation of quantum programs to native quantum hardware. +For interoperability, we provide {doc}`conversions ` between +dialects. ```{toctree} :maxdepth: 2 diff --git a/docs/mqt_core_ir.md b/docs/mqt_core_ir.md index fda2d4362f..ae5dfed95f 100644 --- a/docs/mqt_core_ir.md +++ b/docs/mqt_core_ir.md @@ -13,23 +13,30 @@ mystnb: # MQT Core IR -The central interface for working with quantum computations throughout the Munich Quantum Toolkit is the {py:class}`~mqt.core.ir.QuantumComputation` class. -It effectively represents quantum computations as sequential lists of operation, similar to Qiskit's {py:class}`~qiskit.circuit.QuantumCircuit` class. +The central interface for working with quantum computations throughout the +Munich Quantum Toolkit is the {py:class}`~mqt.core.ir.QuantumComputation` class. +It effectively represents quantum computations as sequential lists of operation, +similar to Qiskit's {py:class}`~qiskit.circuit.QuantumCircuit` class. -The following will demonstrate how to work with the {py:class}`~mqt.core.ir.QuantumComputation` class in Python. +The following will demonstrate how to work with the {py: +class}`~mqt.core.ir.QuantumComputation` class in Python. :::{note} MQT Core is primarily designed in C++ with a thin Python wrapper. -Historically, the C++ part of MQT Core was the focus and the Python interface was added later. -As the standards we hold ourselves to have evolved, the Python interface is much better documented than the C++ interface. -Contributions to the C++ documentation are welcome. See the [contribution guidelines](contributing.md) for more information. +Historically, the C++ part of MQT Core was the focus +and the Python interface was added later. +As the standards we hold ourselves to have evolved, +the Python interface is much better documented than the C++ interface. +Contributions to the C++ documentation are welcome. +See the [contribution guidelines](contributing.md) for more information. ::: ## Quickstart -The following code snippet demonstrates how to construct a quantum computation for an -instance of the Iterative Quantum Phase Estimation algorithm that aims to estimate -the phase of a unitary operator $U=p(3\pi/8)$ using 3 bits of precision. +The following code snippet demonstrates how to construct a quantum computation +for an instance of the Iterative Quantum Phase Estimation algorithm +that aims to estimate the phase of a unitary operator $U=p(3\pi/8)$ using 3 bits +of precision. ```{code-cell} ipython3 --- @@ -79,8 +86,10 @@ for i in range(precision): qc.reset(q[0]) ``` -The circuit class provides lots of flexibility when it comes to the kind of gates that can be applied. -Check out the full API documentation of the {py:class}`~mqt.core.ir.QuantumComputation` class for more details. +The circuit class provides lots of flexibility +when it comes to the kind of gates that can be applied. +Check out the full API documentation of the {py: +class}`~mqt.core.ir.QuantumComputation` class for more details. ## Visualizing Circuits @@ -89,14 +98,19 @@ The output is to be read from top to bottom and left to right. Each line represents a single operation in the circuit. :::{note} -The first and last lines have a special meaning: the first line contains the initial layout information, while the last line contains the output permutation. This is explained in more detail in the [Layout Information](#layout-information) section. +The first and last lines have a special meaning: +the first line contains the initial layout information, +while the last line contains the output permutation. +This is explained in more detail in the +[Layout Information](#layout-information) section. ::: ```{code-cell} ipython3 print(qc) ``` -Circuits can also easily be exported to OpenQASM 3 using the {py:meth}`~mqt.core.ir.QuantumComputation.qasm3_str` method. +Circuits can also easily be exported to OpenQASM 3 using the {py: +meth}`~mqt.core.ir.QuantumComputation.qasm3_str` method. ```{code-cell} ipython3 --- @@ -108,27 +122,49 @@ print(qc.qasm3_str()) ## Layout Information -When compiling a quantum circuit for a specific quantum device, it is necessary to map the qubits of the circuit to the qubits of the device. -In addition, SWAP operations might be necessary to ensure that gates are only applied to qubits connected on the device. +When compiling a quantum circuit for a specific quantum device, +it is necessary to map the qubits of the circuit to the qubits of the device. +In addition, SWAP operations might be necessary to ensure +that gates are only applied to qubits connected on the device. These SWAP operations permute the assignment of circuit qubits to device qubits. -At the end of the computation, the values of the circuit qubits are measured at specific device qubits. -This kind of _layout information_ is important for reasoning about the functionality of the compiled circuit. -As such, preserving this information is essential for verification and debugging purposes. +At the end of the computation, +the values of the circuit qubits are measured at specific device qubits. +This kind of _layout information_ is important +for reasoning about the functionality of the compiled circuit. +As such, preserving this information is essential for verification +and debugging purposes. :::{note} -In the literature, the qubits used in the circuit are often referred to as _logical qubits_ or _virtual qubits_, while the qubits of the device are also called _physical qubits_. -Within the MQT, we try to avoid the terms _logical_ and _physical_ qubits, as they can be misleading due to the connection to error correction. +In the literature, the qubits used in the circuit are often referred to +as _logical qubits_ or _virtual qubits_, +while the qubits of the device are also called _physical qubits_. +Within the MQT, we try to avoid the terms _logical_ and _physical_ qubits, +as they can be misleading due to the connection to error correction. Instead, we use the terms _circuit qubits_ and _device qubits_. ::: -To this end, the {py:class}`~mqt.core.ir.QuantumComputation` class contains two members, {py:attr}`~mqt.core.ir.QuantumComputation.initial_layout` and {py:attr}`~mqt.core.ir.QuantumComputation.output_permutation`, which are instances of the {py:class}`~mqt.core.ir.Permutation` class. -The initial layout tracks the mapping of circuit qubits to device qubits at the beginning of the computation, while the output permutation tracks where a particular circuit qubit is measured at the end of the computation. -While the output permutation can generally be inferred from the measurements in the circuit (using {py:meth}`~mqt.core.ir.QuantumComputation.initialize_io_mapping`), the initial layout is not always clear. -OpenQASM, for example, lacks a way to express the initial layout of a circuit and preserve this information. -Therefore, MQT Core will output the layout information as comments in the first two lines of the QASM string using the following format: - -- `// i Q_0, Q_1, ..., Q_n`, meaning circuit qubit $i$ is mapped to device qubit $Q_i$. -- `// o Q_0, Q_1, ..., Q_n` meaning the value of circuit qubit $i$ (assumed to be stored in classical bit $c[i]$) is measured at device qubit $Q_i$. +To this end, the {py:class}`~mqt.core.ir.QuantumComputation` class contains two +members, {py:attr}`~mqt.core.ir.QuantumComputation.initial_layout` and +{py:attr}`~mqt.core.ir.QuantumComputation.output_permutation`, which are +instances of the {py:class}`~mqt.core.ir.Permutation` class. +The initial layout tracks the mapping of circuit qubits to device qubits at the +beginning of the computation, while the output permutation tracks where a +particular circuit qubit is measured at the end of the computation. +While the output permutation can generally be inferred from the measurements in +the circuit (using +{py:meth}`~mqt.core.ir.QuantumComputation.initialize_io_mapping`), the initial +layout is not always clear. +OpenQASM, for example, lacks a way to express the initial layout of a circuit +and preserve this information. +Therefore, MQT Core will output the layout information +as comments in the first two lines of the QASM string using the following +format: + +- `// i Q_0, Q_1, ..., Q_n`, + meaning circuit qubit $i$ is mapped to device qubit $Q_i$. +- `// o Q_0, Q_1, ..., Q_n` meaning the value of circuit qubit $i$ + (assumed to be stored in classical bit $c[i]$) + is measured at device qubit $Q_i$. An example illustrates the idea: @@ -158,26 +194,34 @@ print(qc.qasm3_str()) ``` In the example above, the initial layout is not explicitly specified. -A trivial layout is thus assumed, where the circuit qubits are mapped to the device qubits in order. -The output permutation is determined from the measurements and is printed as comments in the QASM string. +A trivial layout is thus assumed, +where the circuit qubits are mapped to the device qubits in order. +The output permutation is determined from the measurements and is printed +as comments in the QASM string. :::{note} This layout information is not part of the OpenQASM 3 standard. It is a feature of MQT Core to help with debugging and verification. -MQT Core's QASM export will always include this layout information in the first two lines of the QASM string. -MQT Core's QASM import will parse these lines and set the initial layout and output permutation accordingly. +MQT Core's QASM export will always include this layout information in the first +two lines of the QASM string. +MQT Core's QASM import will parse these lines and set the initial layout +and output permutation accordingly. ::: ## Operations -The operations in a {py:class}`~mqt.core.ir.QuantumComputation` object are of type {py:class}`~mqt.core.ir.operations.Operation`. +The operations in a {py: +class}`~mqt.core.ir.QuantumComputation` object are of type {py: +class}`~mqt.core.ir.operations.Operation`. Every type of operation in `mqt-core` is derived from this class. Operations can also be explicitly constructed. -Each {py:class}`~mqt.core.ir.operations.Operation` has a type in the form of an {py:class}`~mqt.core.ir.operations.OpType`. +Each {py:class}`~mqt.core.ir.operations.Operation` has a type in the form of an +{py:class}`~mqt.core.ir.operations.OpType`. ### `StandardOperation` -A {py:class}`~mqt.core.ir.operations.StandardOperation` is used to represent basic unitary gates. +A {py:class}`~mqt.core.ir.operations.StandardOperation` is used to represent +basic unitary gates. These can also be declared with arbitrarily many controls. ```{code-cell} ipython3 @@ -203,7 +247,8 @@ print(qc) ### `NonUnitaryOperation` -A {py:class}`~mqt.core.ir.operations.NonUnitaryOperation` is used to represent operations involving measurements or resets. +A {py:class}`~mqt.core.ir.operations.NonUnitaryOperation` is used to represent +operations involving measurements or resets. ```{code-cell} ipython3 from mqt.core.ir.operations import NonUnitaryOperation @@ -226,8 +271,14 @@ print(qc) ### `SymbolicOperation` -A {py:class}`~mqt.core.ir.operations.SymbolicOperation` can represent all gates of a {py:class}`~mqt.core.ir.operations.StandardOperation` but the gate parameters can be symbolic. -Symbolic expressions are represented in MQT using the {py:class}`~mqt.core.ir.symbolic.Expression` type, which represent linear combinations of symbolic {py:class}`~mqt.core.ir.symbolic.Term` objects over some set of {py:class}`~mqt.core.ir.symbolic.Variable` objects. +A {py:class}`~mqt.core.ir.operations.SymbolicOperation` can represent all gates +of a {py:class}`~mqt.core.ir.operations.StandardOperation` but the gate +parameters can be symbolic. +Symbolic expressions are represented in MQT using the {py: +class}`~mqt.core.ir.symbolic.Expression` type, +which represent linear combinations of symbolic {py: +class}`~mqt.core.ir.symbolic.Term` objects over some set of {py: +class}`~mqt.core.ir.symbolic.Variable` objects. ```{code-cell} ipython3 from mqt.core.ir.operations import SymbolicOperation @@ -250,7 +301,8 @@ u2_symb = SymbolicOperation(target=0, params=[sym, 2.0], op_type=OpType.u2) ### `CompoundOperation` -A {py:class}`~mqt.core.ir.operations.CompoundOperation` bundles multiple {py:class}`~mqt.core.ir.operations.Operation` objects together. +A {py:class}`~mqt.core.ir.operations.CompoundOperation` bundles multiple {py: +class}`~mqt.core.ir.operations.Operation` objects together. ```{code-cell} ipython3 from mqt.core.ir.operations import CompoundOperation @@ -267,7 +319,8 @@ qc.append(comp_op) print(qc) ``` -Circuits can be conveniently turned into operations which allows to create nested circuits: +Circuits can be conveniently turned into operations +which allows to create nested circuits: ```{code-cell} ipython3 nqubits = 2 @@ -283,9 +336,12 @@ print(qc) ### `IfElseOperation` -A {py:class}`~mqt.core.ir.operations.IfElseOperation` is an operation controlled by a classical bit or a classical register. -If a given condition is met, the {py:attr}`~mqt.core.ir.operations.IfElseOperation.then_operation` is applied. -If the condition is not met, the {py:attr}`~mqt.core.ir.operations.IfElseOperation.else_operation` is applied. +A {py:class}`~mqt.core.ir.operations.IfElseOperation` is an operation controlled +by a classical bit or a classical register. +If a given condition is met, the {py: +attr}`~mqt.core.ir.operations.IfElseOperation.then_operation` is applied. +If the condition is not met, the {py: +attr}`~mqt.core.ir.operations.IfElseOperation.else_operation` is applied. ```{code-cell} ipython3 qc = QuantumComputation(1, 1) @@ -301,7 +357,9 @@ qc.if_else( print(qc) ``` -If you do not need an `else_operation`, the {py:class}`~mqt.core.ir.QuantumComputation` class provides a shortcut for creating an {py:meth}`~mqt.core.ir.QuantumComputation.if_` operation. +If you do not need an `else_operation`, the {py: +class}`~mqt.core.ir.QuantumComputation` class provides a shortcut +for creating an {py:meth}`~mqt.core.ir.QuantumComputation.if_` operation. ```{code-cell} ipython3 qc = QuantumComputation(1, 1) @@ -318,8 +376,11 @@ print(qc) ### OpenQASM OpenQASM is a widely used format for representing quantum circuits. -Its latest version, [OpenQASM 3](https://openqasm.com/index.html), is a powerful language that can express a wide range of quantum circuits. -MQT Core supports the full functionality of OpenQASM 2.0 (including classically controlled operations) and a growing subset of OpenQASM 3. +Its latest version, [OpenQASM 3](https://openqasm.com/index.html), +is a powerful language that can express a wide range of quantum circuits. +MQT Core supports the full functionality of OpenQASM 2.0 +(including classically controlled operations) +and a growing subset of OpenQASM 3. ```{code-cell} ipython3 from mqt.core.ir import QuantumComputation @@ -340,7 +401,9 @@ print(qc) ### Qiskit -In addition to OpenQASM, `mqt-core` can natively import [Qiskit](https://qiskit.org/) {py:class}`~qiskit.circuit.QuantumCircuit` objects. +In addition to OpenQASM, +`mqt-core` can natively import [Qiskit](https://qiskit.org/) {py: +class}`~qiskit.circuit.QuantumCircuit` objects. ```{code-cell} ipython3 from qiskit import QuantumCircuit diff --git a/docs/qdmi/ddsim_device.md b/docs/qdmi/ddsim_device.md index 0ad5f9ebc5..9be543aa55 100644 --- a/docs/qdmi/ddsim_device.md +++ b/docs/qdmi/ddsim_device.md @@ -2,17 +2,32 @@ ## Objective -MQT Core provides a QDMI device that is powered by a classical quantum circuit simulator based on decision diagrams (see [the documentation of the DD Package](../dd_package.md)). -This functionality is exposed through the QDMI interface as a device, which can be used to classically simulate quantum programs. +MQT Core provides a QDMI device +that is powered by a classical quantum circuit simulator based on decision +diagrams (see [the documentation of the DD Package](../dd_package.md)). +This functionality is exposed through the QDMI interface as a device, +which can be used to classically simulate quantum programs. ## Capabilities -The simulator device supports all operations that our [MQT Core IR](../mqt_core_ir.md) supports and takes programs in either OpenQASM 2 or OpenQASM 3 format. -It can either be used for performing weak simulation, i.e., sampling from the distribution produced by the circuit, or for performing strong simulation, i.e., computing a representation of the full state vector. -To switch between these two modes, either set the `QDMI_DEVICE_JOB_PARAMETER_SHOTSNUM` parameter to the desired number of shots for weak simulation or to `0` for strong simulation. +The simulator device supports all operations +that our [MQT Core IR](../mqt_core_ir.md) supports +and takes programs in either OpenQASM 2 or OpenQASM 3 format. +It can either be used for performing weak simulation, i.e., +sampling from the distribution produced by the circuit, +or for performing strong simulation, i.e., +computing a representation of the full state vector. +To switch between these two modes, +either set the `QDMI_DEVICE_JOB_PARAMETER_SHOTSNUM` parameter to the desired +number of shots for weak simulation or to `0` for strong simulation. -Under the hood, the QDMI device uses the MQT Core OpenQASM parser (see {cpp:func}`qasm3::Importer::imports`) to parse the program into a {cpp:class}`qc::QuantumComputation` object. -That circuit is then passed either to the {cpp:func}`dd::sample` or {cpp:func}`dd::simulate` function, depending on the mode. +Under the hood, the QDMI device uses the MQT Core OpenQASM parser +(see {cpp:func}`qasm3::Importer::imports`) +to parse the program into a {cpp:class}`qc::QuantumComputation` object. +That circuit is then passed either to the {cpp:func}`dd::sample` or {cpp: +func}`dd::simulate` function, depending on the mode. Consult the respective documentation for more details and limitations. -The device implements the full QDMI job interface (except for the `QDMI_JOB_RESULT_SHOTS` result format not supported by the simulator). +The device implements the full QDMI job interface +(except for the `QDMI_JOB_RESULT_SHOTS` result format not supported by the +simulator). diff --git a/docs/qdmi/driver.md b/docs/qdmi/driver.md index 4767124b29..6b3e7a8dd8 100644 --- a/docs/qdmi/driver.md +++ b/docs/qdmi/driver.md @@ -10,21 +10,37 @@ mystnb: ## Objective -A QDMI Driver manages the communication between QDMI devices, such as [MQT Core's NA QDMI Device](na_device.md) or [MQT Core's DDSIM QDMI Device](ddsim_device.md), and QDMI clients, see the [QDMI specification](https://munich-quantum-software-stack.github.io/QDMI/). -It is responsible for loading the device, forwarding requests from the client to the device, and sending back the results. -MQT Core's QDMI Driver, {cpp:class}`qdmi::Driver`, comes with several preloaded devices that can be used directly. -Other devices can be loaded dynamically at runtime via {cpp:func}`qdmi::Driver::addDynamicDeviceLibrary`. +A QDMI Driver manages the communication between QDMI devices, +such as [MQT Core's NA QDMI Device](na_device.md) +or [MQT Core's DDSIM QDMI Device](ddsim_device.md), and QDMI clients, see the +[QDMI specification](https://munich-quantum-software-stack.github.io/QDMI/). +It is responsible for loading the device, +forwarding requests from the client to the device, and sending back the results. +MQT Core's QDMI Driver, {cpp:class}`qdmi::Driver`, +comes with several preloaded devices that can be used directly. +Other devices can be loaded dynamically at runtime via {cpp: +func}`qdmi::Driver::addDynamicDeviceLibrary`. ## Python Bindings -The QDMI Driver is implemented in C++ and exposed to Python via [{code}`nanobind`](https://nanobind.readthedocs.io/). -Direct binding of the QDMI Client interface functions is not feasible due to technical limitations. -Instead, a FoMaC (Figure of Merits and Constraints) library defines wrapper classes ({cpp:class}`~fomac::Session`, {cpp:class}`~fomac::Session::Device`, {cpp:class}`~fomac::Session::Device::Site`, {cpp:class}`~fomac::Session::Device::Operation`, {cpp:class}`~fomac::Session::Job`) for the QDMI entities. -These classes together with their methods are then exposed to Python, see {py:class}`~mqt.core.fomac.Session`, {py:class}`~mqt.core.fomac.Device`, {py:class}`~mqt.core.fomac.Device.Site`, {py:class}`~mqt.core.fomac.Device.Operation`, {py:class}`~mqt.core.fomac.Job`. +The QDMI Driver is implemented in C++ +and exposed to Python via [{code}`nanobind`](https://nanobind.readthedocs.io/). +Direct binding of the QDMI Client interface functions is not feasible due to +technical limitations. +Instead, a FoMaC (Figure of Merits and Constraints) library defines wrapper +classes ({cpp:class}`~fomac::Session`, {cpp:class}`~fomac::Session::Device`, +{cpp:class}`~fomac::Session::Device::Site`, +{cpp:class}`~fomac::Session::Device::Operation`, +{cpp:class}`~fomac::Session::Job`) for the QDMI entities. +These classes together with their methods are then exposed to Python, see {py: +class}`~mqt.core.fomac.Session`, {py:class}`~mqt.core.fomac.Device`, {py: +class}`~mqt.core.fomac.Device.Site`, {py: +class}`~mqt.core.fomac.Device.Operation`, {py:class}`~mqt.core.fomac.Job`. ## Usage -The following example shows how to create a session and get devices from the QDMI driver. +The following example shows how to create a session +and get devices from the QDMI driver. ```{code-cell} ipython3 from mqt.core.fomac import Session diff --git a/docs/qdmi/index.md b/docs/qdmi/index.md index 5768d1832b..beca0a73a3 100644 --- a/docs/qdmi/index.md +++ b/docs/qdmi/index.md @@ -1,7 +1,13 @@ # QDMI in the MQT -The [Quantum Device Management Interface (QDMI)](https://munich-quantum-software-stack.github.io/QDMI/) provides a standardized interface for describing and interacting with quantum devices. -This part of MQT Core contains the implementation of QDMI's different components, such as a [QDMI driver](driver.md), a [QDMI device for Neutral Atom Systems](na_device.md), and a [QDMI device for a Classical Quantum Circuit Simulator](ddsim_device). +The +[Quantum Device Management Interface (QDMI)](https://munich-quantum-software-stack.github.io/QDMI/) +provides a standardized interface for describing and interacting with quantum +devices. +This part of MQT Core contains the implementation of QDMI's different +components, such as a [QDMI driver](driver.md), a +[QDMI device for Neutral Atom Systems](na_device.md), and a +[QDMI device for a Classical Quantum Circuit Simulator](ddsim_device). ```{toctree} :maxdepth: 1 diff --git a/docs/qdmi/na_device.md b/docs/qdmi/na_device.md index 05778e860c..05db63da68 100644 --- a/docs/qdmi/na_device.md +++ b/docs/qdmi/na_device.md @@ -11,14 +11,23 @@ mystnb: ## Objective Compilation passes throughout MQT need information about the target device. -The Neutral Atom [QDMI](https://munich-quantum-software-stack.github.io/QDMI/) device provides a uniform way to provide the necessary information for neutral atom-based quantum devices. -It defines a representation to easily provide static information in the form of a JSON file. +The Neutral Atom [QDMI](https://munich-quantum-software-stack.github.io/QDMI/) +device provides a uniform way to provide the necessary information for neutral +atom-based quantum devices. +It defines a representation to easily provide static information in the form of +a JSON file. ## Describing a Device -The basis of a such device implementation in MQT is a specification in a JSON file. -The structure of this JSON file is defined by the {cpp:class}`na::Device` struct. -The struct defines functions to serialize and deserialize the data using the [nlohmann/json](https://json.nlohmann.me) library. -During compilation, this JSON file is parsed and the corresponding C++ code is produced by an application (see `src/na/device/App.cpp`) for the actual QDMI device implementation. +The basis of a such device implementation in MQT is a specification in a JSON +file. +The structure of this JSON file is defined by the {cpp: +class}`na::Device` struct. +The struct defines functions to serialize +and deserialize the data using the [nlohmann/json](https://json.nlohmann.me) +library. +During compilation, this JSON file is parsed +and the corresponding C++ code is produced by an application +(see `src/na/device/App.cpp`) for the actual QDMI device implementation. The C++ code is then compiled to a library that can be used by the QDMI driver. An example instance of a device JSON file can be found in `json/na/device.json`. diff --git a/docs/qdmi/qdmi_backend.md b/docs/qdmi/qdmi_backend.md index 3b89fac043..13fd66079a 100644 --- a/docs/qdmi/qdmi_backend.md +++ b/docs/qdmi/qdmi_backend.md @@ -8,8 +8,11 @@ mystnb: # Qiskit Backend Integration -The {py:mod}`mqt.core.plugins.qiskit` module provides a Qiskit {py:class}`~qiskit.providers.BackendV2`-compatible interface to QDMI devices via FoMaC. -This integration allows you to execute Qiskit circuits on QDMI-compliant quantum devices using a familiar Qiskit workflow. +The {py:mod}`mqt.core.plugins.qiskit` module provides a Qiskit {py: +class}`~qiskit.providers.BackendV2`-compatible interface to QDMI devices via +FoMaC. +This integration allows you to execute Qiskit circuits on QDMI-compliant quantum +devices using a familiar Qiskit workflow. ## Installation @@ -22,7 +25,7 @@ Install MQT Core with Qiskit support: :sync: uv ```console -$ uv pip install "mqt-core[qiskit]" +uv pip install "mqt-core[qiskit]" ``` ::: @@ -35,6 +38,7 @@ $ uv pip install "mqt-core[qiskit]" ``` ::: + :::: ## Quickstart @@ -65,8 +69,10 @@ print(f"Results: {counts}") ### Using the Provider -The {py:class}`~mqt.core.plugins.qiskit.QDMIProvider` discovers QDMI devices available through the FoMaC layer. -Backends should always be obtained through the provider rather than instantiated directly. +The {py:class}`~mqt.core.plugins.qiskit.QDMIProvider` discovers QDMI devices +available through the FoMaC layer. +Backends should always be obtained through the provider rather than instantiated +directly. ```{code-cell} ipython3 from mqt.core.plugins.qiskit import QDMIProvider @@ -102,11 +108,15 @@ exact = provider.backends(name="MQT Core DDSIM QDMI Device") ## Authentication -The {py:class}`~mqt.core.plugins.qiskit.QDMIProvider` supports authentication for accessing QDMI devices that require credentials. -Authentication parameters are passed to the provider constructor and forwarded to the underlying session. +The {py:class}`~mqt.core.plugins.qiskit.QDMIProvider` supports authentication +for accessing QDMI devices that require credentials. +Authentication parameters are passed to the provider constructor +and forwarded to the underlying session. :::{note} -The default local devices (MQT Core DDSIM QDMI Device, MQT NA Default QDMI Device) do not require authentication. +The default local devices +(MQT Core DDSIM QDMI Device, MQT NA Default QDMI Device) +do not require authentication. Authentication is primarily used when connecting to remote quantum hardware. ::: @@ -115,10 +125,12 @@ Authentication is primarily used when connecting to remote quantum hardware. The provider supports multiple authentication methods: - **Token-based authentication**: Using an API token or access token -- **Username/password authentication**: Traditional credential-based authentication +- **Username/password authentication**: + Traditional credential-based authentication - **File-based authentication**: Reading credentials from a file - **URL-based authentication**: Connecting to an authentication server -- **Project-based authentication**: Associating sessions with specific projects, e.g., for accounting or quota management +- **Project-based authentication**: Associating sessions with specific projects, + e.g., for accounting or quota management ### Using Authentication Tokens @@ -178,7 +190,8 @@ provider = QDMIProvider(token="your_api_token", project_id="quantum-research-pro ### Combining Authentication Parameters -Multiple authentication parameters can be combined for services that require multiple credentials: +Multiple authentication parameters can be combined for services +that require multiple credentials: ```python # Use multiple authentication parameters @@ -206,8 +219,9 @@ except RuntimeError as e: ## Device Capabilities and Target -The backend automatically introspects the FoMaC (QDMI) device and constructs a Qiskit {py:class}`~qiskit.transpiler.Target` -object describing device capabilities. +The backend automatically introspects the FoMaC (QDMI) device +and constructs a Qiskit {py: +class}`~qiskit.transpiler.Target` object describing device capabilities. ```{code-cell} ipython3 # Access device properties via the Target @@ -220,15 +234,18 @@ if coupling_map: print(f"Coupling map: {coupling_map}") ``` -The backend maps QDMI device operations to corresponding Qiskit gates, including: +The backend maps QDMI device operations to corresponding Qiskit gates, +including: - **Single-qubit Pauli gates**: `x`, `y`, `z`, `id`/`i` - **Hadamard**: `h` - **Phase gates**: `s`, `sdg`, `t`, `tdg`, `sx`, `sxdg`, `p`, `phase`, `gphase` - **Rotation gates (parametric)**: `rx`, `ry`, `rz`, `r`/`prx` - **Universal gates (parametric)**: `u`, `u1`, `u2`, `u3` -- **Two-qubit gates**: `cx`/`cnot`, `cy`, `cz`, `ch`, `cs`, `csdg`, `csx`, `swap`, `iswap`, `dcx`, `ecr` -- **Two-qubit parametric gates**: `cp`, `cu1`, `cu3`, `crx`, `cry`, `crz`, `rxx`, `ryy`, `rzz`, `rzx`, `xx_plus_yy`, `xx_minus_yy` +- **Two-qubit gates**: `cx`/`cnot`, `cy`, `cz`, `ch`, `cs`, `csdg`, `csx`, + `swap`, `iswap`, `dcx`, `ecr` +- **Two-qubit parametric gates**: `cp`, `cu1`, `cu3`, `crx`, `cry`, `crz`, + `rxx`, `ryy`, `rzz`, `rzx`, `xx_plus_yy`, `xx_minus_yy` - **Three-qubit gates**: `ccx`, `ccz`, `cswap` - **Multi-controlled gates**: `mcx`, `mcz`, `mcp`, `mcrx`, `mcry`, `mcrz` - **Non-unitary operations**: `reset`, `measure` @@ -255,13 +272,17 @@ print(f"Total shots: {sum(counts.values())}") Circuits must meet the following requirements before execution: -1. **All parameters must be bound**: Circuits with unbound parameters raise {py:class}`~mqt.core.plugins.qiskit.CircuitValidationError` -2. **Only supported operations**: Operations not supported by the device raise {py:class}`~mqt.core.plugins.qiskit.UnsupportedOperationError` +1. **All parameters must be bound**: Circuits with unbound parameters raise {py: + class}`~mqt.core.plugins.qiskit.CircuitValidationError` +2. **Only supported operations**: + Operations not supported by the device raise {py: + class}`~mqt.core.plugins.qiskit.UnsupportedOperationError` 3. **Valid shots value**: Must be a non-negative integer ### Parameter Binding -The backend supports automatic parameter binding through the `parameter_values` argument. +The backend supports automatic parameter binding through the `parameter_values` +argument. You can pass parameter values either as dictionaries or as sequences of values: ```python @@ -289,7 +310,8 @@ job = backend.run(circuits, parameter_values=param_values, shots=100) ### Job Status -The {py:class}`~mqt.core.plugins.qiskit.QDMIJob` wraps a FoMaC (QDMI) job and provides status tracking: +The {py:class}`~mqt.core.plugins.qiskit.QDMIJob` wraps a FoMaC (QDMI) job +and provides status tracking: ```python from qiskit.providers import JobStatus @@ -368,14 +390,19 @@ for qc in circuits: ## Qiskit Primitives -The backend provides implementations of Qiskit's [Primitives V2](https://docs.quantum.ibm.com/api/qiskit/primitives) interfaces: -{py:class}`~mqt.core.plugins.qiskit.QDMISampler` and {py:class}`~mqt.core.plugins.qiskit.QDMIEstimator`. -These primitives allow for a simplified execution workflow for sampling bitstrings and estimating expectation values. +The backend provides implementations of Qiskit's +[Primitives V2](https://docs.quantum.ibm.com/api/qiskit/primitives) interfaces: +{py:class}`~mqt.core.plugins.qiskit.QDMISampler` and +{py:class}`~mqt.core.plugins.qiskit.QDMIEstimator`. +These primitives allow for a simplified execution workflow +for sampling bitstrings and estimating expectation values. ### Sampler -The {py:class}`~mqt.core.plugins.qiskit.QDMISampler` implements the `BaseSamplerV2` interface. -It is used to sample quantum circuits and obtain measurement counts (bitstrings). +The {py:class}`~mqt.core.plugins.qiskit.QDMISampler` implements the +`BaseSamplerV2` interface. +It is used to sample quantum circuits +and obtain measurement counts (bitstrings). ```{code-cell} ipython3 from mqt.core.plugins.qiskit import QDMISampler @@ -403,7 +430,8 @@ print(f"Sampler results: {counts}") ### Estimator -The {py:class}`~mqt.core.plugins.qiskit.QDMIEstimator` implements the `BaseEstimatorV2` interface. +The {py:class}`~mqt.core.plugins.qiskit.QDMIEstimator` implements the +`BaseEstimatorV2` interface. It is used to calculate expectation values of observables. ```{code-cell} ipython3 @@ -499,8 +527,12 @@ except UnsupportedFormatError as e: When you run a circuit, the backend: -1. Validates the circuit (checks for unbound parameters, supported operations, valid options) -2. Converts the circuit to one of the program formats supported by the target device (IQM JSON, OpenQASM 2, OpenQASM 3) using {py:func}`~mqt.core.plugins.qiskit.qiskit_to_iqm_json` or Qiskit's built-in QASM exporters +1. Validates the circuit (checks for unbound parameters, supported operations, + valid options) +2. Converts the circuit to one of the program formats supported by the target + device (IQM JSON, OpenQASM 2, OpenQASM 3) using + {py:func}`~mqt.core.plugins.qiskit.qiskit_to_iqm_json` or Qiskit's built-in + QASM exporters 3. Submits the program to the QDMI device via `device.submit_job()` 4. Returns a {py:class}`~mqt.core.plugins.qiskit.QDMIJob` @@ -515,10 +547,18 @@ The backend builds its {py:class}`~qiskit.transpiler.Target` by: ### Primitives Implementation -The Qiskit Primitives are implemented as lightweight wrappers around the backend execution: +The Qiskit Primitives are implemented +as lightweight wrappers around the backend execution: -- **Sampler**: Submits circuits to the backend and reshapes the resulting bitstrings into the requested structure (PubResult). -- **Estimator**: Decomposes observables into Pauli terms, appends necessary basis rotations and measurements to the provided circuits, and submits them to the backend. It then reconstructs expectation values and standard deviations from the measurement counts of each term based on the provided precision or shots. +- **Sampler**: Submits circuits to the backend + and reshapes the resulting bitstrings into the requested structure + (PubResult). +- **Estimator**: Decomposes observables into Pauli terms, + appends necessary basis rotations and measurements to the provided circuits, + and submits them to the backend. + It then reconstructs expectation values + and standard deviations from the measurement counts of each term based on the + provided precision or shots. ## API Reference @@ -527,6 +567,8 @@ For complete API documentation, see: - {py:class}`~mqt.core.plugins.qiskit.QDMIProvider` — Device provider interface - {py:class}`~mqt.core.plugins.qiskit.QDMIBackend` — BackendV2 implementation - {py:class}`~mqt.core.plugins.qiskit.QDMIJob` — Job wrapper and result handling -- {py:class}`~mqt.core.plugins.qiskit.QDMIEstimator` — EstimatorV2 primitive implementation -- {py:class}`~mqt.core.plugins.qiskit.QDMISampler` — SamplerV2 primitive implementation +- {py:class}`~mqt.core.plugins.qiskit.QDMIEstimator` — + EstimatorV2 primitive implementation +- {py:class}`~mqt.core.plugins.qiskit.QDMISampler` — + SamplerV2 primitive implementation - {py:mod}`~mqt.core.plugins.qiskit.exceptions` — Exception types diff --git a/docs/qir/index.md b/docs/qir/index.md index c794af124c..9ee02e446e 100644 --- a/docs/qir/index.md +++ b/docs/qir/index.md @@ -1,22 +1,29 @@ # QIR Support in the MQT -The [_Quantum Intermediate Representation_ (QIR)](https://www.qir-alliance.org) is a standardized intermediate representation for quantum programs based on the [_LLVM intermediate representation_ (LLVM IR)](http://llvm.org/). +The [_Quantum Intermediate Representation_ (QIR)](https://www.qir-alliance.org) +is a standardized intermediate representation for quantum programs based on the +[_LLVM intermediate representation_ (LLVM IR)](http://llvm.org/). ## The QIR Runtime in MQT Core -MQT Core provides a runtime for QIR that is based on its decision diagram-based quantum simulator. -This allows for the execution of QIR programs using MQT Core's high-performance simulation capabilities. +MQT Core provides a runtime for QIR +that is based on its decision diagram-based quantum simulator. +This allows for the execution of QIR programs using MQT Core's high-performance +simulation capabilities. The runtime can be utilized in two ways: -1. As a standalone library that can be linked to any QIR program, resulting in a binary executable. -2. By using the `mqt-core-qir-runner` command-line tool, which interprets QIR programs directly. +1. As a standalone library that can be linked to any QIR program, + resulting in a binary executable. +2. By using the `mqt-core-qir-runner` command-line tool, + which interprets QIR programs directly. See {cite:p}`stadeTowardsSupportingQIR2025` for more details. ### Building the Runner -To build this tool, the CMake option `BUILD_MQT_CORE_QIR_RUNNER` has to be enabled. +To build this tool, the CMake option `BUILD_MQT_CORE_QIR_RUNNER` has to be +enabled. It is enabled by default, but depends on `BUILD_MQT_CORE_MLIR` being set. From the root of the repository, you can build the runner as follows: @@ -25,11 +32,13 @@ cmake -S . -B build -DBUILD_MQT_CORE_QIR_RUNNER=ON -DBUILD_MQT_CORE_MLIR=ON cmake --build build --target mqt-core-qir-runner ``` -After building, the tool can be found in the build directory under `bin/mqt-core-qir-runner`. +After building, the tool can be found in the build directory under +`bin/mqt-core-qir-runner`. ### Executing a QIR Program -The `mqt-core-qir-runner` can be used to execute a QIR file (typically with a `.ll` extension). +The `mqt-core-qir-runner` can be used to execute a QIR file +(typically with a `.ll` extension). ```bash ./build/bin/mqt-core-qir-runner bell.ll @@ -40,6 +49,9 @@ The runner supports the QIR Base Profile. ### QIR Support in the DDSIM QDMI Device -The QDMI Device accepts jobs in the following program formats: QASM2, QASM3, QIR Base/Adaptive Profile Module (LLVM bitcode), and QIR Base/Adaptive Profile String (LLVM assembly). -These QIR formats are only supported when the `BUILD_MQT_CORE_QDMI_DDSIM_WITH_QIR` CMake option is enabled. +The QDMI Device accepts jobs in the following program formats: QASM2, QASM3, +QIR Base/Adaptive Profile Module +(LLVM bitcode), and QIR Base/Adaptive Profile String (LLVM assembly). +These QIR formats are only supported +when the `BUILD_MQT_CORE_QDMI_DDSIM_WITH_QIR` CMake option is enabled. It is enabled by default, but depends on `BUILD_MQT_CORE_MLIR` being set. diff --git a/docs/tooling.md b/docs/tooling.md index fd1a9a33ef..4fff9978a1 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 Core. +This page summarizes the main tools, software, and standards used in MQT Core. It serves as a quick reference for new contributors and users who want to understand the project's ecosystem. diff --git a/docs/zx_package.md b/docs/zx_package.md index a958e16ce1..63ea3af703 100644 --- a/docs/zx_package.md +++ b/docs/zx_package.md @@ -1,16 +1,28 @@ # MQT Core ZX -MQT Core provides a minimal library for creating ZX-diagrams and rewriting them using the ZX-calculus. -The main use of this library within the Munich Quantum Toolkit is as a tool for equivalence checking of quantum circuits, especially with a focus on symbolic quantum circuits. -Other uses for the ZX-calculus and ZX-diagrams include compilation and optimization. -Furthermore, other diagrammatic rewriting systems exist for reasoning about different aspects of quantum circuits such as the ZH-calculus. -If you are looking for general-purpose libraries that encompass these functionalities, we recommend [PyZX](https://pyzx.readthedocs.io/en/latest/) or [QuiZX](https://github.com/zxcalc/quizx). -For an introduction to the ZX-calculus, we recommend the excellent [ZX-calculus for the working quantum computer scientist](https://arxiv.org/abs/2012.13966). +MQT Core provides a minimal library for creating ZX-diagrams +and rewriting them using the ZX-calculus. +The main use of this library within the Munich Quantum Toolkit is as a tool +for equivalence checking of quantum circuits, +especially with a focus on symbolic quantum circuits. +Other uses for the ZX-calculus and ZX-diagrams include compilation +and optimization. +Furthermore, other diagrammatic rewriting systems exist +for reasoning about different aspects of quantum circuits such +as the ZH-calculus. +If you are looking for general-purpose libraries +that encompass these functionalities, +we recommend [PyZX](https://pyzx.readthedocs.io/en/latest/) +or [QuiZX](https://github.com/zxcalc/quizx). +For an introduction to the ZX-calculus, +we recommend the excellent +[ZX-calculus for the working quantum computer scientist](https://arxiv.org/abs/2012.13966). ## Quickstart There are two ways of obtaining a ZX-diagram with MQT Core. -The simplest way is from a quantum circuit, or rather, an MQT Core `QuantumComputation`: +The simplest way is from a quantum circuit, or rather, +an MQT Core `QuantumComputation`: ```cpp #include "zx/ZXDiagram.hpp" @@ -53,17 +65,25 @@ Next, we add qubits to the diagram. diag.addQubits(3); ``` -Some vertices in a ZX-diagram are special because they represent inputs and outputs of the diagram. -All vertices in a ZX-diagram are either of type `zx::VertexType::Z`, `zx::VertexType::X` or `zx::VertexType::Boundary`. +Some vertices in a ZX-diagram are special because they represent inputs +and outputs of the diagram. +All vertices in a ZX-diagram are either of type `zx::VertexType::Z`, +`zx::VertexType::X` or `zx::VertexType::Boundary`. Boundary vertices denote the inputs. -Therefore, at this point the diagram has 6 vertices (3 input vertices, 3 output vertices) and 3 edges connecting the respective inputs and outputs. +Therefore, at this point the diagram has 6 vertices +(3 input vertices, 3 output vertices) +and 3 edges connecting the respective inputs and outputs. Next, we add the Hadamard gate on qubit 0. -While Hadamard gates have an Euler decomposition in terms of X- and Z-spiders, they are so common that it is helpful to have a notation for them. +While Hadamard gates have an Euler decomposition in terms of X- and Z-spiders, +they are so common that it is helpful to have a notation for them. To this end, there are two types of edges in the diagram. -An edge is either `zx::EdgeType::Simple` or `zx::EdgeType::Hadamard`, where Hadamard edges represent wires with a Hadamard gate on them. +An edge is either `zx::EdgeType::Simple` or `zx::EdgeType::Hadamard`, +where Hadamard edges represent wires with a Hadamard gate on them. -To represent a Hadamard gate we, therefore, have to add a new Vertex to the diagram, connect it to the input of qubit 0 with a Hadamard edge. +To represent a Hadamard gate we, therefore, +have to add a new Vertex to the diagram, +connect it to the input of qubit 0 with a Hadamard edge. ```cpp auto in0 = diag.getInputs()[0]; @@ -72,16 +92,22 @@ diag.addEdge(in0, newVertex, zx::EdgeType::Hadamard); ``` We see that adding a new vertex requires 4 parameters. -These are the x- and y-coordinates of the vertex, the phase of the vertex and the vertextype. -The coordinates are there to identify where vertices lie if we would arrange the diagram on a grid. +These are the x- and y-coordinates of the vertex, +the phase of the vertex and the vertextype. +The coordinates are there to identify where vertices lie +if we would arrange the diagram on a grid. They have no other special semantics. -The phase of the diagram is of type `zx::PiExpression` which is a class representing symbolic sums of monomials. +The phase of the diagram is of type `zx::PiExpression` +which is a class representing symbolic sums of monomials. We will talk a bit more about these further below. -For now, we simply need to know that `zx::PiExpression()` represents a phase of 0. +For now, we simply need to know +that `zx::PiExpression()` represents a phase of 0. Next we need to add two CNOTs to the diagram. -A CNOT in the ZX-calculus is represented by a Z-vertex (the control) and an X-vertex (the target), connected by a single non-Hadamard wire. +A CNOT in the ZX-calculus is represented by a Z-vertex +(the control) +and an X-vertex (the target), connected by a single non-Hadamard wire. ```cpp auto in1 = diag.getInputs()[1]; @@ -109,21 +135,29 @@ diag.addEdge(trgt2, diag.getOutputs()[2]); ``` Let us return to the matter of symbolic phases and phases in general. -Phases of vertices in a ZX-diagram are all of type `zx::PiExpression` even if the phases are variable-free. -In the variable-free case, the `zx::PiExpression` consists only of a constant of type `zx::PiRational`. -The `zx::PiRational` class represents angles in the half-open interval $(-\pi, \pi]$ as a fraction of $\pi$. -For example, the number $\pi$ itself would be represented by the fraction $\frac{1}{1}$, the number $-\pi / 2$ would be $\frac{-1}{2}$. -This is because phases in terms of fractions of $\pi$ appear frequently in the ZX-calculus. +Phases of vertices in a ZX-diagram are all of type `zx::PiExpression` even +if the phases are variable-free. +In the variable-free case, +the `zx::PiExpression` consists only of a constant of type `zx::PiRational`. +The `zx::PiRational` class represents angles in the half-open interval +$(-\pi, \pi]$ as a fraction of $\pi$. +For example, the number $\pi$ itself would be represented by the fraction +$\frac{1}{1}$, the number $-\pi / 2$ would be $\frac{-1}{2}$. +This is because phases in terms of fractions of $\pi$ appear frequently in the +ZX-calculus. For more on symbolic expressions we refer to the code documentation. ## Rewriting -The true power of ZX-diagrams lies in the ZX-calculus which allows for manipulating ZX-diagrams. -The MQT Core ZX-calculus library provides some rewriting rules for ZX-diagrams in the header `Rules.hpp`. +The true power of ZX-diagrams lies in the ZX-calculus which allows +for manipulating ZX-diagrams. +The MQT Core ZX-calculus library provides some rewriting rules +for ZX-diagrams in the header `Rules.hpp`. The simplification routines are provided in the header `Simplify.hpp`. For example, the previous diagram has multiple connected Z-vertices on qubit 0. -According to the axioms of the ZX-calculus, these can be merged via spider fusion. +According to the axioms of the ZX-calculus, +these can be merged via spider fusion. We can perform this simplification on the diagram as follows. ```cpp @@ -139,7 +173,8 @@ This results in the following diagram. :align: center ``` -`n_simplifications` will be two when executing this code since two spiders can be fused. +`n_simplifications` will be two when executing this code +since two spiders can be fused. The diagrams are manipulated inplace for performance reasons. For an overview on simplifications, we refer to the code documentation. diff --git a/paper/paper.md b/paper/paper.md index 5d10c2f733..3bb73bc213 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -35,110 +35,129 @@ date: 7 November 2024 bibliography: paper.bib --- -# Summary +## Summary -MQT Core is an open-source C++ and Python library for quantum computing that forms the backbone of -the quantum software tools developed as part of the _Munich Quantum Toolkit (MQT, -[@willeMQTHandbookSummary2024])_ by the [Chair for Design Automation](https://www.cda.cit.tum.de/) -at the [Technical University of Munich](https://www.tum.de/) and [MQSC](https://mq.sc). -To this end, it consists of multiple components that are used throughout the MQT, including a fully fledged intermediate representation -(IR) for quantum computations, a state-of-the-art decision diagram (DD) package for quantum -computing, and a state-of-the-art ZX-diagram package for working with the ZX-calculus. Pre-built -binaries are available via [PyPI](https://pypi.org/project/mqt.core/) for all major operating -systems and all modern Python versions. MQT Core is fully compatible with IBM's Qiskit 1.0 and above -[@qiskit2024], as well as the OpenQASM format [@cross2022openqasm], enabling seamless integration -with the broader quantum computing community. +MQT Core is an open-source C++ and Python library for quantum computing +that forms the backbone of the quantum software tools developed +as part of the _Munich Quantum Toolkit (MQT, [@willeMQTHandbookSummary2024])_ by +the [Chair for Design Automation](https://www.cda.cit.tum.de/) at the +[Technical University of Munich](https://www.tum.de/) and [MQSC](https://mq.sc). +To this end, it consists of multiple components +that are used throughout the MQT, +including a fully fledged intermediate representation (IR) +for quantum computations, +a state-of-the-art decision diagram (DD) package for quantum computing, +and a state-of-the-art ZX-diagram package for working with the ZX-calculus. +Pre-built binaries are available via [PyPI](https://pypi.org/project/mqt.core/) +for all major operating systems and all modern Python versions. +MQT Core is fully compatible with IBM's Qiskit 1.0 and above [@qiskit2024], +as well as the OpenQASM format [@cross2022openqasm], +enabling seamless integration with the broader quantum computing community. -# Statement of Need +## Statement of Need -Quantum computing is rapidly transitioning from theoretical research to practice, with potential -applications in fields such as finance, chemistry, machine learning, optimization, cryptography, and -unstructured search. However, the development of scalable quantum applications requires automated, -efficient, and accessible software tools that cater to the diverse needs of end users, engineers, +Quantum computing is rapidly transitioning from theoretical research to +practice, with potential applications in fields such as finance, chemistry, +machine learning, optimization, cryptography, and unstructured search. +However, the development of scalable quantum applications requires automated, +efficient, and accessible software tools +that cater to the diverse needs of end users, engineers, and physicists across the entire quantum software stack. -The Munich Quantum Toolkit (MQT, [@willeMQTHandbookSummary2024]) addresses this need by leveraging -decades of design automation expertise from the classical computing domain. Developed by the Chair -for Design Automation at the Technical University of Munich, the MQT provides a comprehensive suite -of tools designed to support various design tasks in quantum computing. These tasks include -high-level application development, classical simulation, compilation, verification of quantum -circuits, quantum error correction, and physical design. +The Munich Quantum Toolkit +(MQT, [@willeMQTHandbookSummary2024]) +addresses this need by leveraging decades of design automation expertise from +the classical computing domain. +Developed by the Chair for Design Automation at the Technical University of +Munich, the MQT provides a comprehensive suite of tools designed to support +various design tasks in quantum computing. +These tasks include high-level application development, classical simulation, +compilation, verification of quantum circuits, quantum error correction, +and physical design. -MQT Core offers a flexible intermediate representation for quantum computations that forms the basis -for working with quantum circuits throughout the MQT. The library provides interfaces to IBM's -Qiskit [@qiskit2024] and the OpenQASM format [@cross2022openqasm] to make the developed tools -accessible to the broader quantum computing community. Furthermore, MQT Core integrates -state-of-the-art data structures for quantum computing, such as decision diagrams -[@willeDecisionDiagramsQuantum2023] and the ZX-calculus [@vandeweteringZXcalculusWorkingQuantum2020; -@duncanGraphtheoreticSimplificationQuantum2020], that power the MQT's software packages for classical -quantum circuit simulation ([MQT DDSIM](https://github.com/cda-tum/mqt-ddsim)), compilation ([MQT QMAP](https://github.com/cda-tum/mqt-qmap)), -verification ([MQT QCEC](https://github.com/cda-tum/mqt-qcec)), and more. As such, MQT Core has enabled -more than 30 research papers over its first five years of development [@willeDecisionDiagramsQuantum2023; -@hillmichJustRealThing2020; -@hillmichApproximatingDecisionDiagrams2022; @grurlStochasticQuantumCircuit2021; -@grurlConsideringDecoherenceErrors2020; @grurlNoiseawareQuantumCircuit2023; -@grurlAutomaticImplementationEvaluation2023; @burgholzerHybridSchrodingerFeynmanSimulation2021; -@burgholzerExploitingArbitraryPaths2022; @burgholzerSimulationPathsQuantum2022; -@burgholzerEfficientConstructionFunctional2021; @hillmichAccurateNeededEfficient2020; -@hillmichConcurrencyDDbasedQuantum2020; @hillmichExploitingQuantumTeleportation2021; -@burgholzerLimitingSearchSpace2022; @pehamDepthoptimalSynthesisClifford2023; @pehamOptimalSubarchitecturesQuantum2023; -@schmidComputationalCapabilitiesCompiler2024; @schmidHybridCircuitMapping2024; -@burgholzerAdvancedEquivalenceChecking2021; @burgholzerImprovedDDbasedEquivalence2020; -@burgholzerPowerSimulationEquivalence2020; @burgholzerRandomStimuliGeneration2021; -@burgholzerVerifyingResultsIBM2020; @pehamEquivalenceCheckingParadigms2022; -@pehamEquivalenceCheckingParameterized2023; @pehamEquivalenceCheckingQuantum2022; -@willeVerificationQuantumCircuits2022; @sanderHamiltonianSimulationDecision2023; -@willeToolsQuantumComputing2022; @willeVisualizingDecisionDiagrams2021; @willeEfficientCorrectCompilation2020]. +MQT Core offers a flexible intermediate representation for quantum computations +that forms the basis for working with quantum circuits throughout the MQT. +The library provides interfaces to IBM's Qiskit [@qiskit2024] +and the OpenQASM format [@cross2022openqasm] to make the developed tools +accessible to the broader quantum computing community. +Furthermore, MQT Core integrates state-of-the-art data structures +for quantum computing, such +as decision diagrams [@willeDecisionDiagramsQuantum2023] and the ZX-calculus +[@vandeweteringZXcalculusWorkingQuantum2020; @duncanGraphtheoreticSimplificationQuantum2020], +that power the MQT's software packages for classical quantum circuit simulation +([MQT DDSIM](https://github.com/cda-tum/mqt-ddsim)), compilation +([MQT QMAP](https://github.com/cda-tum/mqt-qmap)), verification +([MQT QCEC](https://github.com/cda-tum/mqt-qcec)), and more. +As such, MQT Core has enabled more than 30 research papers over its first five +years of development +[@willeDecisionDiagramsQuantum2023; @hillmichJustRealThing2020; @hillmichApproximatingDecisionDiagrams2022; @grurlStochasticQuantumCircuit2021; @grurlConsideringDecoherenceErrors2020; @grurlNoiseawareQuantumCircuit2023; @grurlAutomaticImplementationEvaluation2023; @burgholzerHybridSchrodingerFeynmanSimulation2021; @burgholzerExploitingArbitraryPaths2022; @burgholzerSimulationPathsQuantum2022; @burgholzerEfficientConstructionFunctional2021; @hillmichAccurateNeededEfficient2020; @hillmichConcurrencyDDbasedQuantum2020; @hillmichExploitingQuantumTeleportation2021; @burgholzerLimitingSearchSpace2022; @pehamDepthoptimalSynthesisClifford2023; @pehamOptimalSubarchitecturesQuantum2023; @schmidComputationalCapabilitiesCompiler2024; @schmidHybridCircuitMapping2024; @burgholzerAdvancedEquivalenceChecking2021; @burgholzerImprovedDDbasedEquivalence2020; @burgholzerPowerSimulationEquivalence2020; @burgholzerRandomStimuliGeneration2021; @burgholzerVerifyingResultsIBM2020; @pehamEquivalenceCheckingParadigms2022; @pehamEquivalenceCheckingParameterized2023; @pehamEquivalenceCheckingQuantum2022; @willeVerificationQuantumCircuits2022; @sanderHamiltonianSimulationDecision2023; @willeToolsQuantumComputing2022; @willeVisualizingDecisionDiagrams2021; @willeEfficientCorrectCompilation2020]. -To ensure performance, MQT Core is primarily implemented in C++. Since the quantum computing -community predominantly uses Python, MQT Core provides Python bindings that allow seamless -integration with existing Python-based quantum computing tools. In addition, pre-built Python wheels -are available for all major platforms and Python versions, making it easy to install and use MQT -Core in various environments without the need for manual compilation. +To ensure performance, MQT Core is primarily implemented in C++. +Since the quantum computing community predominantly uses Python, +MQT Core provides Python bindings +that allow seamless integration with existing Python-based quantum computing +tools. +In addition, pre-built Python wheels are available for all major platforms +and Python versions, making it easy to install +and use MQT Core in various environments without the need +for manual compilation. -# Related Work +## Related Work -MQT Core builds on a rich history of research in quantum computing, design automation, and data -structures. The design of its IR is heavily inspired by IBM's Qiskit [@qiskit2024], with which it -has stayed compatible since `qiskit-terra` version 0.16.1 (released at the end of 2020). -MQT Core remains one of the few libraries providing drop-in replacements for large parts of Qiskit's -core data structures in C++. -Alternative IRs, that come as part of larger quantum computing frameworks, include -Quantinuum's C++-based t$|$ket$\rangle$ [@sivarajah_tket_2021], +MQT Core builds on a rich history of research in quantum computing, +design automation, and data structures. +The design of its IR is heavily inspired by IBM's Qiskit [@qiskit2024], +with which it has stayed compatible since `qiskit-terra` version 0.16.1 +(released at the end of 2020). +MQT Core remains one of the few libraries providing drop-in replacements +for large parts of Qiskit's core data structures in C++. +Alternative IRs, that come as part of larger quantum computing frameworks, +include Quantinuum's C++-based t$|$ket$\rangle$ [@sivarajah_tket_2021], LBNL's Python-based `bqskit` [@younis_berkeley_2021], -Xanadu's MLIR-based `catalyst` [@Ittah2024], and -NVIDIA's MLIR-based `CUDA-Q` [@cuda_q]. +Xanadu's MLIR-based `catalyst` [@Ittah2024], +and NVIDIA's MLIR-based `CUDA-Q` [@cuda_q]. -The origin of the decision diagram package in MQT Core dates back to the seminal work on -Quantum Multiple-Valued Decision Diagrams (QMDDs) [@niemann_qmdds_2016]. -It provides a state-of-the-art implementation of QMDDs that natively integrates with the MQT Core IR. -Alternative types of quantum decision diagrams and related software packages include -TDD's [@hong_tensor_2022], Bit-Slicing Decision Diagrams [@tsaiBitSlicingHilbertSpace2021], and -LIMDDs [@vinkhuijzen_limdd_2023]. -In comparison to MQT Core, most of these libraries have remained academic prototypes and have not -seen widespread adoption in the quantum computing community. +The origin of the decision diagram package in MQT Core dates back to the seminal +work on Quantum Multiple-Valued Decision Diagrams (QMDDs) [@niemann_qmdds_2016]. +It provides a state-of-the-art implementation of QMDDs +that natively integrates with the MQT Core IR. +Alternative types of quantum decision diagrams +and related software packages include TDD's [@hong_tensor_2022], +Bit-Slicing Decision Diagrams [@tsaiBitSlicingHilbertSpace2021], +and LIMDDs [@vinkhuijzen_limdd_2023]. +In comparison to MQT Core, +most of these libraries have remained academic prototypes +and have not seen widespread adoption in the quantum computing community. -The ZX-diagram package in MQT Core is inspired by the `PyZX` library [@kissingerPyZXLargeScale2020] -and the t$|$ket$\rangle$ [@sivarajah_tket_2021] compiler. -It provides an efficient C++ implementation of core ZX-calculus concepts and is tightly integrated -with the MQT Core IR. -Compared to other implementations, the ZX package in MQT Core is fine-tuned for verification use -cases and provides dedicated support for handling qubit permutations as well as numerical -inaccuracies that arise in practice. +The ZX-diagram package in MQT Core is inspired by the `PyZX` library +[@kissingerPyZXLargeScale2020] and the t$|$ket$\rangle$ [@sivarajah_tket_2021] +compiler. +It provides an efficient C++ implementation of core ZX-calculus concepts +and is tightly integrated with the MQT Core IR. +Compared to other implementations, +the ZX package in MQT Core is fine-tuned for verification use cases +and provides dedicated support for handling qubit permutations as well +as numerical inaccuracies that arise in practice. -# Acknowledgements +## Acknowledgements -We would like to thank all past and present contributors to the MQT Core project, including (in alphabetical order): -Hartwig Bauer, Martin Fink, Ioan-Albert Florea, Elias Foramitti, Rebecca Ghidini, Thomas Grurl, -Stefan Hillmich, Fabian Hingerl, Daniel Lummerstorfer, Joachim Marin, Katrin Muck, Christoph Pichler, -Tobias Prienberger, Parham Rahimi, Janez Rotman, Damian Rovara, Roope Salmi, Aaron Sander, -Ludwig Schmid, Sarah Schneider, Tianyi Wang, Theresa Wasserer, and Alwin Zulehner. -Their contributions have been instrumental in making MQT Core a robust and feature-rich library. +We would like to thank all past +and present contributors to the MQT Core project, including +(in alphabetical order): +Hartwig Bauer, Martin Fink, Ioan-Albert Florea, Elias Foramitti, +Rebecca Ghidini, Thomas Grurl, Stefan Hillmich, Fabian Hingerl, +Daniel Lummerstorfer, Joachim Marin, Katrin Muck, Christoph Pichler, +Tobias Prienberger, Parham Rahimi, Janez Rotman, Damian Rovara, Roope Salmi, +Aaron Sander, Ludwig Schmid, Sarah Schneider, Tianyi Wang, Theresa Wasserer, +and Alwin Zulehner. +Their contributions have been instrumental in making MQT Core a robust +and feature-rich library. -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 +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. -# References +## References From e8c6abfb6e987aa4e0802392b6871186930efda8 Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:51:15 +0200 Subject: [PATCH 3/6] Replace figure directive with image directive --- docs/dd_package.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/dd_package.md b/docs/dd_package.md index d9b23f6750..58a3635d7d 100644 --- a/docs/dd_package.md +++ b/docs/dd_package.md @@ -135,11 +135,17 @@ generate_plot(counts, name, light=True) generate_plot(counts, name, light=False) ``` -```{figure} fig-qpe-light.svg -:align: center :width: 75% :figclass: only-light ``` +```{image} fig-qpe-light.svg +:align: center +:width: 75% +:class: only-light +``` -```{figure} fig-qpe-dark.svg -:align: center :width: 75% :figclass: only-dark ``` +```{image} fig-qpe-dark.svg +:align: center +:width: 75% +:class: only-dark +``` The {py:func}`~mqt.core.dd.sample` function is a high-level interface to the decision diagram package that does not require any knowledge of the underlying From a8ce8a0585df8f2cc93559f23692a88af567c75b Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Tue, 16 Jun 2026 19:08:22 +0200 Subject: [PATCH 4/6] Update rumdl to v0.2.17 --- .pre-commit-config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3917071ee7..f8846ebb82 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -112,9 +112,10 @@ repos: ## Format Markdown files with rumdl - repo: https://github.com/rvben/rumdl-pre-commit - rev: v0.2.10 + rev: v0.2.17 hooks: - id: rumdl + args: [--fix] priority: 5 - id: rumdl-fmt priority: 6 From abda50e2146dcf4e2c58f5d43841953bab8e4c7a Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:39:47 +0200 Subject: [PATCH 5/6] Update rumdl to v0.2.18 --- .pre-commit-config.yaml | 2 +- docs/contributing.md | 10 ++++---- docs/dd_package.md | 38 +++++++++++++++---------------- docs/mqt_core_ir.md | 48 +++++++++++++++++++-------------------- docs/qdmi/driver.md | 8 +++---- docs/qdmi/qdmi_backend.md | 17 +++++++------- 6 files changed, 62 insertions(+), 61 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8846ebb82..ff91510405 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -112,7 +112,7 @@ repos: ## Format Markdown files with rumdl - repo: https://github.com/rvben/rumdl-pre-commit - rev: v0.2.17 + rev: v0.2.18 hooks: - id: rumdl args: [--fix] diff --git a/docs/contributing.md b/docs/contributing.md index 981b536cd6..53f0403d59 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -464,8 +464,8 @@ The Python package itself lives in the {code}`python/mqt/core` directory. The package lives in the {code}`src/mqt/core` 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, @@ -572,9 +572,9 @@ 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. diff --git a/docs/dd_package.md b/docs/dd_package.md index 58a3635d7d..9753fccce5 100644 --- a/docs/dd_package.md +++ b/docs/dd_package.md @@ -34,8 +34,8 @@ in MQT Core from Python. In its simplest use case, the MQT Core DD package can be used -as a classical circuit simulator using the {py: -func}`~mqt.core.dd.sample` function. +as a classical circuit simulator using the {py:func}`~mqt.core.dd.sample` +function. The underlying simulation approach supports mid-circuit measurements, reset operations, as well as classically-controlled operations. For example, the following code snippet demonstrates how to simulate the @@ -150,10 +150,10 @@ generate_plot(counts, name, light=False) The {py:func}`~mqt.core.dd.sample` function is a high-level interface to the decision diagram package that does not require any knowledge of the underlying data structure. -In a similar fashion, the {py:func}`~mqt.core.dd.simulate_statevector` and {py: -func}`~mqt.core.dd.build_unitary` functions can be used to perform statevector -simulation or to construct the unitary matrix representation of a quantum -circuit, respectively. +In a similar fashion, the {py:func}`~mqt.core.dd.simulate_statevector` +and {py:func}`~mqt.core.dd.build_unitary` functions can be used to perform +statevector simulation or to construct the unitary matrix representation of a +quantum circuit, respectively. ```{code-cell} ipython3 from mqt.core.dd import simulate_statevector @@ -200,8 +200,8 @@ out_state_dd = simulate(qc, zero_state_dd, dd) If the [Graphviz](https://www.graphviz.org/) library is installed, the `graphviz` Python package can be used to visualize resulting decision diagram via the {py:meth}`~mqt.core.dd.VectorDD.to_dot` method. -To directly, generate SVG files, the {py: -meth}`~mqt.core.dd.VectorDD.to_svg` method can be used. +To directly, generate SVG files, +the {py:meth}`~mqt.core.dd.VectorDD.to_svg` method can be used. ```{code-cell} ipython3 --- @@ -217,26 +217,26 @@ graphviz.Source(out_state_dd.to_dot()) The DD package provides list of additional functionality when it comes to working with decision diagrams. -Check out the full API documentation of the {py: -class}`~mqt.core.dd.DDPackage` class for more details. +Check out the full API documentation of the {py:class}`~mqt.core.dd.DDPackage` +class for more details. ## How do Quantum Decision Diagrams Work? Decision diagrams were introduced in the 1980s as a data structure -for the efficient representation and manipulation of Boolean functions {cite: -p}`bryantGraphbasedAlgorithmsBoolean1986`. +for the efficient representation +and manipulation of Boolean functions +{cite:p}`bryantGraphbasedAlgorithmsBoolean1986`. This led to the emergence of a wide variety of decision diagrams, -including BDDs, FBDDs, KFDDs, MTBDDs, and ZDDs -(see, for example, {cite: -p}`bryantSymbolicBooleanManipulation1992,wegenerBranchingProgramsBinary2000,gergovEfficientBooleanManipulation1994,drechslerEfficientRepresentationManipulation1994,baharAlgebraicDecisionDiagrams1993,minatoZerosuppressedBDDsSet1993`), +including BDDs, FBDDs, KFDDs, MTBDDs, and ZDDs (see, for example, +{cite:p}`bryantSymbolicBooleanManipulation1992,wegenerBranchingProgramsBinary2000,gergovEfficientBooleanManipulation1994,drechslerEfficientRepresentationManipulation1994,baharAlgebraicDecisionDiagrams1993,minatoZerosuppressedBDDsSet1993`), which made them a crucial tool in the development of modern circuits and systems. Because of their previous success, decision diagrams have been proposed -for application in the realm of quantum computing {cite: -p}`willeDecisionDiagramsQuantum2023,willeToolsQuantumComputing2022,millerQMDDDecisionDiagram2006,niemannQMDDsEfficientQuantum2016,zulehnerHowEfficientlyHandle2019,hongTensorNetworkBased2020,vinkhuijzenLIMDDDecisionDiagram2021`. -Particularly for design tasks like _simulation_ {cite: -p}`viamontesImprovingGatelevelSimulation2003,zulehnerAdvancedSimulationQuantum2019,hillmichJustRealThing2020,burgholzerHybridSchrodingerFeynmanSimulation2021,vinkhuijzenLIMDDDecisionDiagram2021,hillmichApproximatingDecisionDiagrams2022,burgholzerSimulationPathsQuantum2022,grurlNoiseawareQuantumCircuit2023,matoMixeddimensionalQuantumCircuit2023,sanderHamiltonianSimulationDecision2023`, +for application in the realm of quantum computing +{cite:p}`willeDecisionDiagramsQuantum2023,willeToolsQuantumComputing2022,millerQMDDDecisionDiagram2006,niemannQMDDsEfficientQuantum2016,zulehnerHowEfficientlyHandle2019,hongTensorNetworkBased2020,vinkhuijzenLIMDDDecisionDiagram2021`. +Particularly for design tasks like _simulation_ +{cite:p}`viamontesImprovingGatelevelSimulation2003,zulehnerAdvancedSimulationQuantum2019,hillmichJustRealThing2020,burgholzerHybridSchrodingerFeynmanSimulation2021,vinkhuijzenLIMDDDecisionDiagram2021,hillmichApproximatingDecisionDiagrams2022,burgholzerSimulationPathsQuantum2022,grurlNoiseawareQuantumCircuit2023,matoMixeddimensionalQuantumCircuit2023,sanderHamiltonianSimulationDecision2023`, _synthesis_ {cite:p}`niemannEfficientSynthesisQuantum2014,abdollahiAnalysisSynthesisQuantum2006,soekenSynthesisReversibleCircuits2012,zulehnerOnepassDesignReversible2018,adarshSyReCSynthesizerMQT2022,matoMixeddimensionalQuditState2024`, and _verification_ diff --git a/docs/mqt_core_ir.md b/docs/mqt_core_ir.md index ae5dfed95f..003bdfaee0 100644 --- a/docs/mqt_core_ir.md +++ b/docs/mqt_core_ir.md @@ -18,8 +18,8 @@ Munich Quantum Toolkit is the {py:class}`~mqt.core.ir.QuantumComputation` class. It effectively represents quantum computations as sequential lists of operation, similar to Qiskit's {py:class}`~qiskit.circuit.QuantumCircuit` class. -The following will demonstrate how to work with the {py: -class}`~mqt.core.ir.QuantumComputation` class in Python. +The following will demonstrate how to work with the +{py:class}`~mqt.core.ir.QuantumComputation` class in Python. :::{note} MQT Core is primarily designed in C++ with a thin Python wrapper. @@ -88,8 +88,8 @@ for i in range(precision): The circuit class provides lots of flexibility when it comes to the kind of gates that can be applied. -Check out the full API documentation of the {py: -class}`~mqt.core.ir.QuantumComputation` class for more details. +Check out the full API documentation of the +{py:class}`~mqt.core.ir.QuantumComputation` class for more details. ## Visualizing Circuits @@ -109,8 +109,8 @@ This is explained in more detail in the print(qc) ``` -Circuits can also easily be exported to OpenQASM 3 using the {py: -meth}`~mqt.core.ir.QuantumComputation.qasm3_str` method. +Circuits can also easily be exported to OpenQASM 3 using the +{py:meth}`~mqt.core.ir.QuantumComputation.qasm3_str` method. ```{code-cell} ipython3 --- @@ -210,9 +210,8 @@ and output permutation accordingly. ## Operations -The operations in a {py: -class}`~mqt.core.ir.QuantumComputation` object are of type {py: -class}`~mqt.core.ir.operations.Operation`. +The operations in a {py:class}`~mqt.core.ir.QuantumComputation` object are of +type {py:class}`~mqt.core.ir.operations.Operation`. Every type of operation in `mqt-core` is derived from this class. Operations can also be explicitly constructed. Each {py:class}`~mqt.core.ir.operations.Operation` has a type in the form of an @@ -274,11 +273,10 @@ print(qc) A {py:class}`~mqt.core.ir.operations.SymbolicOperation` can represent all gates of a {py:class}`~mqt.core.ir.operations.StandardOperation` but the gate parameters can be symbolic. -Symbolic expressions are represented in MQT using the {py: -class}`~mqt.core.ir.symbolic.Expression` type, -which represent linear combinations of symbolic {py: -class}`~mqt.core.ir.symbolic.Term` objects over some set of {py: -class}`~mqt.core.ir.symbolic.Variable` objects. +Symbolic expressions are represented in MQT using the +{py:class}`~mqt.core.ir.symbolic.Expression` type, which represent linear +combinations of symbolic {py:class}`~mqt.core.ir.symbolic.Term` objects over +some set of {py:class}`~mqt.core.ir.symbolic.Variable` objects. ```{code-cell} ipython3 from mqt.core.ir.operations import SymbolicOperation @@ -301,8 +299,8 @@ u2_symb = SymbolicOperation(target=0, params=[sym, 2.0], op_type=OpType.u2) ### `CompoundOperation` -A {py:class}`~mqt.core.ir.operations.CompoundOperation` bundles multiple {py: -class}`~mqt.core.ir.operations.Operation` objects together. +A {py:class}`~mqt.core.ir.operations.CompoundOperation` bundles multiple +{py:class}`~mqt.core.ir.operations.Operation` objects together. ```{code-cell} ipython3 from mqt.core.ir.operations import CompoundOperation @@ -338,10 +336,12 @@ print(qc) A {py:class}`~mqt.core.ir.operations.IfElseOperation` is an operation controlled by a classical bit or a classical register. -If a given condition is met, the {py: -attr}`~mqt.core.ir.operations.IfElseOperation.then_operation` is applied. -If the condition is not met, the {py: -attr}`~mqt.core.ir.operations.IfElseOperation.else_operation` is applied. +If a given condition is met, +the {py:attr}`~mqt.core.ir.operations.IfElseOperation.then_operation` is +applied. +If the condition is not met, +the {py:attr}`~mqt.core.ir.operations.IfElseOperation.else_operation` is +applied. ```{code-cell} ipython3 qc = QuantumComputation(1, 1) @@ -357,8 +357,8 @@ qc.if_else( print(qc) ``` -If you do not need an `else_operation`, the {py: -class}`~mqt.core.ir.QuantumComputation` class provides a shortcut +If you do not need an `else_operation`, +the {py:class}`~mqt.core.ir.QuantumComputation` class provides a shortcut for creating an {py:meth}`~mqt.core.ir.QuantumComputation.if_` operation. ```{code-cell} ipython3 @@ -402,8 +402,8 @@ print(qc) ### Qiskit In addition to OpenQASM, -`mqt-core` can natively import [Qiskit](https://qiskit.org/) {py: -class}`~qiskit.circuit.QuantumCircuit` objects. +`mqt-core` can natively import [Qiskit](https://qiskit.org/) +{py:class}`~qiskit.circuit.QuantumCircuit` objects. ```{code-cell} ipython3 from qiskit import QuantumCircuit diff --git a/docs/qdmi/driver.md b/docs/qdmi/driver.md index 6b3e7a8dd8..bc76482250 100644 --- a/docs/qdmi/driver.md +++ b/docs/qdmi/driver.md @@ -32,10 +32,10 @@ classes ({cpp:class}`~fomac::Session`, {cpp:class}`~fomac::Session::Device`, {cpp:class}`~fomac::Session::Device::Site`, {cpp:class}`~fomac::Session::Device::Operation`, {cpp:class}`~fomac::Session::Job`) for the QDMI entities. -These classes together with their methods are then exposed to Python, see {py: -class}`~mqt.core.fomac.Session`, {py:class}`~mqt.core.fomac.Device`, {py: -class}`~mqt.core.fomac.Device.Site`, {py: -class}`~mqt.core.fomac.Device.Operation`, {py:class}`~mqt.core.fomac.Job`. +These classes together with their methods are then exposed to Python, +see {py:class}`~mqt.core.fomac.Session`, {py:class}`~mqt.core.fomac.Device`, +{py:class}`~mqt.core.fomac.Device.Site`, +{py:class}`~mqt.core.fomac.Device.Operation`, {py:class}`~mqt.core.fomac.Job`. ## Usage diff --git a/docs/qdmi/qdmi_backend.md b/docs/qdmi/qdmi_backend.md index 13fd66079a..c7c228050c 100644 --- a/docs/qdmi/qdmi_backend.md +++ b/docs/qdmi/qdmi_backend.md @@ -8,8 +8,8 @@ mystnb: # Qiskit Backend Integration -The {py:mod}`mqt.core.plugins.qiskit` module provides a Qiskit {py: -class}`~qiskit.providers.BackendV2`-compatible interface to QDMI devices via +The {py:mod}`mqt.core.plugins.qiskit` module provides a Qiskit +{py:class}`~qiskit.providers.BackendV2`-compatible interface to QDMI devices via FoMaC. This integration allows you to execute Qiskit circuits on QDMI-compliant quantum devices using a familiar Qiskit workflow. @@ -220,8 +220,8 @@ except RuntimeError as e: ## Device Capabilities and Target The backend automatically introspects the FoMaC (QDMI) device -and constructs a Qiskit {py: -class}`~qiskit.transpiler.Target` object describing device capabilities. +and constructs a Qiskit {py:class}`~qiskit.transpiler.Target` object describing +device capabilities. ```{code-cell} ipython3 # Access device properties via the Target @@ -272,11 +272,12 @@ print(f"Total shots: {sum(counts.values())}") Circuits must meet the following requirements before execution: -1. **All parameters must be bound**: Circuits with unbound parameters raise {py: - class}`~mqt.core.plugins.qiskit.CircuitValidationError` +1. **All parameters must be bound**: + Circuits with unbound parameters raise + {py:class}`~mqt.core.plugins.qiskit.CircuitValidationError` 2. **Only supported operations**: - Operations not supported by the device raise {py: - class}`~mqt.core.plugins.qiskit.UnsupportedOperationError` + Operations not supported by the device raise + {py:class}`~mqt.core.plugins.qiskit.UnsupportedOperationError` 3. **Valid shots value**: Must be a non-negative integer ### Parameter Binding From 1f18b4e9a8e6c3cf629e70da3f4a42adda0badba Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:40:52 +0200 Subject: [PATCH 6/6] Fix more MyST admonitions --- README.md | 4 ++-- docs/dd_package.md | 27 +++++++++++++++++++-------- docs/qdmi/ddsim_device.md | 4 ++-- docs/qdmi/driver.md | 4 ++-- docs/qdmi/na_device.md | 4 ++-- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4fdde16eaf..e3e4ba8837 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,8 @@ for the quantum computing community. To support this endeavor, please consider: -- Starring and sharing our repositories: https: - //github.com/munich-quantum-toolkit +- Starring and sharing our repositories: + - Contributing code, documentation, tests, or examples via issues and pull requests - Citing the MQT in your publications (see [Cite This](#cite-this)) diff --git a/docs/dd_package.md b/docs/dd_package.md index 9753fccce5..0b2480cc92 100644 --- a/docs/dd_package.md +++ b/docs/dd_package.md @@ -299,7 +299,9 @@ The state's amplitudes are annotated at the respective edges. Edges without annotations correspond to an edge weight of 1. ````{admonition} Example _(Single-Qubit States)_ -:class: tip Consider the computational basis states $\ket{0}$ and $\ket{1}$. +:class: tip + +Consider the computational basis states $\ket{0}$ and $\ket{1}$. Then, the corresponding decision diagrams have the structures ```{image} _static/dd-figure-02.svg @@ -397,7 +399,9 @@ that their graph structure allows redundant parts to be merged in the representation instead of being represented repeatedly. ````{admonition} Example _(Redundancy in Decision Diagrams)_ -:class: tip Observe how, as in the previous example, +:class: tip + +Observe how, as in the previous example, the left and right successors of the top-level node (labeled $q_2$) lead to exactly the same structure @@ -515,7 +519,9 @@ Note that $U_{ij}$ can be interpreted as the transformation of $\ket{j}$ to $\ket{i}$. ````{admonition} Example _(Single-Qubit Operations)_ -:class: tip The following shows decision diagram representations +:class: tip + +The following shows decision diagram representations for selected \mbox{single-qubit} operations: ```{image} _static/dd-figure-08.svg @@ -542,17 +548,22 @@ that all complex numbers within the decision diagram have a magnitude of at most $1$, which is used for optimization purposes. ````{admonition} Example _(Matrix Decision Diagrams)_ -:class: tip Consider the maximally-entangling two-qubit $R_{xx}$ rotation -represented by the matrix +:class: tip + +Consider the maximally-entangling two-qubit $R_{xx}$ rotation represented by the +matrix + ```{math} R_{xx} \Bigl(\theta = \frac{\pi}{2} \Bigl) = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 0 & 0 & -i \\ 0 & 1 & -i & 0 \\ 0 & -i & 1 & 0 \\ -i & 0 & 0 & 1 -\end{bmatrix} . +\end{bmatrix}. ``` + This matrix is equivalent to blocks of $2 \times 2$ matrices corresponding to the identity $I$ and the Pauli-$X$ matrix, i.e., + ```{math} :label: rxxmat R_{xx} \Bigl(\theta = \frac{\pi}{2} \Bigl) = \frac{1}{\sqrt{2}}\begin{bmatrix} @@ -560,6 +571,7 @@ I & -iX \\ -iX & I \end{bmatrix}. ``` + The corresponding (already reduced) decision diagram has the following structure: ```{image} _static/dd-figure-09.svg @@ -677,14 +689,13 @@ Matrix-vector multiplication can be handled in a very similar fashion as addition. Standard matrix-vector multiplication can be expressed as - ```{math} :label: multiplication U\ket{\Psi} = \begin{bmatrix} U_{00} & U_{01} \\ U_{10} & U_{11} \end{bmatrix} \begin{bmatrix} \Psi_0 \\ \Psi_1 \end{bmatrix} = w \begin{bmatrix} u_{00} & u_{01} \\ u_{10} & u_{11} \end{bmatrix} w' \begin{bmatrix} \alpha_0 \\ \alpha_1 \end{bmatrix} = ww' \begin{bmatrix} u_{00} \cdot \alpha_0 + u_{10} \cdot \alpha_1 \\ -u_{01} \cdot \alpha_0 + u_{11} \cdot \alpha_1 \end{bmatrix} . +u_{01} \cdot \alpha_0 + u_{11} \cdot \alpha_1 \end{bmatrix}. ``` This implies that a multiplication boils down to four smaller multiplications diff --git a/docs/qdmi/ddsim_device.md b/docs/qdmi/ddsim_device.md index 9be543aa55..0b54c9b73d 100644 --- a/docs/qdmi/ddsim_device.md +++ b/docs/qdmi/ddsim_device.md @@ -24,8 +24,8 @@ number of shots for weak simulation or to `0` for strong simulation. Under the hood, the QDMI device uses the MQT Core OpenQASM parser (see {cpp:func}`qasm3::Importer::imports`) to parse the program into a {cpp:class}`qc::QuantumComputation` object. -That circuit is then passed either to the {cpp:func}`dd::sample` or {cpp: -func}`dd::simulate` function, depending on the mode. +That circuit is then passed either to the {cpp:func}`dd::sample` +or {cpp:func}`dd::simulate` function, depending on the mode. Consult the respective documentation for more details and limitations. The device implements the full QDMI job interface diff --git a/docs/qdmi/driver.md b/docs/qdmi/driver.md index bc76482250..a5878ada1e 100644 --- a/docs/qdmi/driver.md +++ b/docs/qdmi/driver.md @@ -18,8 +18,8 @@ It is responsible for loading the device, forwarding requests from the client to the device, and sending back the results. MQT Core's QDMI Driver, {cpp:class}`qdmi::Driver`, comes with several preloaded devices that can be used directly. -Other devices can be loaded dynamically at runtime via {cpp: -func}`qdmi::Driver::addDynamicDeviceLibrary`. +Other devices can be loaded dynamically at runtime via +{cpp:func}`qdmi::Driver::addDynamicDeviceLibrary`. ## Python Bindings diff --git a/docs/qdmi/na_device.md b/docs/qdmi/na_device.md index 05db63da68..305ce2aacc 100644 --- a/docs/qdmi/na_device.md +++ b/docs/qdmi/na_device.md @@ -21,8 +21,8 @@ a JSON file. The basis of a such device implementation in MQT is a specification in a JSON file. -The structure of this JSON file is defined by the {cpp: -class}`na::Device` struct. +The structure of this JSON file is defined by the {cpp:class}`na::Device` +struct. The struct defines functions to serialize and deserialize the data using the [nlohmann/json](https://json.nlohmann.me) library.