├── .clang-format ├── .clang-tidy ├── .cmake-format.yaml ├── .editorconfig ├── .git_archival.txt ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ └── feature-request.yml ├── SECURITY.md ├── codecov.yml ├── contributing.md ├── pull_request_template.md ├── release-drafter.yml ├── renovate.json5 ├── support.md └── workflows │ ├── cd.yml │ ├── ci.yml │ ├── ci_mlir.yml │ ├── release-drafter.yml │ └── upstream.yml ├── .gitignore ├── .license-tools-config.json ├── .pre-commit-config.yaml ├── .python_version ├── .readthedocs.yaml ├── CHANGELOG.md ├── CITATION.cff ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── UPGRADING.md ├── cmake ├── AddMQTCoreLibrary.cmake ├── Cache.cmake ├── CompilerOptions.cmake ├── CompilerWarnings.cmake ├── ExternalDependencies.cmake ├── FindGMP.cmake ├── GetVersion.cmake ├── PackageAddTest.cmake ├── PreventInSourceBuilds.cmake ├── Sanitizers.cmake ├── SetupMLIR.cmake ├── StandardProjectSettings.cmake ├── cmake_uninstall.cmake.in └── mqt-core-config.cmake.in ├── docs ├── CHANGELOG.md ├── DevelopmentGuide.md ├── Doxyfile ├── UPGRADING.md ├── _static │ ├── custom.css │ ├── dd-figure-01.svg │ ├── dd-figure-02.svg │ ├── dd-figure-03.svg │ ├── dd-figure-04.svg │ ├── dd-figure-05.svg │ ├── dd-figure-06.svg │ ├── dd-figure-07.svg │ ├── dd-figure-08.svg │ ├── dd-figure-09.svg │ ├── dd-figure-10.svg │ ├── dd-figure-11.svg │ ├── dd-figure-12.svg │ ├── dd-figure-13.svg │ ├── dd-figure.tex │ ├── ghz.svg │ ├── ghz_simp.svg │ ├── mqt_dark.png │ └── mqt_light.png ├── _templates │ └── page.html ├── conf.py ├── contributing.md ├── dd_package.md ├── dd_package_evaluation.md ├── index.md ├── installation.md ├── lit_header.bib ├── mlir.md ├── mqt_core_ir.md ├── references.md ├── refs.bib ├── support.md └── zx_package.md ├── eval ├── CMakeLists.txt └── eval_dd_package.cpp ├── include └── mqt-core │ ├── algorithms │ ├── BernsteinVazirani.hpp │ ├── GHZState.hpp │ ├── Grover.hpp │ ├── QFT.hpp │ ├── QPE.hpp │ ├── RandomCliffordCircuit.hpp │ ├── StatePreparation.hpp │ └── WState.hpp │ ├── circuit_optimizer │ └── CircuitOptimizer.hpp │ ├── datastructures │ ├── DirectedAcyclicGraph.hpp │ ├── DirectedGraph.hpp │ ├── DisjointSet.hpp │ ├── Layer.hpp │ ├── SymmetricMatrix.hpp │ └── UndirectedGraph.hpp │ ├── dd │ ├── Approximation.hpp │ ├── CachedEdge.hpp │ ├── Complex.hpp │ ├── ComplexNumbers.hpp │ ├── ComplexValue.hpp │ ├── ComputeTable.hpp │ ├── DDDefinitions.hpp │ ├── DDpackageConfig.hpp │ ├── DensityNoiseTable.hpp │ ├── Edge.hpp │ ├── Export.hpp │ ├── FunctionalityConstruction.hpp │ ├── GateMatrixDefinitions.hpp │ ├── LinkedListBase.hpp │ ├── MemoryManager.hpp │ ├── Node.hpp │ ├── NoiseFunctionality.hpp │ ├── Operations.hpp │ ├── Package.hpp │ ├── Package_fwd.hpp │ ├── RealNumber.hpp │ ├── RealNumberUniqueTable.hpp │ ├── Simulation.hpp │ ├── StateGeneration.hpp │ ├── StochasticNoiseOperationTable.hpp │ ├── UnaryComputeTable.hpp │ ├── UniqueTable.hpp │ └── statistics │ │ ├── MemoryManagerStatistics.hpp │ │ ├── PackageStatistics.hpp │ │ ├── Statistics.hpp │ │ ├── TableStatistics.hpp │ │ └── UniqueTableStatistics.hpp │ ├── ir │ ├── Definitions.hpp │ ├── Permutation.hpp │ ├── QuantumComputation.hpp │ ├── Register.hpp │ └── operations │ │ ├── AodOperation.hpp │ │ ├── ClassicControlledOperation.hpp │ │ ├── CompoundOperation.hpp │ │ ├── Control.hpp │ │ ├── Expression.hpp │ │ ├── NonUnitaryOperation.hpp │ │ ├── OpType.hpp │ │ ├── OpType.inc │ │ ├── Operation.hpp │ │ ├── StandardOperation.hpp │ │ └── SymbolicOperation.hpp │ ├── na │ ├── NAComputation.hpp │ ├── entities │ │ ├── Atom.hpp │ │ ├── Location.hpp │ │ └── Zone.hpp │ └── operations │ │ ├── GlobalCZOp.hpp │ │ ├── GlobalOp.hpp │ │ ├── GlobalRYOp.hpp │ │ ├── LoadOp.hpp │ │ ├── LocalOp.hpp │ │ ├── LocalRZOp.hpp │ │ ├── LocalUOp.hpp │ │ ├── MoveOp.hpp │ │ ├── Op.hpp │ │ ├── ShuttlingOp.hpp │ │ └── StoreOp.hpp │ ├── qasm3 │ ├── Exception.hpp │ ├── Gate.hpp │ ├── Importer.hpp │ ├── InstVisitor.hpp │ ├── NestedEnvironment.hpp │ ├── Parser.hpp │ ├── Scanner.hpp │ ├── Statement.hpp │ ├── Statement_fwd.hpp │ ├── StdGates.hpp │ ├── Token.hpp │ ├── Types.hpp │ ├── Types_fwd.hpp │ └── passes │ │ ├── CompilerPass.hpp │ │ ├── ConstEvalPass.hpp │ │ └── TypeCheckPass.hpp │ └── zx │ ├── FunctionalityConstruction.hpp │ ├── Rational.hpp │ ├── Rules.hpp │ ├── Simplify.hpp │ ├── Utils.hpp │ ├── ZXDefinitions.hpp │ └── ZXDiagram.hpp ├── mlir ├── .gitignore ├── CMakeLists.txt ├── include │ ├── CMakeLists.txt │ └── mlir │ │ ├── CMakeLists.txt │ │ └── Dialect │ │ ├── CMakeLists.txt │ │ ├── Common │ │ ├── Compat.h │ │ └── IR │ │ │ ├── CommonTraits.h │ │ │ ├── CommonTraits.td │ │ │ └── StdOps.td.inc │ │ ├── MQTDyn │ │ ├── CMakeLists.txt │ │ ├── IR │ │ │ ├── CMakeLists.txt │ │ │ ├── MQTDynDialect.h │ │ │ ├── MQTDynInterfaces.td │ │ │ └── MQTDynOps.td │ │ └── Transforms │ │ │ ├── CMakeLists.txt │ │ │ ├── Passes.h │ │ │ └── Passes.td │ │ └── MQTOpt │ │ ├── CMakeLists.txt │ │ ├── IR │ │ ├── CMakeLists.txt │ │ ├── MQTOptDialect.h │ │ ├── MQTOptInterfaces.td │ │ └── MQTOptOps.td │ │ └── Transforms │ │ ├── CMakeLists.txt │ │ ├── Passes.h │ │ └── Passes.td ├── lib │ ├── CMakeLists.txt │ └── Dialect │ │ ├── CMakeLists.txt │ │ ├── MQTDyn │ │ ├── CMakeLists.txt │ │ ├── IR │ │ │ ├── CMakeLists.txt │ │ │ └── MQTDynOps.cpp │ │ └── Transforms │ │ │ ├── CMakeLists.txt │ │ │ ├── ConstantFoldExtractQubitPattern.cpp │ │ │ └── ConstantFolding.cpp │ │ └── MQTOpt │ │ ├── CMakeLists.txt │ │ ├── IR │ │ ├── CMakeLists.txt │ │ └── MQTOptOps.cpp │ │ └── Transforms │ │ ├── CMakeLists.txt │ │ ├── CancelConsecutiveInverses.cpp │ │ ├── CancelConsecutiveInversesPattern.cpp │ │ ├── FromQuantumComputationPattern.cpp │ │ ├── MQTCoreRoundTrip.cpp │ │ ├── QuantumSinkPass.cpp │ │ ├── QuantumSinkPushPattern.cpp │ │ ├── QuantumSinkShiftPattern.cpp │ │ └── ToQuantumComputationPattern.cpp ├── test │ ├── CMakeLists.txt │ ├── Dialect │ │ ├── MQTDyn │ │ │ ├── IR │ │ │ │ └── bell_state_reference_dialect.mlir │ │ │ └── Transforms │ │ │ │ └── constant-folding.mlir │ │ └── MQTOpt │ │ │ ├── IR │ │ │ └── dialect_features.mlir │ │ │ └── Transforms │ │ │ ├── branch-opt.mlir │ │ │ ├── consecutive-inverses.mlir │ │ │ └── to-quantum-computation.mlir │ ├── lit.cfg.py │ └── lit.site.cfg.py.in └── tools │ ├── CMakeLists.txt │ └── quantum-opt │ ├── CMakeLists.txt │ └── quantum-opt.cpp ├── noxfile.py ├── paper ├── codemeta.json ├── paper.bib └── paper.md ├── pyproject.toml ├── src ├── CMakeLists.txt ├── algorithms │ ├── BernsteinVazirani.cpp │ ├── CMakeLists.txt │ ├── GHZState.cpp │ ├── Grover.cpp │ ├── QFT.cpp │ ├── QPE.cpp │ ├── RandomCliffordCircuit.cpp │ ├── StatePreparation.cpp │ └── WState.cpp ├── circuit_optimizer │ ├── CMakeLists.txt │ └── CircuitOptimizer.cpp ├── datastructures │ ├── CMakeLists.txt │ └── Layer.cpp ├── dd │ ├── Approximation.cpp │ ├── CMakeLists.txt │ ├── CachedEdge.cpp │ ├── Complex.cpp │ ├── ComplexNumbers.cpp │ ├── ComplexValue.cpp │ ├── Edge.cpp │ ├── Export.cpp │ ├── FunctionalityConstruction.cpp │ ├── GateMatrixDefinitions.cpp │ ├── MemoryManager.cpp │ ├── Node.cpp │ ├── NoiseFunctionality.cpp │ ├── Operations.cpp │ ├── Package.cpp │ ├── RealNumber.cpp │ ├── RealNumberUniqueTable.cpp │ ├── Simulation.cpp │ ├── StateGeneration.cpp │ ├── UniqueTable.cpp │ └── statistics │ │ ├── MemoryManagerStatistics.cpp │ │ ├── PackageStatistics.cpp │ │ ├── Statistics.cpp │ │ ├── TableStatistics.cpp │ │ └── UniqueTableStatistics.cpp ├── ir │ ├── CMakeLists.txt │ ├── Permutation.cpp │ ├── QuantumComputation.cpp │ └── operations │ │ ├── AodOperation.cpp │ │ ├── ClassicControlledOperation.cpp │ │ ├── CompoundOperation.cpp │ │ ├── Expression.cpp │ │ ├── NonUnitaryOperation.cpp │ │ ├── OpType.cpp │ │ ├── Operation.cpp │ │ ├── StandardOperation.cpp │ │ └── SymbolicOperation.cpp ├── mqt │ └── core │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── _commands.py │ │ ├── _compat │ │ ├── __init__.py │ │ └── typing.py │ │ ├── _version.pyi │ │ ├── dd.pyi │ │ ├── dd_evaluation.py │ │ ├── ir │ │ ├── __init__.pyi │ │ ├── operations.pyi │ │ ├── registers.pyi │ │ └── symbolic.pyi │ │ ├── plugins │ │ ├── __init__.py │ │ └── qiskit │ │ │ ├── __init__.py │ │ │ ├── mqt_to_qiskit.py │ │ │ └── qiskit_to_mqt.py │ │ └── py.typed ├── na │ ├── CMakeLists.txt │ ├── NAComputation.cpp │ ├── entities │ │ └── Zone.cpp │ └── operations │ │ ├── GlobalOp.cpp │ │ ├── LoadOp.cpp │ │ ├── LocalOp.cpp │ │ ├── MoveOp.cpp │ │ └── StoreOp.cpp ├── python │ ├── CMakeLists.txt │ ├── dd │ │ ├── CMakeLists.txt │ │ ├── register_dd.cpp │ │ ├── register_dd_package.cpp │ │ ├── register_matrix_dds.cpp │ │ └── register_vector_dds.cpp │ └── ir │ │ ├── CMakeLists.txt │ │ ├── operations │ │ ├── register_classic_controlled_operation.cpp │ │ ├── register_compound_operation.cpp │ │ ├── register_control.cpp │ │ ├── register_non_unitary_operation.cpp │ │ ├── register_operation.cpp │ │ ├── register_optype.cpp │ │ ├── register_standard_operation.cpp │ │ └── register_symbolic_operation.cpp │ │ ├── register_ir.cpp │ │ ├── register_operations.cpp │ │ ├── register_permutation.cpp │ │ ├── register_quantum_computation.cpp │ │ ├── register_registers.cpp │ │ ├── register_symbolic.cpp │ │ └── symbolic │ │ ├── register_expression.cpp │ │ ├── register_term.cpp │ │ └── register_variable.cpp ├── qasm3 │ ├── CMakeLists.txt │ ├── Importer.cpp │ ├── Parser.cpp │ ├── Scanner.cpp │ ├── Statement.cpp │ ├── Token.cpp │ ├── Types.cpp │ └── passes │ │ ├── ConstEvalPass.cpp │ │ └── TypeCheckPass.cpp └── zx │ ├── CMakeLists.txt │ ├── FunctionalityConstruction.cpp │ ├── Rational.cpp │ ├── Rules.cpp │ ├── Simplify.cpp │ ├── Utils.cpp │ └── ZXDiagram.cpp ├── test ├── CMakeLists.txt ├── algorithms │ ├── CMakeLists.txt │ ├── eval_dynamic_circuits.cpp │ ├── test_bernsteinvazirani.cpp │ ├── test_entanglement.cpp │ ├── test_grover.cpp │ ├── test_qft.cpp │ ├── test_qpe.cpp │ ├── test_random_clifford.cpp │ ├── test_statepreparation.cpp │ └── test_wstate.cpp ├── circuit_optimizer │ ├── CMakeLists.txt │ ├── test_backpropagate_output_permutation.cpp │ ├── test_cancel_cnots.cpp │ ├── test_collect_blocks.cpp │ ├── test_decompose_swap.cpp │ ├── test_defer_measurements.cpp │ ├── test_elide_permutations.cpp │ ├── test_eliminate_resets.cpp │ ├── test_flatten_operations.cpp │ ├── test_remove_diagonal_gates_before_measure.cpp │ ├── test_remove_final_measurements.cpp │ ├── test_remove_operation.cpp │ ├── test_replace_mcx_with_mcz.cpp │ ├── test_single_qubit_gate_fusion.cpp │ └── test_swap_reconstruction.cpp ├── circuits │ ├── bell.qasm │ └── test.qasm ├── datastructures │ ├── CMakeLists.txt │ ├── test_directed_acyclic_graph.cpp │ ├── test_directed_graph.cpp │ ├── test_disjoint_set.cpp │ ├── test_layer.cpp │ ├── test_symmetric_matrix.cpp │ └── test_undirected_graph.cpp ├── dd │ ├── CMakeLists.txt │ ├── test_approximations.cpp │ ├── test_complex.cpp │ ├── test_dd_functionality.cpp │ ├── test_dd_noise_functionality.cpp │ ├── test_edge_functionality.cpp │ ├── test_package.cpp │ └── test_state_generation.cpp ├── ir │ ├── CMakeLists.txt │ ├── test_io.cpp │ ├── test_operation.cpp │ ├── test_qasm3_parser.cpp │ ├── test_qfr_functionality.cpp │ └── test_symbolic.cpp ├── na │ ├── CMakeLists.txt │ └── test_nacomputation.cpp ├── python │ ├── dd │ │ ├── evaluation │ │ │ ├── results_baseline.json │ │ │ ├── results_feature.json │ │ │ └── test_evaluation.py │ │ ├── test_dd_package.py │ │ ├── test_matrix_dds.py │ │ └── test_vector_dds.py │ ├── ir │ │ └── test_ir.py │ ├── plugins │ │ └── test_qiskit.py │ ├── test_cli.py │ └── test_load.py └── zx │ ├── CMakeLists.txt │ ├── test_expression.cpp │ ├── test_rational.cpp │ ├── test_simplify.cpp │ ├── test_zx.cpp │ └── test_zx_functionality.cpp └── uv.lock /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | IncludeBlocks: Regroup 3 | PointerAlignment: Left 4 | -------------------------------------------------------------------------------- /.cmake-format.yaml: -------------------------------------------------------------------------------- 1 | format: 2 | line_width: 100 3 | keyword_case: "upper" 4 | autosort: true 5 | 6 | markup: 7 | first_comment_is_literal: true 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{py,pyi}] 12 | indent_size = 4 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | 17 | [{*.{cmake,cmake.in},CMakeLists.txt}] 18 | max_line_length = 100 19 | -------------------------------------------------------------------------------- /.git_archival.txt: -------------------------------------------------------------------------------- 1 | node: 08e61d14291da0e7e39af3f5e6c46a6641635eb7 2 | node-date: 2025-06-09T20:34:43Z 3 | describe-name: v3.0.2-86-g08e61d142 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | test/circuits/** linguist-vendored 2 | .git_archival.txt export-subst 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | name: 🐛 Bug Report 10 | description: Report a problem or unexpected behavior 11 | title: "🐛 " 12 | body: 13 | - type: markdown 14 | attributes: 15 | value: >- 16 | **Thanks for taking the time to report an issue!** 17 | 18 | ⚠ Before submitting: 19 | 1. Search [existing issues](https://github.com/munich-quantum-toolkit/core/search?q=is%3Aissue&type=issues) to avoid duplicates 20 | 2. For questions or discussions, please use our [discussions forum](https://github.com/munich-quantum-toolkit/core/discussions) 21 | - type: textarea 22 | attributes: 23 | label: System Information 24 | description: Please provide details about your environment 25 | placeholder: | 26 | - Operating System (including version): 27 | - MQT Core version: 28 | - Python/C++ compiler version (if applicable): 29 | - Any relevant dependencies and their versions: 30 | validations: 31 | required: true 32 | - type: textarea 33 | attributes: 34 | label: Bug Description 35 | description: Provide a clear and detailed explanation of the issue you're experiencing. 36 | placeholder: | 37 | What happened? 38 | What did you expect to happen instead? 39 | Include any error messages or unexpected behavior you observed. 40 | validations: 41 | required: true 42 | - type: textarea 43 | attributes: 44 | label: Steps to Reproduce 45 | description: Provide specific steps to reproduce this issue 46 | placeholder: | 47 | 1. Set up environment with '...' 48 | 2. Configure workflow using '...' 49 | 3. Execute command '...' 50 | 4. Observe error/issue: '...' 51 | 52 | Include any relevant code snippets, workflow configurations, or input files that help demonstrate the problem. 53 | validations: 54 | required: true 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | name: ✨ Feature request 10 | description: Suggest a new feature or improvement 11 | title: "✨ " 12 | body: 13 | - type: markdown 14 | attributes: 15 | value: > 16 | **Thanks for helping improve this project by suggesting a feature!** 17 | 18 | ⚠ Before submitting: 19 | - Search [existing feature requests](https://github.com/munich-quantum-toolkit/core/search?q=is%3Aissue&type=issues) to avoid duplicates 20 | - One feature per issue helps us track and implement ideas effectively 21 | 22 | - type: textarea 23 | attributes: 24 | label: Problem Statement 25 | description: >- 26 | Describe the problem you're facing and why it needs to be solved. What limitations are you encountering? 27 | placeholder: >- 28 | Currently, when I try to [action/task], I'm unable to [blockers/limitations]. 29 | This creates problems because [impact/consequences]. 30 | validations: 31 | required: true 32 | 33 | - type: textarea 34 | attributes: 35 | label: Proposed Solution 36 | description: > 37 | Describe your ideal solution. What would the feature look like? How would it work? 38 | placeholder: >- 39 | I'd like to see [feature/change] that would: 40 | - [benefit 1] 41 | - [benefit 2] 42 | - [example usage/scenario] 43 | validations: 44 | required: true 45 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Security updates are applied only to the most recent releases. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | To report vulnerabilities, you can privately report a potential security issue 10 | via the GitHub security vulnerabilities feature. This can be done here: 11 | 12 | https://github.com/munich-quantum-toolkit/core/security/advisories 13 | 14 | Please do **not** open a public issue about a potential security vulnerability. 15 | 16 | You can find more details on the security vulnerability feature in the GitHub 17 | documentation here: 18 | 19 | https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability 20 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "**/python" 3 | - "test/**/*" 4 | 5 | coverage: 6 | range: 60..90 7 | precision: 1 8 | status: 9 | project: off 10 | patch: off 11 | 12 | flag_management: 13 | default_rules: 14 | carryforward: true 15 | statuses: 16 | - type: project 17 | target: auto 18 | threshold: 0.5% 19 | removed_code_behavior: adjust_base 20 | - type: patch 21 | target: 90% 22 | threshold: 1% 23 | individual_flags: 24 | - name: cpp 25 | paths: 26 | - "include" 27 | - "src" 28 | - name: python 29 | paths: 30 | - "src/mqt/**/*.py" 31 | statuses: 32 | - type: project 33 | threshold: 0.5% 34 | removed_code_behavior: adjust_base 35 | - type: patch 36 | target: 95% 37 | threshold: 1% 38 | 39 | parsers: 40 | gcov: 41 | branch_detection: 42 | conditional: no 43 | loop: no 44 | 45 | comment: 46 | layout: "reach, diff, flags, files" 47 | require_changes: true 48 | show_carryforward_flags: true 49 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Please include a summary of the change and, if applicable, which issue is fixed. 4 | Please also include relevant motivation and context. 5 | List any dependencies that are required for this change. 6 | 7 | Fixes #(issue) <!--- Replace `(issue)` with the issue number fixed by this pull request. If this PR does not fix an issue, please remove this line. --> 8 | 9 | ## Checklist: 10 | 11 | <!--- 12 | This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. 13 | --> 14 | 15 | - [ ] The pull request only contains commits that are focused and relevant to this change. 16 | - [ ] I have added appropriate tests that cover the new/changed functionality. 17 | - [ ] I have updated the documentation to reflect these changes. 18 | - [ ] I have added entries to the changelog for any noteworthy additions, changes, fixes or removals. 19 | - [ ] I have added migration instructions to the upgrade guide (if needed). 20 | - [ ] The changes follow the project's style guidelines and introduce no new warnings. 21 | - [ ] The changes are fully tested and pass the CI checks. 22 | - [ ] I have reviewed my own code changes. 23 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: "MQT Core $RESOLVED_VERSION Release" 2 | tag-template: "v$RESOLVED_VERSION" 3 | categories: 4 | - title: "⚛️ MQT Core IR" 5 | labels: 6 | - "Core" 7 | - title: "⚖️ MQT Core DD Package" 8 | labels: 9 | - "DD" 10 | - title: "🕸️ MQT Core ZX Package" 11 | labels: 12 | - "ZX" 13 | - title: "🏼 MQT Core NA Package" 14 | labels: 15 | - "NA" 16 | - title: "🐉 MQT Core MLIR" 17 | labels: 18 | - "MLIR" 19 | - title: "🚀 Features and Enhancements" 20 | labels: 21 | - "feature" 22 | - "enhancement" 23 | - "usability" 24 | - "refactor" 25 | - title: "🐛 Bug Fixes" 26 | labels: 27 | - "bug" 28 | - "fix" 29 | - title: "📄 Documentation" 30 | labels: 31 | - "documentation" 32 | - title: "📦 Packaging" 33 | labels: 34 | - "packaging" 35 | - title: "🧹 Code Quality" 36 | labels: 37 | - "code quality" 38 | - title: "🤖 CI" 39 | labels: 40 | - "continuous integration" 41 | - title: "⬆️ Dependencies" 42 | collapse-after: 5 43 | labels: 44 | - "dependencies" 45 | - "submodules" 46 | - "github_actions" 47 | - "pre-commit" 48 | change-template: "- $TITLE ([#$NUMBER]($URL)) ([**@$AUTHOR**](https://github.com/$AUTHOR))" 49 | change-title-escapes: '\<*_&' 50 | version-resolver: 51 | major: 52 | labels: 53 | - "major" 54 | minor: 55 | labels: 56 | - "minor" 57 | patch: 58 | labels: 59 | - "patch" 60 | default: patch 61 | 62 | template: | 63 | ## 👀 What Changed 64 | 65 | _Please refer to the [changelog](https://github.com/$OWNER/$REPOSITORY/blob/main/CHANGELOG.md) and the [upgrade guide](https://github.com/$OWNER/$REPOSITORY/blob/main/UPGRADING.md) for a structured overview of the changes._ 66 | 67 | $CHANGES 68 | 69 | **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION 70 | -------------------------------------------------------------------------------- /.github/renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | $schema: "https://docs.renovatebot.com/renovate-schema.json", 3 | extends: ["config:recommended", ":gitSignOff"], 4 | prHourlyLimit: 10, 5 | enabledManagers: ["github-actions", "pre-commit", "pep621"], 6 | "pre-commit": { 7 | enabled: true 8 | }, 9 | lockFileMaintenance: { 10 | "enabled": true, 11 | "automerge": true, 12 | }, 13 | configMigration: true, 14 | labels: ["dependencies"], 15 | schedule: ["every weekend"], 16 | packageRules: [ 17 | { 18 | matchManagers: ["github-actions"], 19 | addLabels: ["github-actions"], 20 | commitMessagePrefix: "⬆\uFE0F\uD83D\uDC68\u200D\uD83D\uDCBB" 21 | }, 22 | { 23 | matchManagers: ["pep621"], 24 | addLabels: ["python"], 25 | commitMessagePrefix: "⬆\uFE0F\uD83D\uDC0D" 26 | }, 27 | { 28 | matchManagers: ["pre-commit"], 29 | addLabels: ["pre-commit"], 30 | commitMessagePrefix: "⬆\uFE0F\uD83E\uDE9D", 31 | }, 32 | { 33 | description: "Automerge patch updates", 34 | matchUpdateTypes: ["patch"], 35 | automerge: true 36 | }, 37 | { 38 | description: "Automerge minor updates for stable dependencies", 39 | matchManagers: ["pep621", "pre-commit"], 40 | matchUpdateTypes: ["minor", "patch"], 41 | matchCurrentVersion: "!/^0/", 42 | automerge: true 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /.github/support.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | If you are stuck with a problem using MQT Core or have questions, please get in touch at our [Issues](https://github.com/munich-quantum-toolkit/core/issues) or [Discussions](https://github.com/munich-quantum-toolkit/core/discussions). We'd love to help. 4 | 5 | You can save time by following this procedure when reporting a problem: 6 | 7 | - Do try to solve the problem on your own first. 8 | - Search through past [Issues](https://github.com/munich-quantum-toolkit/core/issues) and [Discussions](https://github.com/munich-quantum-toolkit/core/discussions) to see if someone else already had the same problem. 9 | - Before filing a bug report, try to create a minimal working example (MWE) 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. 10 | 11 | You can also always reach us at [quantum.cda@xcit.tum.de](mailto:quantum.cda@xcit.tum.de). 12 | -------------------------------------------------------------------------------- /.github/workflows/cd.yml: -------------------------------------------------------------------------------- 1 | name: CD 🚀 2 | on: 3 | release: 4 | types: [published] 5 | workflow_dispatch: 6 | 7 | permissions: 8 | attestations: write 9 | contents: read 10 | id-token: write 11 | 12 | jobs: 13 | # Builds the sdist and wheels on all supported platforms and uploads the resulting 14 | # wheels as GitHub artifacts `dev-cibw-*` or `cibw-*`, depending on whether the 15 | # workflow is triggered from a PR or a release, respectively. 16 | python-packaging: 17 | name: 🐍 Packaging 18 | uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging.yml@v1.10 19 | with: 20 | # Runs to enable 21 | enable-ubuntu2404: true 22 | enable-ubuntu2404-arm: true 23 | enable-macos13: true 24 | enable-macos14: true 25 | enable-windows2022: true 26 | enable-windows11-arm: true 27 | # Runs to disable 28 | enable-ubuntu2204: false 29 | enable-ubuntu2204-arm: false 30 | enable-macos15: false 31 | enable-windows2025: false 32 | 33 | # Downloads the previously generated artifacts and deploys to PyPI on published releases. 34 | deploy: 35 | if: github.event_name == 'release' && github.event.action == 'published' 36 | name: 🚀 Deploy to PyPI 37 | runs-on: ubuntu-latest 38 | environment: 39 | name: pypi 40 | url: https://pypi.org/p/mqt.core 41 | needs: [python-packaging] 42 | steps: 43 | - uses: actions/download-artifact@v4 44 | with: 45 | pattern: cibw-* 46 | path: dist 47 | merge-multiple: true 48 | - name: Generate artifact attestation for sdist and wheel(s) 49 | uses: actions/attest-build-provenance@v2 50 | with: 51 | subject-path: "dist/*" 52 | - uses: pypa/gh-action-pypi-publish@release/v1 53 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | types: [opened, reopened, synchronize] 9 | merge_group: 10 | 11 | jobs: 12 | update_release_draft: 13 | name: Run 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: release-drafter/release-drafter@v6 20 | env: 21 | GITHUB_TOKEN: ${{ github.token }} 22 | -------------------------------------------------------------------------------- /.license-tools-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "name": "Chair for Design Automation, TUM\nCopyright (c) 2025 Munich Quantum Software Company GmbH", 4 | "years": [2023, 2025] 5 | }, 6 | "force_author": true, 7 | "license": "MIT", 8 | "title": false, 9 | "include": ["**/*"], 10 | "style_override_for_suffix": { 11 | ".pyi": "DOCSTRING_STYLE", 12 | ".in": "POUND_STYLE", 13 | ".mlir": "SLASH_STYLE", 14 | ".td": "SLASH_STYLE", 15 | ".yaml": "POUND_STYLE", 16 | ".toml": "POUND_STYLE" 17 | }, 18 | "exclude": [ 19 | "^\\.[^/]+", 20 | "/\\.[^/]+", 21 | ".*\\.qasm", 22 | ".*\\.md", 23 | ".*\\.bib", 24 | ".*\\.cff", 25 | ".*\\.css", 26 | ".*\\.json", 27 | ".*\\.html", 28 | ".*\\.tfc", 29 | ".*\\.qc", 30 | ".*\\.real", 31 | ".*\\.tex", 32 | "uv\\.lock", 33 | "py\\.typed", 34 | ".*build.*" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.python_version: -------------------------------------------------------------------------------- 1 | 3.12 2 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | formats: 4 | - pdf 5 | - htmlzip 6 | 7 | build: 8 | os: ubuntu-24.04 9 | tools: 10 | python: "3.12" 11 | apt_packages: 12 | - graphviz 13 | - inkscape 14 | jobs: 15 | post_checkout: 16 | # Skip docs build if the commit message contains "skip ci" 17 | - (git --no-pager log --pretty="tformat:%s -- %b" -1 | grep -viq "skip ci") || exit 183 18 | # Skip docs build if there are no changes related to docs 19 | - | 20 | if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/main -- docs/ .readthedocs.yaml src/mqt/ src/python include/*/python .github/contributing* .github/support*; 21 | then 22 | exit 183; 23 | fi 24 | # Unshallow the git clone and fetch tags to get proper version information 25 | - git fetch --unshallow --tags 26 | pre_build: 27 | # Set up uv 28 | - asdf plugin add uv 29 | - asdf install uv latest 30 | - asdf global uv latest 31 | build: 32 | html: 33 | - uv run --frozen --no-dev --group docs -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html 34 | htmlzip: 35 | - uv run --frozen --no-dev --group docs -m sphinx -T -b dirhtml -d docs/_build/doctrees -D language=en docs docs/_build/dirhtml 36 | - mkdir -p $READTHEDOCS_OUTPUT/htmlzip 37 | - zip -r $READTHEDOCS_OUTPUT/htmlzip/html.zip docs/_build/dirhtml/* 38 | pdf: 39 | - uv run --frozen --no-dev --group docs -m sphinx -T -b latex -d docs/_build/doctrees -D language=en docs docs/_build/latex 40 | - cd docs/_build/latex && latexmk -pdf -f -dvi- -ps- -interaction=nonstopmode -jobname=$READTHEDOCS_PROJECT 41 | - mkdir -p $READTHEDOCS_OUTPUT/pdf 42 | - cp docs/_build/latex/$READTHEDOCS_PROJECT.pdf $READTHEDOCS_OUTPUT/pdf/$READTHEDOCS_PROJECT.pdf 43 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: "1.2.0" 2 | authors: 3 | - family-names: Burgholzer 4 | given-names: Lukas 5 | orcid: "https://orcid.org/0000-0003-4699-1316" 6 | - family-names: Stade 7 | given-names: Yannick 8 | orcid: "https://orcid.org/0000-0001-5785-2528" 9 | - family-names: Peham 10 | given-names: Tom 11 | orcid: "https://orcid.org/0000-0003-3434-7881" 12 | - family-names: Wille 13 | given-names: Robert 14 | orcid: "https://orcid.org/0000-0002-4993-7860" 15 | contact: 16 | - family-names: Burgholzer 17 | given-names: Lukas 18 | orcid: "https://orcid.org/0000-0003-4699-1316" 19 | doi: 10.6084/m9.figshare.28740254.v1 20 | message: If you use this software, please cite our article in the 21 | Journal of Open Source Software. 22 | preferred-citation: 23 | authors: 24 | - family-names: Burgholzer 25 | given-names: Lukas 26 | orcid: "https://orcid.org/0000-0003-4699-1316" 27 | - family-names: Stade 28 | given-names: Yannick 29 | orcid: "https://orcid.org/0000-0001-5785-2528" 30 | - family-names: Peham 31 | given-names: Tom 32 | orcid: "https://orcid.org/0000-0003-3434-7881" 33 | - family-names: Wille 34 | given-names: Robert 35 | orcid: "https://orcid.org/0000-0002-4993-7860" 36 | date-published: 2025-04-07 37 | doi: 10.21105/joss.07478 38 | issn: 2475-9066 39 | issue: 108 40 | journal: Journal of Open Source Software 41 | publisher: 42 | name: Open Journals 43 | start: 7478 44 | title: "MQT Core: The Backbone of the Munich Quantum Toolkit (MQT)" 45 | type: article 46 | url: "https://joss.theoj.org/papers/10.21105/joss.07478" 47 | volume: 10 48 | title: "MQT Core: The Backbone of the Munich Quantum Toolkit (MQT)" 49 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 4 | Copyright (c) 2025 Munich Quantum Software Company GmbH 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /cmake/AddMQTCoreLibrary.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | function(kebab_to_camel output input) 10 | string(REPLACE "-" ";" parts "${input}") 11 | set(result "") 12 | foreach(part ${parts}) 13 | string(SUBSTRING ${part} 0 1 first) 14 | string(SUBSTRING ${part} 1 -1 rest) 15 | string(TOUPPER ${first} first) 16 | string(APPEND result "${first}${rest}") 17 | endforeach() 18 | set(${output} 19 | "${result}" 20 | PARENT_SCOPE) 21 | endfunction() 22 | 23 | function(add_mqt_core_library name) 24 | cmake_parse_arguments(ARG "" "ALIAS_NAME" "" ${ARGN}) 25 | if(BUILD_MQT_CORE_SHARED_LIBS) 26 | add_library(${name} SHARED ${ARG_UNPARSED_ARGUMENTS}) 27 | else() 28 | add_library(${name} ${ARG_UNPARSED_ARGUMENTS}) 29 | endif() 30 | if(NOT ARG_ALIAS_NAME) 31 | # remove prefix 'mqt-' from target name if exists 32 | string(REGEX REPLACE "^${MQT_CORE_TARGET_NAME}" "" ALIAS_NAME_ARG ${name}) 33 | # transform kebab-case to camelCase 34 | kebab_to_camel(ARG_ALIAS_NAME ${ALIAS_NAME_ARG}) 35 | endif() 36 | add_library(MQT::Core${ARG_ALIAS_NAME} ALIAS ${name}) 37 | endfunction() 38 | -------------------------------------------------------------------------------- /cmake/Cache.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | option(ENABLE_CACHE "Enable compiler cache if available" ON) 10 | if(NOT ENABLE_CACHE) 11 | return() 12 | endif() 13 | 14 | set(CACHE_OPTION_VALUES "ccache" "sccache") 15 | set(CACHE_OPTION 16 | "ccache" 17 | CACHE STRING "Compiler cache to use") 18 | set_property(CACHE CACHE_OPTION PROPERTY STRINGS ${CACHE_OPTION_VALUES}) 19 | list(FIND CACHE_OPTION_VALUES ${CACHE_OPTION} CACHE_OPTION_INDEX) 20 | if(CACHE_OPTION_INDEX EQUAL -1) 21 | message(NOTICE 22 | "Unknown compiler cache '${CACHE_OPTION}'. Available options are: ${CACHE_OPTION_VALUES}") 23 | endif() 24 | 25 | find_program(CACHE_BINARY ${CACHE_OPTION}) 26 | if(CACHE_BINARY) 27 | message(STATUS "Compiler cache '${CACHE_OPTION}' found and enabled") 28 | set(CMAKE_C_COMPILER_LAUNCHER ${CACHE_BINARY}) 29 | set(CMAKE_CXX_COMPILER_LAUNCHER ${CACHE_BINARY}) 30 | else() 31 | message(NOTICE "${CACHE_OPTION} is enabled but was not found. Not using it") 32 | endif() 33 | -------------------------------------------------------------------------------- /cmake/PackageAddTest.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # macro to add a test executable for one of the project libraries 10 | macro(PACKAGE_ADD_TEST testname linklibs) 11 | if(NOT TARGET ${testname}) 12 | # create an executable in which the tests will be stored 13 | add_executable(${testname} ${ARGN}) 14 | # link the Google test infrastructure and a default main function to the test executable. 15 | target_link_libraries(${testname} PRIVATE ${linklibs} gmock gtest_main MQT::ProjectOptions 16 | MQT::ProjectWarnings) 17 | # discover tests 18 | gtest_discover_tests( 19 | ${testname} 20 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 21 | PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DISCOVERY_TIMEOUT 60) 22 | set_target_properties(${testname} PROPERTIES FOLDER tests) 23 | endif() 24 | endmacro() 25 | 26 | macro(PACKAGE_ADD_TEST_WITH_WORKING_DIR testname linklibs test_working_directory) 27 | if(NOT TARGET ${testname}) 28 | # create an executable in which the tests will be stored 29 | add_executable(${testname} ${ARGN}) 30 | # link the Google test infrastructure and a default main function to the test executable. 31 | target_link_libraries(${testname} PRIVATE ${linklibs} gmock gtest_main MQT::ProjectOptions 32 | MQT::ProjectWarnings) 33 | # discover tests 34 | gtest_discover_tests( 35 | ${testname} 36 | WORKING_DIRECTORY ${test_working_directory} 37 | PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${test_working_directory}" DISCOVERY_TIMEOUT 60) 38 | set_target_properties(${testname} PROPERTIES FOLDER tests) 39 | endif() 40 | endmacro() 41 | -------------------------------------------------------------------------------- /cmake/PreventInSourceBuilds.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # This function will prevent in-source builds 10 | function(assure_out_of_source_builds) 11 | # make sure the user doesn't play dirty with symlinks 12 | get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) 13 | get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) 14 | 15 | # disallow in-source builds 16 | if("${srcdir}" STREQUAL "${bindir}") 17 | message("######################################################") 18 | message("Warning: in-source builds are disabled") 19 | message("Please create a separate build directory and run cmake from there") 20 | message("######################################################") 21 | message(FATAL_ERROR "Quitting configuration") 22 | endif() 23 | endfunction() 24 | 25 | assure_out_of_source_builds() 26 | -------------------------------------------------------------------------------- /cmake/Sanitizers.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # enable support for all kinds of sanitizers 10 | function(enable_sanitizers target_name) 11 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 12 | set(sanitizers "") 13 | 14 | option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE) 15 | if(ENABLE_SANITIZER_ADDRESS) 16 | list(APPEND sanitizers "address") 17 | endif() 18 | 19 | option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE) 20 | if(ENABLE_SANITIZER_LEAK) 21 | list(APPEND sanitizers "leak") 22 | endif() 23 | 24 | option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE) 25 | if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) 26 | list(APPEND sanitizers "undefined") 27 | endif() 28 | 29 | option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE) 30 | if(ENABLE_SANITIZER_THREAD) 31 | if("address" IN_LIST sanitizers OR "leak" IN_LIST sanitizers) 32 | message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") 33 | else() 34 | list(APPEND sanitizers "thread") 35 | endif() 36 | endif() 37 | 38 | option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE) 39 | if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 40 | if("address" IN_LIST sanitizers 41 | OR "thread" IN_LIST sanitizers 42 | OR "leak" IN_LIST sanitizers) 43 | message( 44 | WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled") 45 | else() 46 | list(APPEND sanitizers "memory") 47 | endif() 48 | endif() 49 | 50 | list(JOIN sanitizers "," list_of_sanitizers) 51 | endif() 52 | 53 | if(list_of_sanitizers) 54 | if(NOT "${list_of_sanitizers}" STREQUAL "") 55 | target_compile_options(${target_name} INTERFACE -fsanitize=${list_of_sanitizers}) 56 | target_link_options(${target_name} INTERFACE -fsanitize=${list_of_sanitizers}) 57 | endif() 58 | endif() 59 | endfunction() 60 | -------------------------------------------------------------------------------- /cmake/SetupMLIR.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # set the include directory for the build tree 10 | set(MQT_MLIR_INCLUDE_BUILD_DIR "${CMAKE_SOURCE_DIR}/mlir/include") 11 | set(MQT_MLIR_MIN_VERSION 19.0) 12 | 13 | # MLIR must be installed on the system 14 | find_package(MLIR REQUIRED CONFIG) 15 | if(MLIR_VERSION VERSION_LESS MQT_MLIR_MIN_VERSION) 16 | message(FATAL_ERROR "MLIR version must be at least ${MQT_MLIR_MIN_VERSION}") 17 | endif() 18 | message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}") 19 | message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 20 | 21 | # Add the paths to the MLIR and LLVM CMake modules. 22 | list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}") 23 | list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") 24 | 25 | # Include the TableGen, LLVM and MLIR CMake modules. 26 | include(TableGen) 27 | include(AddLLVM) 28 | include(AddMLIR) 29 | include(HandleLLVMOptions) 30 | 31 | include_directories(${LLVM_INCLUDE_DIRS}) 32 | include_directories(${MLIR_INCLUDE_DIRS}) 33 | include_directories(${MQT_MLIR_INCLUDE_BUILD_DIR}) 34 | include_directories(${CMAKE_BINARY_DIR}/mlir/include) 35 | link_directories(${LLVM_BUILD_LIBRARY_DIR}) 36 | add_definitions(${LLVM_DEFINITIONS}) 37 | 38 | string(REPLACE "." ";" MLIR_VERSION_COMPONENTS ${MLIR_VERSION}) 39 | list(GET MLIR_VERSION_COMPONENTS 0 MLIR_VERSION_MAJOR) 40 | add_compile_definitions(MLIR_VERSION_MAJOR=${MLIR_VERSION_MAJOR}) 41 | 42 | # set the binary directory for the build tree such that, e.g., docs can be generated in the build 43 | # tree 44 | set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR}) 45 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake 10 | 11 | if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 12 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") 13 | endif() 14 | 15 | file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) 16 | string(REGEX REPLACE "\n" ";" files "${files}") 17 | foreach(file ${files}) 18 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 19 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 20 | exec_program( 21 | "@CMAKE_COMMAND@" ARGS 22 | "-E remove \"$ENV{DESTDIR}${file}\"" 23 | OUTPUT_VARIABLE rm_out 24 | RETURN_VALUE rm_retval) 25 | if(NOT "${rm_retval}" STREQUAL 0) 26 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 27 | endif() 28 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 29 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 30 | endif() 31 | endforeach() 32 | -------------------------------------------------------------------------------- /cmake/mqt-core-config.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # A CMake config file for the library, to be used by external projects 10 | 11 | @PACKAGE_INIT@ 12 | 13 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 14 | 15 | include(CMakeFindDependencyMacro) 16 | find_dependency(nlohmann_json) 17 | option(MQT_CORE_WITH_GMP "Library is configured to use GMP" @MQT_CORE_WITH_GMP@) 18 | if(MQT_CORE_WITH_GMP) 19 | find_dependency(GMP) 20 | endif() 21 | 22 | option(MQT_CORE_ZX_SYSTEM_BOOST 23 | "Library is configured to use system Boost instead of the bundled Boost::multiprecision" 24 | @MQT_CORE_ZX_SYSTEM_BOOST@) 25 | if(MQT_CORE_ZX_SYSTEM_BOOST) 26 | find_dependency(Boost @BOOST_MIN_VERSION@) 27 | endif() 28 | 29 | if(TARGET MQT::Core) 30 | return() 31 | endif() 32 | 33 | include("${CMAKE_CURRENT_LIST_DIR}/Cache.cmake") 34 | include("${CMAKE_CURRENT_LIST_DIR}/PackageAddTest.cmake") 35 | include("${CMAKE_CURRENT_LIST_DIR}/PreventInSourceBuilds.cmake") 36 | include("${CMAKE_CURRENT_LIST_DIR}/StandardProjectSettings.cmake") 37 | include("${CMAKE_CURRENT_LIST_DIR}/mqt-core-targets.cmake") 38 | 39 | if(NOT mqt-core_FIND_QUIETLY) 40 | message(STATUS "Found mqt-core version ${mqt-core_VERSION}") 41 | endif() 42 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ```{include} ../CHANGELOG.md 2 | 3 | ``` 4 | -------------------------------------------------------------------------------- /docs/UPGRADING.md: -------------------------------------------------------------------------------- 1 | ```{include} ../UPGRADING.md 2 | 3 | ``` 4 | -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | .acknowledgements { 2 | margin-top: 1rem; 3 | padding-bottom: 1rem; 4 | padding-top: 1rem; 5 | border-top: 1px solid var(--color-background-border); 6 | font-size: var(--font-size--small); 7 | color: var(--color-foreground-secondary); 8 | } 9 | 10 | .acknowledgements-logos { 11 | display: grid; 12 | grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); 13 | grid-gap: 1em; 14 | align-items: center; 15 | margin-top: 0.5rem; 16 | } 17 | .acknowledgement { 18 | display: flex; 19 | flex-direction: column; 20 | align-items: center; 21 | justify-content: center; 22 | } 23 | 24 | /* override the default background color for literal strings */ 25 | body:not([data-theme="light"]) .highlight .sa, 26 | .highlight .sb, 27 | .highlight .sc, 28 | .highlight .dl, 29 | .highlight .sd, 30 | .highlight .s2, 31 | .highlight .se, 32 | .highlight .sh, 33 | .highlight .si, 34 | .highlight .sx, 35 | .highlight .sr, 36 | .highlight .s1, 37 | .highlight .ss, 38 | .highlight .s1, 39 | .highlight .s { 40 | background-color: #00000001; 41 | } 42 | 43 | /* provide dark mode overrides for mystnb variables */ 44 | body:not([data-theme="light"]) { 45 | --mystnb-source-bg-color: #131416; 46 | --mystnb-stdout-bg-color: #1a1c1e; 47 | --mystnb-stderr-bg-color: #442222; 48 | --mystnb-traceback-bg-color: #202020; 49 | } 50 | 51 | body:not([data-theme="light"]) .highlight .gp { 52 | color: #c65d09; 53 | } 54 | -------------------------------------------------------------------------------- /docs/_static/mqt_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/munich-quantum-toolkit/core/08e61d14291da0e7e39af3f5e6c46a6641635eb7/docs/_static/mqt_dark.png -------------------------------------------------------------------------------- /docs/_static/mqt_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/munich-quantum-toolkit/core/08e61d14291da0e7e39af3f5e6c46a6641635eb7/docs/_static/mqt_light.png -------------------------------------------------------------------------------- /docs/contributing.md: -------------------------------------------------------------------------------- 1 | ```{include} ../.github/contributing.md 2 | 3 | ``` 4 | -------------------------------------------------------------------------------- /docs/mlir.md: -------------------------------------------------------------------------------- 1 | # MLIR in MQT 2 | 3 | This part of MQT explores the capabilities of the Multi-Level Intermediate Representation (MLIR) in the context of compilation for quantum computing. 4 | We define multiple dialects, each with its dedicated purpose. 5 | For example, the MQTOpt dialect is designed for optimization of quantum programs and features value-semantics. 6 | Accompanying the dialects, we provide a set of transformations on each dialect and conversions between dialects. 7 | 8 | :::{note} 9 | This page is a work in progress. 10 | The content is not yet complete and may be subject to change. 11 | Contributions are welcome. 12 | See the [contribution guidelines](contributing.md) for more information. 13 | ::: 14 | 15 | ## FAQ 16 | 17 | ### How to print the textual representation of an operation? 18 | 19 | During debugging, it can be handy to dump the textual representation of an operation to stdout. 20 | This can be done using the `dump` method of the operation either in the evaluation field of the debugger or in the code. 21 | It prints the textual representation of the operation to the standard output. 22 | 23 | ```c++ 24 | op->dump(); 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/references.md: -------------------------------------------------------------------------------- 1 | ```{raw} latex 2 | \begingroup 3 | \renewcommand\section[1]{\endgroup} 4 | \phantomsection 5 | ``` 6 | 7 | ```{only} html 8 | # References 9 | 10 | If you use *MQT Core* in your work, we would appreciate if you cited {cite:p}`burgholzer2025MQTCore`. 11 | 12 | A full list of references is given below. 13 | ``` 14 | 15 | ```{bibliography} 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/support.md: -------------------------------------------------------------------------------- 1 | ```{include} ../.github/support.md 2 | 3 | ``` 4 | -------------------------------------------------------------------------------- /eval/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_executable(mqt-core-dd-eval eval_dd_package.cpp) 10 | target_link_libraries( 11 | mqt-core-dd-eval PRIVATE MQT::CoreDD MQT::CoreAlgorithms MQT::CoreCircuitOptimizer 12 | MQT::ProjectOptions MQT::ProjectWarnings) 13 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/BernsteinVazirani.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | #include <bitset> 17 | #include <cstddef> 18 | 19 | namespace qc { 20 | 21 | using BVBitString = std::bitset<4096>; 22 | 23 | [[nodiscard]] auto createBernsteinVazirani(const BVBitString& hiddenString) 24 | -> QuantumComputation; 25 | [[nodiscard]] auto createBernsteinVazirani(Qubit nq, std::size_t seed = 0) 26 | -> QuantumComputation; 27 | [[nodiscard]] auto createBernsteinVazirani(const BVBitString& hiddenString, 28 | Qubit nq) -> QuantumComputation; 29 | 30 | [[nodiscard]] auto 31 | createIterativeBernsteinVazirani(const BVBitString& hiddenString) 32 | -> QuantumComputation; 33 | [[nodiscard]] auto createIterativeBernsteinVazirani(Qubit nq, 34 | std::size_t seed = 0) 35 | -> QuantumComputation; 36 | [[nodiscard]] auto 37 | createIterativeBernsteinVazirani(const BVBitString& hiddenString, Qubit nq) 38 | -> QuantumComputation; 39 | } // namespace qc 40 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/GHZState.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | namespace qc { 17 | [[nodiscard]] auto createGHZState(Qubit nq) -> QuantumComputation; 18 | } // namespace qc 19 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/Grover.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | #include <bitset> 17 | #include <cstddef> 18 | 19 | namespace qc { 20 | 21 | using GroverBitString = std::bitset<128>; 22 | auto appendGroverInitialization(QuantumComputation& qc) -> void; 23 | auto appendGroverOracle(QuantumComputation& qc, 24 | const GroverBitString& targetValue) -> void; 25 | auto appendGroverDiffusion(QuantumComputation& qc) -> void; 26 | 27 | [[nodiscard]] auto computeNumberOfIterations(Qubit nq) -> std::size_t; 28 | 29 | [[nodiscard]] auto createGrover(Qubit nq, const GroverBitString& targetValue) 30 | -> QuantumComputation; 31 | [[nodiscard]] auto createGrover(Qubit nq, std::size_t seed = 0) 32 | -> QuantumComputation; 33 | } // namespace qc 34 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/QFT.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | namespace qc { 17 | [[nodiscard]] auto createQFT(Qubit nq, bool includeMeasurements = true) 18 | -> QuantumComputation; 19 | 20 | [[nodiscard]] auto createIterativeQFT(Qubit nq) -> QuantumComputation; 21 | } // namespace qc 22 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/QPE.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | #include <cstddef> 17 | 18 | namespace qc { 19 | [[nodiscard]] auto createQPE(Qubit nq, bool exact = true, std::size_t seed = 0) 20 | -> QuantumComputation; 21 | 22 | [[nodiscard]] auto createQPE(fp lambda, Qubit precision) -> QuantumComputation; 23 | 24 | [[nodiscard]] auto createIterativeQPE(Qubit nq, bool exact = true, 25 | std::size_t seed = 0) 26 | -> QuantumComputation; 27 | 28 | [[nodiscard]] auto createIterativeQPE(fp lambda, Qubit precision) 29 | -> QuantumComputation; 30 | } // namespace qc 31 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/RandomCliffordCircuit.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | #include <cstddef> 17 | 18 | namespace qc { 19 | [[nodiscard]] auto createRandomCliffordCircuit(Qubit nq, std::size_t depth = 1, 20 | std::size_t seed = 0) 21 | -> QuantumComputation; 22 | } // namespace qc 23 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/StatePreparation.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/QuantumComputation.hpp" 14 | 15 | #include <complex> 16 | #include <vector> 17 | 18 | namespace qc { 19 | /** 20 | * @brief Prepares a generic quantum state from a list of normalized 21 | * complex amplitudes 22 | * 23 | * Adapted implementation of IBM Qiskit's State Preparation: 24 | * https://github.com/Qiskit/qiskit/blob/e9ccd3f374fd5424214361d47febacfa5919e1e3/qiskit/circuit/library/data_preparation/state_preparation.py 25 | * based on the following paper: 26 | * 27 | * V. V. Shende, S. S. Bullock and I. L. Markov, 28 | * "Synthesis of quantum-logic circuits", in IEEE Transactions on 29 | * Computer-Aided Design of Integrated Circuits and Systems, 30 | * vol. 25, no. 6, pp. 1000-1010, June 2006, 31 | * doi: 10.1109/TCAD.2005.855930. 32 | * 33 | * @param amplitudes State (vector) to prepare. 34 | * Must be normalized and have a size that is a power of two. 35 | * @param eps Precision wanted for computations, default 1e-10 36 | * @return Quantum computation that prepares the state 37 | * @throws invalid_argument If @p amplitudes is not normalized or its length is 38 | * not a power of two. 39 | **/ 40 | [[nodiscard]] auto createStatePreparationCircuit( 41 | const std::vector<std::complex<double>>& amplitudes, double eps = 1e-10) 42 | -> QuantumComputation; 43 | } // namespace qc 44 | -------------------------------------------------------------------------------- /include/mqt-core/algorithms/WState.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | namespace qc { 17 | [[nodiscard]] auto createWState(Qubit nq) -> QuantumComputation; 18 | } // namespace qc 19 | -------------------------------------------------------------------------------- /include/mqt-core/datastructures/DisjointSet.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <algorithm> 14 | #include <cstddef> 15 | #include <unordered_map> 16 | 17 | namespace qc { 18 | template <class T> struct DisjointSet { 19 | std::unordered_map<T, T> parent; 20 | std::unordered_map<T, std::size_t> rank; 21 | 22 | template <class Iterator> 23 | explicit DisjointSet(const Iterator& begin, const Iterator& end) { 24 | std::for_each(begin, end, [&](const auto& element) { 25 | parent[element] = element; 26 | rank[element] = 0; 27 | }); 28 | } 29 | 30 | T findSet(const T& v) { 31 | if (parent[v] != v) { 32 | parent[v] = findSet(parent[v]); 33 | } 34 | return parent[v]; 35 | } 36 | 37 | void unionSet(const T& x, const T& y) { 38 | const auto& xSet = findSet(x); 39 | const auto& ySet = findSet(y); 40 | if (rank[xSet] > rank[ySet]) { 41 | parent[ySet] = xSet; 42 | } else { 43 | parent[xSet] = ySet; 44 | if (rank[xSet] == rank[ySet]) { 45 | ++rank[ySet]; 46 | } 47 | } 48 | } 49 | }; 50 | } // namespace qc 51 | -------------------------------------------------------------------------------- /include/mqt-core/datastructures/SymmetricMatrix.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <cstddef> 14 | #include <vector> 15 | 16 | namespace qc { 17 | /** 18 | * @brief Symmetric matrix class with same number of rows and columns that 19 | * allows access by row and column but uses less memory than a full matrix 20 | */ 21 | template <typename T> class SymmetricMatrix { 22 | std::vector<std::vector<T>> data; 23 | 24 | public: 25 | // Constructors 26 | SymmetricMatrix() = default; 27 | explicit SymmetricMatrix(const size_t size) { 28 | data.resize(size); 29 | for (size_t i = 0; i < size; ++i) { 30 | data[i].resize(i + 1); 31 | } 32 | } 33 | 34 | SymmetricMatrix(const size_t size, const T& value) { 35 | data.resize(size); 36 | for (size_t i = 0; i < size; ++i) { 37 | data[i].resize(i + 1, value); 38 | } 39 | } 40 | 41 | [[nodiscard]] const T& operator()(const size_t row, const size_t col) const { 42 | if (row < col) { 43 | return data[col][row]; 44 | } 45 | return data[row][col]; 46 | } 47 | 48 | [[nodiscard]] T& operator()(const size_t row, const size_t col) { 49 | if (row < col) { 50 | return data[col][row]; 51 | } 52 | return data[row][col]; 53 | } 54 | 55 | [[nodiscard]] size_t size() const { return data.size(); } 56 | }; 57 | } // namespace qc 58 | -------------------------------------------------------------------------------- /include/mqt-core/dd/Approximation.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dd/Node.hpp" 14 | #include "dd/Package.hpp" 15 | 16 | namespace dd { 17 | 18 | /** 19 | * @brief Useful metadata of an approximation run. 20 | */ 21 | struct ApproximationMetadata { 22 | /// @brief The fidelity between the source and the approximated state. 23 | double fidelity; 24 | /// @brief The number of nodes visited during the mark stage. 25 | std::size_t nodesVisited; 26 | /// @brief The lowest qubit number that requires rebuilding. 27 | Qubit min; 28 | }; 29 | 30 | /** 31 | * @brief Approximate the @p state based on fidelity. The fidelity of the 32 | * approximated state will be at least @p fidelity. 33 | * @details Traverses the decision diagram layer by layer in a breadth-first 34 | * manner (iterative deepening algorithm) and eliminates edges greedily until 35 | * the budget (1 - @p fidelity) is exhausted. 36 | * 37 | * @param state The DD to approximate. 38 | * @param fidelity The desired minimum fidelity after approximation. 39 | * @param dd The DD package to use for the approximation. 40 | * @return Metadata about the approximation. 41 | */ 42 | ApproximationMetadata approximate(VectorDD& state, double fidelity, 43 | Package& dd); 44 | 45 | } // namespace dd 46 | -------------------------------------------------------------------------------- /include/mqt-core/dd/GateMatrixDefinitions.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dd/DDDefinitions.hpp" 14 | #include "ir/operations/OpType.hpp" 15 | 16 | #include <vector> 17 | 18 | namespace dd { 19 | 20 | /// Single-qubit gate matrix for collapsing a qubit to the |0> state 21 | constexpr GateMatrix MEAS_ZERO_MAT{1, 0, 0, 0}; 22 | /// Single-qubit gate matrix for collapsing a qubit to the |1> state 23 | constexpr GateMatrix MEAS_ONE_MAT{0, 0, 0, 1}; 24 | 25 | /** 26 | * @brief Converts a given quantum operation to a single-qubit gate matrix 27 | * @param t The quantum operation to convert 28 | * @param params The parameters of the quantum operation 29 | * @return The single-qubit gate matrix representation of the quantum operation 30 | */ 31 | GateMatrix opToSingleQubitGateMatrix(qc::OpType t, 32 | const std::vector<fp>& params = {}); 33 | 34 | /** 35 | * @brief Converts a given quantum operation to a two-qubit gate matrix 36 | * @param t The quantum operation to convert 37 | * @param params The parameters of the quantum operation 38 | * @return The two-qubit gate matrix representation of the quantum operation 39 | */ 40 | TwoQubitGateMatrix opToTwoQubitGateMatrix(qc::OpType t, 41 | const std::vector<fp>& params = {}); 42 | 43 | } // namespace dd 44 | -------------------------------------------------------------------------------- /include/mqt-core/dd/LinkedListBase.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Linked list functionality required for UniqueTable and MemoryManager. 13 | */ 14 | 15 | #pragma once 16 | 17 | namespace dd { 18 | 19 | /** 20 | * @brief A class to provide a base for linked list objects 21 | */ 22 | struct LLBase { 23 | /** 24 | * @brief The pointer to the next object 25 | * @details The next pointer is used to form linked lists of objects. 26 | * Classes used in a linked list must solely inherit from this class. 27 | * Other code in mqt-core relies on the assumption that all objects in a 28 | * linked list are of the same type. 29 | */ 30 | LLBase* next_ = nullptr; 31 | 32 | /** 33 | * @brief Default getter for the next object 34 | * @details Classes that inherit from LLBase should implement their own next() 35 | * method to return the next object in the list with a specialized return 36 | * type. 37 | * @return LLBase* 38 | */ 39 | [[nodiscard]] LLBase* next() const noexcept { return next_; } 40 | 41 | /// Setter for the next object 42 | void setNext(LLBase* n) noexcept { next_ = n; } 43 | }; 44 | 45 | } // namespace dd 46 | -------------------------------------------------------------------------------- /include/mqt-core/dd/Package_fwd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dd/Edge.hpp" 14 | #include "dd/Node.hpp" 15 | 16 | namespace dd { 17 | class Package; 18 | 19 | using VectorDD = Edge<vNode>; 20 | using MatrixDD = Edge<mNode>; 21 | using DensityMatrixDD = Edge<dNode>; 22 | } // namespace dd 23 | -------------------------------------------------------------------------------- /include/mqt-core/dd/statistics/PackageStatistics.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dd/Package.hpp" 14 | 15 | #include <iostream> 16 | #include <nlohmann/json_fwd.hpp> 17 | #include <string> 18 | 19 | namespace dd { 20 | 21 | /** 22 | * @brief Computes an estimate for the memory usage of active DDs. 23 | * @details The estimate is based on the number of active entries in the 24 | * respective unique tables. It accounts for the memory used by DD nodes, DD 25 | * edges, and real numbers. 26 | * @param package The package instance 27 | * @return The estimated memory usage in MiB 28 | */ 29 | [[nodiscard]] double computeActiveMemoryMiB(const Package& package); 30 | 31 | /** 32 | * @brief Computes an estimate for the peak memory usage of DDs. 33 | * @details The estimate is based on the peak number of used entries in the 34 | * respective memory managers. It accounts for the memory used by DD nodes, DD 35 | * edges, and real numbers. 36 | * @param package The package instance 37 | * @return The estimated memory usage in MiB 38 | */ 39 | [[nodiscard]] double computePeakMemoryMiB(const Package& package); 40 | 41 | [[nodiscard]] nlohmann::basic_json<> 42 | getStatistics(const Package& package, bool includeIndividualTables = false); 43 | 44 | /** 45 | * @brief Get some key statistics about data structures used by the DD package 46 | * @return A JSON representation of the statistics 47 | */ 48 | [[nodiscard]] nlohmann::basic_json<> getDataStructureStatistics(); 49 | 50 | [[nodiscard]] std::string getStatisticsString(const Package& package); 51 | 52 | void printStatistics(const Package& package, std::ostream& os = std::cout); 53 | 54 | } // namespace dd 55 | -------------------------------------------------------------------------------- /include/mqt-core/dd/statistics/Statistics.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "nlohmann/json_fwd.hpp" 14 | 15 | #include <ostream> 16 | #include <string> 17 | 18 | namespace dd { 19 | 20 | struct Statistics { 21 | Statistics() = default; 22 | Statistics(const Statistics&) = default; 23 | Statistics(Statistics&&) = default; 24 | Statistics& operator=(const Statistics&) = default; 25 | Statistics& operator=(Statistics&&) = default; 26 | virtual ~Statistics() = default; 27 | 28 | /// Reset all statistics (except for peak values) 29 | virtual void reset() noexcept {}; 30 | 31 | /// Get a JSON representation of the statistics 32 | [[nodiscard]] virtual nlohmann::json json() const; 33 | 34 | /// Get a pretty-printed string representation of the statistics 35 | [[nodiscard]] virtual std::string toString() const; 36 | 37 | /** 38 | * @brief Write a string representation to an output stream 39 | * @param os The output stream 40 | * @param stats The statistics 41 | * @return The output stream 42 | */ 43 | friend std::ostream& operator<<(std::ostream& os, const Statistics& stats) { 44 | return os << stats.toString(); 45 | } 46 | }; 47 | 48 | } // namespace dd 49 | -------------------------------------------------------------------------------- /include/mqt-core/dd/statistics/UniqueTableStatistics.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "dd/statistics/TableStatistics.hpp" 14 | 15 | #include <cstddef> 16 | #include <nlohmann/json_fwd.hpp> 17 | 18 | namespace dd { 19 | /// \brief A class for storing statistics of a unique table 20 | struct UniqueTableStatistics : public TableStatistics { 21 | /** 22 | * @brief The total number of active entries 23 | * @details An entry is considered active if it has a non-zero reference count 24 | */ 25 | std::size_t numActiveEntries = 0U; 26 | /// The peak number of active entries in the table 27 | std::size_t peakNumActiveEntries = 0U; 28 | /// The number of garbage collection runs 29 | std::size_t gcRuns = 0U; 30 | 31 | /// Track a new active entry 32 | void trackActiveEntry() noexcept; 33 | 34 | /// Reset all statistics (except for the peak values) 35 | void reset() noexcept override; 36 | 37 | /// Get a JSON representation of the statistics 38 | [[nodiscard]] nlohmann::json json() const override; 39 | }; 40 | 41 | } // namespace dd 42 | -------------------------------------------------------------------------------- /include/mqt-core/na/entities/Atom.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a type for representing individual atoms. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include <ostream> 18 | #include <string> 19 | #include <utility> 20 | 21 | namespace na { 22 | /// Represents an atom in the NAComputation. 23 | /// @details The name of the atom is used for printing the NAComputation. 24 | /// To maintain the uniqueness of atoms, the name of the atom should be unique. 25 | class Atom final { 26 | /// The identifier of the atom. 27 | std::string name_; 28 | 29 | public: 30 | /// Creates a new atom with the given name. 31 | /// @param name The name of the atom. 32 | explicit Atom(std::string name) : name_(std::move(name)) {} 33 | 34 | /// Returns the name of the atom. 35 | [[nodiscard]] auto getName() const -> std::string { return name_; } 36 | 37 | /// Prints the atom to the given output stream. 38 | /// @param os The output stream to print the atom to. 39 | /// @param obj The atom to print. 40 | /// @return The output stream after printing the atom. 41 | friend auto operator<<(std::ostream& os, const Atom& obj) -> std::ostream& { 42 | return os << obj.getName(); 43 | } 44 | 45 | /// Compares two atoms for equality. 46 | /// @param other The atom to compare with. 47 | /// @return True if the atoms are equal, false otherwise. 48 | [[nodiscard]] auto operator==(const Atom& other) const -> bool { 49 | if (this == &other) { 50 | return true; 51 | } 52 | return name_ == other.name_; 53 | } 54 | 55 | /// Compares two atoms for inequality. 56 | /// @param other The atom to compare with. 57 | /// @return True if the atoms are not equal, false otherwise. 58 | [[nodiscard]] auto operator!=(const Atom& other) const -> bool { 59 | return !(*this == other); 60 | } 61 | }; 62 | } // namespace na 63 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/GlobalCZOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing global CZ operations. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "na/entities/Zone.hpp" 18 | #include "na/operations/GlobalOp.hpp" 19 | 20 | #include <utility> 21 | #include <vector> 22 | 23 | namespace na { 24 | /// Represents a global CZ operation in the NAComputation. 25 | class GlobalCZOp final : public GlobalOp { 26 | public: 27 | /// Creates a new CZ operation in the given zones. 28 | /// @param zones The zones the operation is applied to. 29 | explicit GlobalCZOp(std::vector<const Zone*> zones) 30 | : GlobalOp(std::move(zones), {}) { 31 | name_ = "cz"; 32 | } 33 | 34 | /// Creates a new CZ operation in the given zone. 35 | /// @param zone The zone the operation is applied to. 36 | explicit GlobalCZOp(const Zone& zone) : GlobalCZOp({&zone}) {} 37 | }; 38 | } // namespace na 39 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/GlobalOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing global operations in the 13 | * NAComputation. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include "ir/Definitions.hpp" 19 | #include "na/entities/Zone.hpp" 20 | #include "na/operations/Op.hpp" 21 | 22 | #include <string> 23 | #include <utility> 24 | #include <vector> 25 | 26 | namespace na { 27 | /// Represents a global operation in the NAComputation. 28 | /// @details Global operations are applied to entire zones instead of to 29 | /// individual atoms. 30 | class GlobalOp : public Op { 31 | protected: 32 | /// The name of the operation. 33 | std::string name_; 34 | /// The parameters of the operation. 35 | std::vector<qc::fp> params_; 36 | /// The zones the operation is applied to. 37 | std::vector<const Zone*> zones_; 38 | 39 | /// Creates a new global operation in the given zone with the given 40 | /// parameters. 41 | /// @param zones The zones the operation is applied to. 42 | /// @param params The parameters of the operation. 43 | GlobalOp(std::vector<const Zone*> zones, std::vector<qc::fp> params) 44 | : params_(std::move(params)), zones_(std::move(zones)) {} 45 | 46 | public: 47 | GlobalOp() = delete; 48 | 49 | /// Returns the parameters of the operation. 50 | [[nodiscard]] auto getParams() const -> auto& { return params_; } 51 | 52 | /// Returns the zone the operation is applied to. 53 | [[nodiscard]] auto getZones() const -> auto& { return zones_; } 54 | 55 | /// Returns a string representation of the operation. 56 | [[nodiscard]] auto toString() const -> std::string override; 57 | }; 58 | } // namespace na 59 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/GlobalRYOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing global RY operations. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "ir/Definitions.hpp" 18 | #include "na/entities/Zone.hpp" 19 | #include "na/operations/GlobalOp.hpp" 20 | 21 | #include <utility> 22 | #include <vector> 23 | 24 | namespace na { 25 | /// Represents a global RY operation in the NAComputation. 26 | class GlobalRYOp final : public GlobalOp { 27 | public: 28 | /// Creates a new RY operation in the given zones with the given angle. 29 | /// @param zones The zones the operation is applied to. 30 | /// @param angle The angle of the operation. 31 | GlobalRYOp(std::vector<const Zone*> zones, const qc::fp angle) 32 | : GlobalOp(std::move(zones), {angle}) { 33 | name_ = "ry"; 34 | } 35 | 36 | /// Creates a new RY operation in the given zone with the given angle. 37 | /// @param zone The zone the operation is applied to. 38 | /// @param angle The angle of the operation. 39 | GlobalRYOp(const Zone& zone, const qc::fp angle) 40 | : GlobalRYOp({&zone}, angle) {} 41 | }; 42 | } // namespace na 43 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/LocalOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing local operations in the 13 | * NAComputation. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include "ir/Definitions.hpp" 19 | #include "na/entities/Atom.hpp" 20 | #include "na/operations/Op.hpp" 21 | 22 | #include <string> 23 | #include <utility> 24 | #include <vector> 25 | 26 | namespace na { 27 | /// Represents a local operation in the NAComputation. 28 | /// @details A local operation is applied to individual atoms. 29 | class LocalOp : public Op { 30 | protected: 31 | /// The name of the operation. 32 | std::string name_; 33 | /// The parameters of the operation. 34 | std::vector<qc::fp> params_; 35 | /// The atoms the operation is applied to. 36 | std::vector<const Atom*> atoms_; 37 | 38 | /// Creates a new local operation with the given atoms and parameters. 39 | /// @param atoms The atoms the operation is applied to. 40 | /// @param params The parameters of the operation. 41 | LocalOp(std::vector<const Atom*> atoms, std::vector<qc::fp> params) 42 | : params_(std::move(params)), atoms_(std::move(atoms)) {} 43 | 44 | public: 45 | LocalOp() = delete; 46 | 47 | /// Returns the atoms the operation is applied to. 48 | [[nodiscard]] auto getAtoms() const -> auto& { return atoms_; } 49 | 50 | /// Returns the parameters of the operation. 51 | [[nodiscard]] auto getParams() const -> auto& { return params_; } 52 | 53 | /// Returns a string representation of the operation. 54 | [[nodiscard]] auto toString() const -> std::string override; 55 | }; 56 | } // namespace na 57 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/LocalRZOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing local RZ operations. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "ir/Definitions.hpp" 18 | #include "na/entities/Atom.hpp" 19 | #include "na/operations/LocalOp.hpp" 20 | 21 | #include <string> 22 | #include <utility> 23 | #include <vector> 24 | 25 | namespace na { 26 | /// Represents a local RZ operation in the NAComputation. 27 | class LocalRZOp final : public LocalOp { 28 | public: 29 | /// Creates a new RZ operation with the given atoms and angle. 30 | /// @param atoms The atoms the operation is applied to. 31 | /// @param angle The angle of the operation. 32 | LocalRZOp(std::vector<const Atom*> atoms, const qc::fp angle) 33 | : LocalOp(std::move(atoms), {angle}) { 34 | name_ = "rz"; 35 | } 36 | 37 | /// Creates a new RZ operation with the given atom and angle. 38 | /// @param atom The atom the operation is applied to. 39 | /// @param angle The angle of the operation. 40 | LocalRZOp(const Atom& atom, const qc::fp angle) : LocalRZOp({&atom}, angle) {} 41 | }; 42 | } // namespace na 43 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/LocalUOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing local U3 operations. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "ir/Definitions.hpp" 18 | #include "na/entities/Atom.hpp" 19 | #include "na/operations/LocalOp.hpp" 20 | 21 | #include <string> 22 | #include <utility> 23 | #include <vector> 24 | 25 | namespace na { 26 | /// Represents a local U3 operation in the NAComputation. 27 | class LocalUOp final : public LocalOp { 28 | public: 29 | /// Creates a new U3 operation with the given atoms and angles. 30 | /// @param atoms The atoms the operation is applied to. 31 | /// @param theta The first parameter of the operation. 32 | /// @param phi The second parameter of the operation. 33 | /// @param lambda The third parameter of the operation. 34 | LocalUOp(std::vector<const Atom*> atoms, const qc::fp theta, const qc::fp phi, 35 | const qc::fp lambda) 36 | : LocalOp(std::move(atoms), {theta, phi, lambda}) { 37 | name_ = "u"; 38 | } 39 | 40 | /// Creates a new U3 operation with the given atom and angle. 41 | /// @param atom The atom the operation is applied to. 42 | /// @param theta The first parameter of the operation. 43 | /// @param phi The second parameter of the operation. 44 | /// @param lambda The third parameter of the operation. 45 | LocalUOp(const Atom& atom, const qc::fp theta, const qc::fp phi, 46 | const qc::fp lambda) 47 | : LocalUOp({&atom}, theta, phi, lambda) {} 48 | }; 49 | } // namespace na 50 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/MoveOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a class for representing move operations. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "na/entities/Atom.hpp" 18 | #include "na/entities/Location.hpp" 19 | #include "na/operations/ShuttlingOp.hpp" 20 | 21 | #include <stdexcept> 22 | #include <string> 23 | #include <utility> 24 | #include <vector> 25 | 26 | namespace na { 27 | /// Represents a move operation in the NAComputation. 28 | class MoveOp final : public ShuttlingOp { 29 | protected: 30 | /// The target locations to move the atoms to. 31 | std::vector<Location> targetLocations_; 32 | 33 | public: 34 | /// Creates a new move operation with the given atoms and target locations. 35 | /// @param atoms The atoms to move. 36 | /// @param targetLocations The target locations to move the atoms to. 37 | MoveOp(std::vector<const Atom*> atoms, std::vector<Location> targetLocations) 38 | : ShuttlingOp(std::move(atoms)), 39 | targetLocations_(std::move(targetLocations)) { 40 | if (atoms_.size() != targetLocations_.size()) { 41 | throw std::invalid_argument( 42 | "Number of atoms and target locations must be equal."); 43 | } 44 | } 45 | 46 | /// Creates a new move operation with the given atom and target location. 47 | /// @param atom The atom to move. 48 | /// @param targetLocation The target location to move the atom to. 49 | MoveOp(const Atom& atom, const Location& targetLocation) 50 | : MoveOp({&atom}, {targetLocation}) {} 51 | 52 | /// Returns whether the move operation has target locations set. 53 | [[nodiscard]] auto hasTargetLocations() const -> bool override { 54 | return true; 55 | } 56 | 57 | /// Returns the target locations of the move operation. 58 | [[nodiscard]] auto getTargetLocations() const -> const 59 | decltype(targetLocations_)& override { 60 | return targetLocations_; 61 | } 62 | 63 | /// Returns a string representation of the operation. 64 | [[nodiscard]] auto toString() const -> std::string override; 65 | }; 66 | } // namespace na 67 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/Op.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines the base class for all operations in the NAComputation. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include <ostream> 18 | #include <string> 19 | 20 | namespace na { 21 | /// This is the base class for all operations in the NAComputation. 22 | class Op { 23 | public: 24 | /// Default constructor. 25 | Op() = default; 26 | 27 | /// Virtual destructor. 28 | virtual ~Op() = default; 29 | 30 | /// Returns a string representation of the operation. 31 | [[nodiscard]] virtual auto toString() const -> std::string = 0; 32 | 33 | /// Prints the operation to the given output stream. 34 | /// @param os The output stream to print the operation to. 35 | /// @param obj The operation to print. 36 | /// @return The output stream after printing the operation. 37 | friend auto operator<<(std::ostream& os, const Op& obj) -> std::ostream& { 38 | return os << obj.toString(); // Using toString() method 39 | } 40 | 41 | /// Checks if the operation is of the given type. 42 | /// @tparam T The type to check for. 43 | /// @return True if the operation is of the given type, false otherwise. 44 | template <class T> [[nodiscard]] auto is() const -> bool { 45 | return dynamic_cast<const T*>(this) != nullptr; 46 | } 47 | 48 | /// Casts the operation to the given type. 49 | /// @tparam T The type to cast to. 50 | /// @return A reference to the operation as the given type. 51 | template <class T> [[nodiscard]] auto as() -> T& { 52 | return dynamic_cast<T&>(*this); 53 | } 54 | 55 | /// Casts the operation to the given type. 56 | /// @tparam T The type to cast to. 57 | /// @return A const reference to the operation as the given type. 58 | template <class T> [[nodiscard]] auto as() const -> const T& { 59 | return dynamic_cast<const T&>(*this); 60 | } 61 | }; 62 | } // namespace na 63 | -------------------------------------------------------------------------------- /include/mqt-core/na/operations/ShuttlingOp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** @file 12 | * @brief Defines a base class for representing shuttling operations. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "na/entities/Atom.hpp" 18 | #include "na/entities/Location.hpp" 19 | #include "na/operations/Op.hpp" 20 | 21 | #include <utility> 22 | #include <vector> 23 | 24 | namespace na { 25 | /// Represents a shuttling operation in the NAComputation. 26 | /// @details A shuttling operation is the super class for all shuttling-related 27 | /// operations, i.e., load, store, and move operations. 28 | class ShuttlingOp : public Op { 29 | protected: 30 | /// The atoms the operation is applied to. 31 | std::vector<const Atom*> atoms_; 32 | 33 | /// Creates a new shuttling operation with the given atoms. 34 | /// @param atoms The atoms the operation is applied to. 35 | explicit ShuttlingOp(std::vector<const Atom*> atoms) 36 | : atoms_(std::move(atoms)) {} 37 | 38 | public: 39 | ShuttlingOp() = delete; 40 | 41 | /// Returns the atoms the operation is applied to. 42 | [[nodiscard]] auto getAtoms() const -> auto& { return atoms_; } 43 | 44 | /// Returns whether the shuttling operation has target locations set. 45 | [[nodiscard]] virtual auto hasTargetLocations() const -> bool = 0; 46 | 47 | /// Returns the target locations of the shuttling operation. 48 | [[nodiscard]] virtual auto getTargetLocations() const 49 | -> const std::vector<Location>& = 0; 50 | }; 51 | } // namespace na 52 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/Exception.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "Statement.hpp" 14 | 15 | #include <exception> 16 | #include <memory> 17 | #include <sstream> 18 | #include <string> 19 | #include <utility> 20 | 21 | namespace qasm3 { 22 | class CompilerError final : public std::exception { 23 | public: 24 | std::string message; 25 | std::shared_ptr<DebugInfo> debugInfo; 26 | mutable std::string cachedMessage; 27 | 28 | CompilerError(std::string msg, std::shared_ptr<DebugInfo> debug) 29 | : message(std::move(msg)), debugInfo(std::move(debug)) {} 30 | 31 | [[nodiscard]] std::string toString() const { 32 | std::stringstream ss{}; 33 | ss << debugInfo->toString(); 34 | 35 | auto parentDebugInfo = debugInfo->parent; 36 | while (parentDebugInfo != nullptr) { 37 | ss << "\n (included from " << parentDebugInfo->toString() << ")"; 38 | parentDebugInfo = parentDebugInfo->parent; 39 | } 40 | 41 | ss << ":\n" << message; 42 | 43 | return ss.str(); 44 | } 45 | 46 | [[nodiscard]] const char* what() const noexcept override { 47 | cachedMessage = toString(); 48 | return cachedMessage.c_str(); 49 | } 50 | }; 51 | 52 | class ConstEvalError final : public std::exception { 53 | public: 54 | std::string message; 55 | mutable std::string cachedMessage; 56 | 57 | explicit ConstEvalError(std::string msg) : message(std::move(msg)) {} 58 | 59 | [[nodiscard]] std::string toString() const { 60 | return "Constant Evaluation: " + message; 61 | } 62 | 63 | [[nodiscard]] const char* what() const noexcept override { 64 | cachedMessage = toString(); 65 | return cachedMessage.c_str(); 66 | } 67 | }; 68 | 69 | class TypeCheckError final : public std::exception { 70 | public: 71 | std::string message; 72 | mutable std::string cachedMessage; 73 | 74 | explicit TypeCheckError(std::string msg) : message(std::move(msg)) {} 75 | 76 | [[nodiscard]] std::string toString() const { 77 | return "Type Check Error: " + message; 78 | } 79 | 80 | [[nodiscard]] const char* what() const noexcept override { 81 | cachedMessage = toString(); 82 | return cachedMessage.c_str(); 83 | } 84 | }; 85 | } // namespace qasm3 86 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/Gate.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "Statement_fwd.hpp" 14 | #include "ir/operations/OpType.hpp" 15 | 16 | #include <cstddef> 17 | #include <memory> 18 | #include <string> 19 | #include <utility> 20 | #include <vector> 21 | 22 | namespace qasm3 { 23 | struct GateInfo { 24 | size_t nControls; 25 | size_t nTargets; 26 | size_t nParameters; 27 | qc::OpType type; 28 | }; 29 | 30 | struct Gate { 31 | virtual ~Gate() = default; 32 | 33 | virtual size_t getNControls() = 0; 34 | virtual size_t getNTargets() = 0; 35 | virtual size_t getNParameters() = 0; 36 | }; 37 | 38 | struct StandardGate final : Gate { 39 | GateInfo info; 40 | 41 | explicit StandardGate(const GateInfo& gateInfo) : info(gateInfo) {} 42 | 43 | size_t getNControls() override { return info.nControls; } 44 | 45 | size_t getNTargets() override { return info.nTargets; } 46 | size_t getNParameters() override { return info.nParameters; } 47 | }; 48 | 49 | struct CompoundGate final : Gate { 50 | std::vector<std::string> parameterNames; 51 | std::vector<std::string> targetNames; 52 | std::vector<std::shared_ptr<QuantumStatement>> body; 53 | 54 | explicit CompoundGate( 55 | std::vector<std::string> parameters, std::vector<std::string> targets, 56 | std::vector<std::shared_ptr<QuantumStatement>> bodyStatements) 57 | : parameterNames(std::move(parameters)), targetNames(std::move(targets)), 58 | body(std::move(bodyStatements)) {} 59 | 60 | size_t getNControls() override { return 0; } 61 | 62 | size_t getNTargets() override { return targetNames.size(); } 63 | size_t getNParameters() override { return parameterNames.size(); } 64 | }; 65 | } // namespace qasm3 66 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/NestedEnvironment.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <map> 14 | #include <optional> 15 | #include <string> 16 | #include <vector> 17 | 18 | namespace qasm3 { 19 | template <typename T> class NestedEnvironment { 20 | std::vector<std::map<std::string, T>> env{}; 21 | 22 | public: 23 | NestedEnvironment() { env.emplace_back(); }; 24 | 25 | void push() { env.emplace_back(); } 26 | 27 | void pop() { env.pop_back(); } 28 | 29 | std::optional<T> find(std::string key) { 30 | for (auto it = env.rbegin(); it != env.rend(); ++it) { 31 | auto found = it->find(key); 32 | if (found != it->end()) { 33 | return found->second; 34 | } 35 | } 36 | return std::nullopt; 37 | } 38 | 39 | void emplace(std::string key, T value) { env.back().emplace(key, value); } 40 | }; 41 | } // namespace qasm3 42 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/Scanner.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "Token.hpp" 14 | 15 | #include <cstddef> 16 | #include <cstdint> 17 | #include <iosfwd> 18 | #include <optional> 19 | #include <string> 20 | #include <unordered_map> 21 | 22 | namespace qasm3 { 23 | class Scanner { 24 | std::istream* is; 25 | std::unordered_map<std::string, Token::Kind> keywords; 26 | char ch = 0; 27 | size_t line = 1; 28 | size_t col = 0; 29 | 30 | [[nodiscard]] static bool isSpace(char c); 31 | 32 | [[nodiscard]] static bool isFirstIdChar(char c); 33 | 34 | [[nodiscard]] static bool isNum(char c); 35 | 36 | [[nodiscard]] static bool isHex(char c); 37 | 38 | [[nodiscard]] static bool hasTimingSuffix(char first, char second); 39 | 40 | static char readUtf8Codepoint(std::istream* in); 41 | 42 | void nextCh(); 43 | 44 | [[nodiscard]] char peek() const; 45 | 46 | std::optional<Token> consumeWhitespaceAndComments(); 47 | 48 | static bool isValidDigit(uint8_t base, char c); 49 | 50 | std::string consumeNumberLiteral(uint8_t base); 51 | 52 | static uint64_t parseIntegerLiteral(const std::string& str, uint8_t base); 53 | 54 | Token consumeNumberLiteral(); 55 | 56 | Token consumeHardwareQubit(); 57 | 58 | Token consumeString(); 59 | 60 | Token consumeName(); 61 | 62 | void error(const std::string& msg) const; 63 | 64 | void expect(char expected); 65 | 66 | public: 67 | explicit Scanner(std::istream* in); 68 | 69 | ~Scanner() = default; 70 | 71 | Token next(); 72 | }; 73 | } // namespace qasm3 74 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/Statement_fwd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | namespace qasm3 { 14 | struct DebugInfo; 15 | class Statement; 16 | class IfStatement; 17 | class IdentifierList; 18 | class MeasureExpression; 19 | class GateCallStatement; 20 | class GateDeclaration; 21 | class BarrierStatement; 22 | class ResetStatement; 23 | class AssignmentStatement; 24 | class VersionDeclaration; 25 | class DeclarationExpression; 26 | class DeclarationStatement; 27 | class IndexOperator; 28 | class IndexedIdentifier; 29 | class GateOperand; 30 | class GateModifier; 31 | class QuantumStatement; 32 | class InitialLayout; 33 | class OutputPermutation; 34 | class Expression; 35 | class Constant; 36 | class BinaryExpression; 37 | class UnaryExpression; 38 | class IdentifierExpression; 39 | } // namespace qasm3 40 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/Types_fwd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <cstdint> 14 | #include <memory> 15 | 16 | namespace qasm3 { 17 | class Expression; 18 | 19 | template <typename T> class Type; 20 | using TypeExpr = Type<std::shared_ptr<Expression>>; 21 | using ResolvedType = Type<uint64_t>; 22 | } // namespace qasm3 23 | -------------------------------------------------------------------------------- /include/mqt-core/qasm3/passes/CompilerPass.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | namespace qasm3 { 14 | class Statement; 15 | 16 | class CompilerPass { 17 | public: 18 | virtual ~CompilerPass() = default; 19 | 20 | virtual void processStatement(Statement& statement) = 0; 21 | }; 22 | } // namespace qasm3 23 | -------------------------------------------------------------------------------- /mlir/.gitignore: -------------------------------------------------------------------------------- 1 | !lib 2 | -------------------------------------------------------------------------------- /mlir/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # add a compile feature for C++17 10 | set(CMAKE_CXX_STANDARD 17) 11 | 12 | # add main library code 13 | add_subdirectory(include) 14 | add_subdirectory(lib) 15 | add_subdirectory(tools) 16 | 17 | # add test code 18 | add_subdirectory(test) 19 | -------------------------------------------------------------------------------- /mlir/include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(mlir) 10 | -------------------------------------------------------------------------------- /mlir/include/mlir/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(Dialect) 10 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(MQTOpt) 10 | add_subdirectory(MQTDyn) 11 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/Common/Compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | /** 12 | * @file 13 | * Compatibility macro for applying rewrite patterns across different MLIR 14 | * versions. 15 | * 16 | * MLIR deprecated `applyPatternsAndFoldGreedily` in version 20 and introduced 17 | * `applyPatternsGreedily` as the replacement. To maintain compatibility across 18 | * both MLIR 19 and MLIR 20+, this macro maps to the correct function 19 | * automatically based on the MLIR version used during compilation. 20 | * 21 | * Usage: 22 | * ``` 23 | * if (mlir::failed(APPLY_PATTERNS_GREEDILY(op, std::move(patterns)))) { 24 | * signalPassFailure(); 25 | * } 26 | * ``` 27 | */ 28 | 29 | #pragma once 30 | 31 | #include "mlir/Transforms/GreedyPatternRewriteDriver.h" 32 | 33 | #if MLIR_VERSION_MAJOR >= 20 34 | /// Use `applyPatternsGreedily` for MLIR >= 20 35 | #define APPLY_PATTERNS_GREEDILY(op, patterns) \ 36 | mlir::applyPatternsGreedily(op, patterns) 37 | #else 38 | /// Use `applyPatternsAndFoldGreedily` for MLIR < 20 39 | #define APPLY_PATTERNS_GREEDILY(op, patterns) \ 40 | mlir::applyPatternsAndFoldGreedily(op, patterns) 41 | #endif 42 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/Common/IR/CommonTraits.td: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | // Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | // All rights reserved. 4 | // 5 | // SPDX-License-Identifier: MIT 6 | // 7 | // Licensed under the MIT License 8 | 9 | #ifndef MQTCOMMON_TRAITS 10 | #define MQTCOMMON_TRAITS 11 | 12 | include "mlir/IR/OpBase.td" 13 | include "mlir/IR/EnumAttr.td" 14 | include "mlir/IR/DialectBase.td" 15 | include "mlir/Interfaces/SideEffectInterfaces.td" 16 | 17 | class TargetArity<int N> 18 | : ParamNativeOpTrait<"TargetArityTrait", !cast<string>(N)> { 19 | let cppNamespace = "::mqt::ir::common"; 20 | } 21 | 22 | def NoTarget : TargetArity<0>; 23 | def OneTarget : TargetArity<1>; 24 | def TwoTarget : TargetArity<2>; 25 | 26 | class ParameterArity<int N> 27 | : ParamNativeOpTrait<"ParameterArityTrait", !cast<string>(N)> { 28 | let cppNamespace = "::mqt::ir::common"; 29 | } 30 | 31 | def NoParameter : ParameterArity<0>; 32 | def OneParameter : ParameterArity<1>; 33 | def TwoParameters : ParameterArity<2>; 34 | def ThreeParameters : ParameterArity<3>; 35 | 36 | def NoControl : NativeOpTrait<"NoControlTrait"> { 37 | let cppNamespace = "::mqt::ir::common"; 38 | } 39 | 40 | def MatchingMeasureInOuts : NativeOpTrait<"MatchingMeasureInOutsTrait"> { 41 | let cppNamespace = "::mqt::ir::common"; 42 | } 43 | 44 | def UniqueSizeDefinition : NativeOpTrait<"UniqueSizeDefinitionTrait"> { 45 | let cppNamespace = "::mqt::ir::common"; 46 | } 47 | 48 | def UniqueIndexDefinition : NativeOpTrait<"UniqueIndexDefinitionTrait"> { 49 | let cppNamespace = "::mqt::ir::common"; 50 | } 51 | 52 | #endif // MQTCOMMON_TRAITS 53 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTDyn/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(IR) 10 | add_subdirectory(Transforms) 11 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTDyn/IR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | set(DIALECT_NAME "MQTDYN") 10 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../Common/IR/StdOps.td.inc 11 | ${CMAKE_CURRENT_BINARY_DIR}/MQTDynStdOps.td @ONLY) 12 | 13 | add_mlir_dialect(MQTDynOps mqtdyn) 14 | add_mlir_interface(MQTDynInterfaces) 15 | add_mlir_doc(MQTDynOps MLIRMQTDynDialect Dialects/ -gen-dialect-doc) 16 | add_mlir_doc(MQTDynInterfaces MLIRMQTDynInterfaces Dialects/ -gen-op-interface-docs) 17 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTDyn/IR/MQTDynDialect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <mlir/Bytecode/BytecodeOpInterface.h> 14 | #include <mlir/IR/BuiltinAttributes.h> 15 | #include <mlir/IR/OpDefinition.h> 16 | #include <mlir/Interfaces/SideEffectInterfaces.h> 17 | 18 | #define DIALECT_NAME_MQTDYN "mqtdyn" 19 | 20 | //===----------------------------------------------------------------------===// 21 | // Dialect 22 | //===----------------------------------------------------------------------===// 23 | 24 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOpsDialect.h.inc" // IWYU pragma: export 25 | 26 | //===----------------------------------------------------------------------===// 27 | // Types 28 | //===----------------------------------------------------------------------===// 29 | 30 | #define GET_TYPEDEF_CLASSES 31 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOpsTypes.h.inc" // IWYU pragma: export 32 | 33 | //===----------------------------------------------------------------------===// 34 | // Interfaces 35 | //===----------------------------------------------------------------------===// 36 | 37 | #include "mlir/Dialect/Common/IR/CommonTraits.h" // IWYU pragma: export 38 | #include "mlir/Dialect/MQTDyn/IR/MQTDynInterfaces.h.inc" // IWYU pragma: export 39 | 40 | //===----------------------------------------------------------------------===// 41 | // Operations 42 | //===----------------------------------------------------------------------===// 43 | 44 | #define GET_OP_CLASSES 45 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOps.h.inc" // IWYU pragma: export 46 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTDyn/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | set(LLVM_TARGET_DEFINITIONS Passes.td) 10 | mlir_tablegen(Passes.h.inc -gen-pass-decls -name MQTDyn) 11 | add_public_tablegen_target(MLIRMQTDynTransformsIncGen) 12 | add_mlir_doc(MQTDynPasses MLIRMQTDynPasses Passes/ -gen-pass-doc) 13 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTDyn/Transforms/Passes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <mlir/Pass/Pass.h> 14 | 15 | namespace mlir { 16 | 17 | class RewritePatternSet; 18 | 19 | } // namespace mlir 20 | 21 | namespace mqt::ir::dyn { 22 | 23 | #define GEN_PASS_DECL 24 | #include "mlir/Dialect/MQTDyn/Transforms/Passes.h.inc" // IWYU pragma: export 25 | 26 | void populateConstantFoldExtractQubitPatterns( 27 | mlir::RewritePatternSet& patterns); 28 | 29 | //===----------------------------------------------------------------------===// 30 | // Registration 31 | //===----------------------------------------------------------------------===// 32 | 33 | /// Generate the code for registering passes. 34 | #define GEN_PASS_REGISTRATION 35 | #include "mlir/Dialect/MQTDyn/Transforms/Passes.h.inc" // IWYU pragma: export 36 | } // namespace mqt::ir::dyn 37 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTDyn/Transforms/Passes.td: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | // Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | // All rights reserved. 4 | // 5 | // SPDX-License-Identifier: MIT 6 | // 7 | // Licensed under the MIT License 8 | 9 | #ifndef MQTD_PASSES 10 | #define MQTD_PASSES 11 | 12 | include "mlir/Pass/PassBase.td" 13 | 14 | def ConstantFolding : Pass<"constant-folding", "mlir::ModuleOp"> { 15 | let summary = "This pass performs constant folding for several operands that might also be added as static arguments"; 16 | let description = [{ 17 | This pass transforms constants that are passed to mqtdyn operations as operands into static arguments. 18 | 19 | It is currently compatible with: 20 | - mqtdyn.extractQubit 21 | }]; 22 | } 23 | 24 | #endif // MQTD_PASSES 25 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTOpt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(IR) 10 | add_subdirectory(Transforms) 11 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTOpt/IR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | set(DIALECT_NAME "MQTOPT") 10 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../Common/IR/StdOps.td.inc 11 | ${CMAKE_CURRENT_BINARY_DIR}/MQTOptStdOps.td @ONLY) 12 | 13 | add_mlir_dialect(MQTOptOps mqtopt) 14 | add_mlir_interface(MQTOptInterfaces) 15 | add_mlir_doc(MQTOptOps MLIRMQTOptDialect Dialects/ -gen-dialect-doc) 16 | add_mlir_doc(MQTOptInterfaces MLIRMQTOptInterfaces Dialects/ -gen-op-interface-docs) 17 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTOpt/IR/MQTOptDialect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include <mlir/Bytecode/BytecodeOpInterface.h> 14 | 15 | #define DIALECT_NAME_MQTOPT "mqtopt" 16 | 17 | //===----------------------------------------------------------------------===// 18 | // Dialect 19 | //===----------------------------------------------------------------------===// 20 | 21 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOpsDialect.h.inc" // IWYU pragma: export 22 | 23 | //===----------------------------------------------------------------------===// 24 | // Types 25 | //===----------------------------------------------------------------------===// 26 | 27 | #define GET_TYPEDEF_CLASSES 28 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOpsTypes.h.inc" // IWYU pragma: export 29 | 30 | //===----------------------------------------------------------------------===// 31 | // Interfaces 32 | //===----------------------------------------------------------------------===// 33 | 34 | #include "mlir/Dialect/Common/IR/CommonTraits.h" // IWYU pragma: export 35 | #include "mlir/Dialect/MQTOpt/IR/MQTOptInterfaces.h.inc" // IWYU pragma: export 36 | 37 | //===----------------------------------------------------------------------===// 38 | // Operations 39 | //===----------------------------------------------------------------------===// 40 | 41 | #define GET_OP_CLASSES 42 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOps.h.inc" // IWYU pragma: export 43 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTOpt/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | set(LLVM_TARGET_DEFINITIONS Passes.td) 10 | mlir_tablegen(Passes.h.inc -gen-pass-decls -name MQTOpt) 11 | add_public_tablegen_target(MLIRMQTOptTransformsIncGen) 12 | add_mlir_doc(MQTOptPasses MLIRMQTOptPasses Passes/ -gen-pass-doc) 13 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTOpt/Transforms/Passes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ir/QuantumComputation.hpp" 14 | 15 | #include <mlir/Pass/Pass.h> 16 | 17 | namespace mlir { 18 | 19 | class RewritePatternSet; 20 | 21 | } // namespace mlir 22 | 23 | namespace mqt::ir::opt { 24 | 25 | #define GEN_PASS_DECL 26 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h.inc" // IWYU pragma: export 27 | 28 | void populateCancelInversesPatterns(mlir::RewritePatternSet& patterns); 29 | void populateQuantumSinkShiftPatterns(mlir::RewritePatternSet& patterns); 30 | void populateQuantumSinkPushPatterns(mlir::RewritePatternSet& patterns); 31 | void populateToQuantumComputationPatterns(mlir::RewritePatternSet& patterns, 32 | qc::QuantumComputation& circuit); 33 | void populateFromQuantumComputationPatterns(mlir::RewritePatternSet& patterns, 34 | qc::QuantumComputation& circuit); 35 | 36 | //===----------------------------------------------------------------------===// 37 | // Registration 38 | //===----------------------------------------------------------------------===// 39 | 40 | /// Generate the code for registering passes. 41 | #define GEN_PASS_REGISTRATION 42 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h.inc" // IWYU pragma: export 43 | } // namespace mqt::ir::opt 44 | -------------------------------------------------------------------------------- /mlir/include/mlir/Dialect/MQTOpt/Transforms/Passes.td: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | // Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | // All rights reserved. 4 | // 5 | // SPDX-License-Identifier: MIT 6 | // 7 | // Licensed under the MIT License 8 | 9 | #ifndef MQTO_PASSES 10 | #define MQTO_PASSES 11 | 12 | include "mlir/Pass/PassBase.td" 13 | 14 | def MQTCoreRoundTrip : Pass<"mqt-core-round-trip", "mlir::ModuleOp"> { 15 | let summary = "This pass performs a round trip to MQT Core's QuantumComputation and back"; 16 | let description = [{ 17 | This pass starts by extracting all quantum-computation-relevant operations and then 18 | translates them into an MQT Core quantum computation, deleting all quantum operations 19 | in the process. Then, the quantum computation is read in a second pattern and used 20 | to generate new MLIR code from it. 21 | 22 | This pass makes the following assumptions: 23 | - Each module consists of a single function that uses `mqtopt` operations with just a single qubit register. 24 | - All qubits are measured exactly once and the boolean measurement results are returned from the function in order. 25 | - The first returned value is the `AllocOp` that constructs a qubit register. 26 | - Measurements/Operations may only target a single qubit. Unitary operations may also use any number of (positive) controls. 27 | - Supported operations are `x`, `y`, `z`, `h`, and `measure`. 28 | }]; 29 | } 30 | 31 | def CancelConsecutiveInverses : Pass<"cancel-consecutive-inverses", "mlir::ModuleOp"> { 32 | let summary = "This pass searches for consecutive applications of gates and their inverses and cancels them."; 33 | let description = [{ 34 | This pass searches for applications of gates that are their own inverses. Walking down their def-use chain, 35 | it then checks if the same gate is applied once again. In that case, the two gates are cancelled. 36 | }]; 37 | } 38 | 39 | def QuantumSinkPass : Pass<"quantum-sink", "mlir::ModuleOp"> { 40 | let summary = "This pass attempts to push down operations into branches for possible optimizations."; 41 | let description = [{ 42 | This pass searches for branch instructions and attempts to push instructions from previous branches into them. 43 | }]; 44 | } 45 | 46 | #endif // MQTO_PASSES 47 | -------------------------------------------------------------------------------- /mlir/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(Dialect) 10 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(MQTOpt) 10 | add_subdirectory(MQTDyn) 11 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTDyn/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(IR) 10 | add_subdirectory(Transforms) 11 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTDyn/IR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_mlir_dialect_library(MLIRMQTDyn MQTDynOps.cpp DEPENDS MLIRMQTDynOpsIncGen 10 | MLIRMQTDynInterfacesIncGen) 11 | 12 | # collect header files 13 | file(GLOB_RECURSE IR_HEADERS ${MQT_MLIR_INCLUDE_BUILD_DIR}/mlir/Dialect/MQTDyn/IR/*.h) 14 | 15 | # add public headers using file sets 16 | target_sources(MLIRMQTDyn PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_MLIR_INCLUDE_BUILD_DIR} FILES 17 | ${IR_HEADERS}) 18 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTDyn/IR/MQTDynOps.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/MQTDyn/IR/MQTDynDialect.h" 12 | 13 | // The following headers are needed for some template instantiations. 14 | // IWYU pragma: begin_keep 15 | #include <llvm/ADT/TypeSwitch.h> 16 | #include <mlir/IR/Builders.h> 17 | #include <mlir/IR/DialectImplementation.h> 18 | // IWYU pragma: end_keep 19 | 20 | //===----------------------------------------------------------------------===// 21 | // Dialect 22 | //===----------------------------------------------------------------------===// 23 | 24 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOpsDialect.cpp.inc" 25 | 26 | void mqt::ir::dyn::MQTDynDialect::initialize() { 27 | addTypes< 28 | #define GET_TYPEDEF_LIST 29 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOpsTypes.cpp.inc" 30 | >(); 31 | 32 | addOperations< 33 | #define GET_OP_LIST 34 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOps.cpp.inc" 35 | >(); 36 | } 37 | 38 | //===----------------------------------------------------------------------===// 39 | // Types 40 | //===----------------------------------------------------------------------===// 41 | 42 | #define GET_TYPEDEF_CLASSES 43 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOpsTypes.cpp.inc" 44 | 45 | //===----------------------------------------------------------------------===// 46 | // Types 47 | //===----------------------------------------------------------------------===// 48 | 49 | #include "mlir/Dialect/MQTDyn/IR/MQTDynInterfaces.cpp.inc" 50 | 51 | //===----------------------------------------------------------------------===// 52 | // Operations 53 | //===----------------------------------------------------------------------===// 54 | 55 | #define GET_OP_CLASSES 56 | #include "mlir/Dialect/MQTDyn/IR/MQTDynOps.cpp.inc" 57 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTDyn/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 10 | set(LIBRARIES ${dialect_libs}) 11 | add_compile_options(-fexceptions) 12 | 13 | file(GLOB TRANSFORMS_SOURCES *.cpp) 14 | 15 | add_mlir_library(MLIRMQTDynTransforms ${TRANSFORMS_SOURCES} LINK_LIBS ${LIBRARIES} DEPENDS 16 | MLIRMQTDynTransformsIncGen) 17 | 18 | # collect header files 19 | file(GLOB_RECURSE TRANSFORMS_HEADERS 20 | ${MQT_MLIR_INCLUDE_BUILD_DIR}/mlir/Dialect/MQTDyn/Transforms/*.h) 21 | 22 | # add public headers using file sets 23 | target_sources(MLIRMQTDynTransforms PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_MLIR_INCLUDE_BUILD_DIR} 24 | FILES ${TRANSFORMS_HEADERS}) 25 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTDyn/Transforms/ConstantFoldExtractQubitPattern.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/MQTDyn/IR/MQTDynDialect.h" 12 | #include "mlir/Dialect/MQTDyn/Transforms/Passes.h" 13 | 14 | #include <mlir/Dialect/Arith/IR/Arith.h> 15 | #include <mlir/IR/MLIRContext.h> 16 | #include <mlir/IR/PatternMatch.h> 17 | #include <mlir/Support/LLVM.h> 18 | #include <mlir/Support/LogicalResult.h> 19 | 20 | namespace mqt::ir::dyn { 21 | 22 | /** 23 | * @brief This pattern attempts to fold constants of `mqtdyn.extractQubit` 24 | * operations. 25 | */ 26 | struct ConstantFoldExtractQubitPattern final 27 | : mlir::OpRewritePattern<ExtractOp> { 28 | 29 | explicit ConstantFoldExtractQubitPattern(mlir::MLIRContext* context) 30 | : OpRewritePattern(context) {} 31 | 32 | mlir::LogicalResult match(ExtractOp op) const override { 33 | auto index = op.getIndex(); 34 | if (!index) { 35 | return mlir::failure(); 36 | } 37 | auto* definition = index.getDefiningOp(); 38 | if (!mlir::isa<mlir::arith::ConstantOp>(definition)) { 39 | return mlir::failure(); 40 | } 41 | return mlir::success(); 42 | } 43 | 44 | void rewrite(ExtractOp op, mlir::PatternRewriter& rewriter) const override { 45 | auto index = op.getIndex(); 46 | auto definition = 47 | mlir::cast<mlir::arith::ConstantOp>(index.getDefiningOp()); 48 | auto value = mlir::cast<mlir::IntegerAttr>(definition.getValue()).getInt(); 49 | rewriter.replaceOpWithNewOp<ExtractOp>(op, op.getOutQubit().getType(), 50 | op.getInQreg(), mlir::Value(), 51 | rewriter.getI64IntegerAttr(value)); 52 | } 53 | }; 54 | 55 | /** 56 | * @brief Populates the given pattern set with the 57 | * `ConstantFoldExtractQubitPattern`. 58 | * 59 | * @param patterns The pattern set to populate. 60 | */ 61 | void populateConstantFoldExtractQubitPatterns( 62 | mlir::RewritePatternSet& patterns) { 63 | patterns.add<ConstantFoldExtractQubitPattern>(patterns.getContext()); 64 | } 65 | 66 | } // namespace mqt::ir::dyn 67 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTDyn/Transforms/ConstantFolding.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/Common/Compat.h" 12 | #include "mlir/Dialect/MQTDyn/Transforms/Passes.h" 13 | 14 | #include <mlir/IR/PatternMatch.h> 15 | #include <mlir/Support/LLVM.h> 16 | #include <utility> 17 | 18 | namespace mqt::ir::dyn { 19 | 20 | #define GEN_PASS_DEF_CONSTANTFOLDING 21 | #include "mlir/Dialect/MQTDyn/Transforms/Passes.h.inc" 22 | 23 | /** 24 | * @brief This pass attempts to perform constant folding for some `mqtdyn` 25 | * operations. 26 | */ 27 | struct ConstantFolding final : impl::ConstantFoldingBase<ConstantFolding> { 28 | 29 | void runOnOperation() override { 30 | // Get the current operation being operated on. 31 | auto op = getOperation(); 32 | auto* ctx = &getContext(); 33 | 34 | // Define the set of patterns to use. 35 | mlir::RewritePatternSet patterns(ctx); 36 | populateConstantFoldExtractQubitPatterns(patterns); 37 | 38 | // Apply patterns in an iterative and greedy manner. 39 | if (mlir::failed(APPLY_PATTERNS_GREEDILY(op, std::move(patterns)))) { 40 | signalPassFailure(); 41 | } 42 | } 43 | }; 44 | 45 | } // namespace mqt::ir::dyn 46 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(IR) 10 | add_subdirectory(Transforms) 11 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/IR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_mlir_dialect_library(MLIRMQTOpt MQTOptOps.cpp DEPENDS MLIRMQTOptOpsIncGen 10 | MLIRMQTOptInterfacesIncGen) 11 | 12 | # collect header files 13 | file(GLOB_RECURSE IR_HEADERS ${MQT_MLIR_INCLUDE_BUILD_DIR}/mlir/Dialect/MQTOpt/IR/*.h) 14 | 15 | # add public headers using file sets 16 | target_sources(MLIRMQTOpt PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_MLIR_INCLUDE_BUILD_DIR} FILES 17 | ${IR_HEADERS}) 18 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/IR/MQTOptOps.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/MQTOpt/IR/MQTOptDialect.h" // IWYU pragma: associated 12 | 13 | // The following headers are needed for some template instantiations. 14 | // IWYU pragma: begin_keep 15 | #include <llvm/ADT/TypeSwitch.h> 16 | #include <mlir/IR/Builders.h> 17 | #include <mlir/IR/DialectImplementation.h> 18 | // IWYU pragma: end_keep 19 | 20 | //===----------------------------------------------------------------------===// 21 | // Dialect 22 | //===----------------------------------------------------------------------===// 23 | 24 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOpsDialect.cpp.inc" 25 | 26 | void mqt::ir::opt::MQTOptDialect::initialize() { 27 | // NOLINTNEXTLINE(clang-analyzer-core.StackAddressEscape) 28 | addTypes< 29 | #define GET_TYPEDEF_LIST 30 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOpsTypes.cpp.inc" 31 | >(); 32 | 33 | addOperations< 34 | #define GET_OP_LIST 35 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOps.cpp.inc" 36 | >(); 37 | } 38 | 39 | //===----------------------------------------------------------------------===// 40 | // Types 41 | //===----------------------------------------------------------------------===// 42 | 43 | #define GET_TYPEDEF_CLASSES 44 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOpsTypes.cpp.inc" 45 | 46 | //===----------------------------------------------------------------------===// 47 | // Interfaces 48 | //===----------------------------------------------------------------------===// 49 | 50 | #include "mlir/Dialect/MQTOpt/IR/MQTOptInterfaces.cpp.inc" 51 | 52 | //===----------------------------------------------------------------------===// 53 | // Operations 54 | //===----------------------------------------------------------------------===// 55 | 56 | #define GET_OP_CLASSES 57 | #include "mlir/Dialect/MQTOpt/IR/MQTOptOps.cpp.inc" 58 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 10 | set(LIBRARIES ${dialect_libs} MQT::CoreIR) 11 | add_compile_options(-fexceptions) 12 | 13 | file(GLOB TRANSFORMS_SOURCES *.cpp) 14 | 15 | add_mlir_library(MLIRMQTOptTransforms ${TRANSFORMS_SOURCES} LINK_LIBS ${LIBRARIES} DEPENDS 16 | MLIRMQTOptTransformsIncGen) 17 | 18 | # collect header files 19 | file(GLOB_RECURSE TRANSFORMS_HEADERS 20 | ${MQT_MLIR_INCLUDE_BUILD_DIR}/mlir/Dialect/MQTOpt/Transforms/*.h) 21 | 22 | # add public headers using file sets 23 | target_sources(MLIRMQTOptTransforms PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_MLIR_INCLUDE_BUILD_DIR} 24 | FILES ${TRANSFORMS_HEADERS}) 25 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/Transforms/CancelConsecutiveInverses.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/Common/Compat.h" 12 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h" 13 | 14 | #include <mlir/IR/PatternMatch.h> 15 | #include <mlir/Support/LLVM.h> 16 | #include <utility> 17 | 18 | namespace mqt::ir::opt { 19 | 20 | #define GEN_PASS_DEF_CANCELCONSECUTIVEINVERSES 21 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h.inc" 22 | 23 | /** 24 | * @brief This pass attempts to cancel consecutive self-inverse operations. 25 | */ 26 | struct CancelConsecutiveInverses final 27 | : impl::CancelConsecutiveInversesBase<CancelConsecutiveInverses> { 28 | 29 | void runOnOperation() override { 30 | // Get the current operation being operated on. 31 | auto op = getOperation(); 32 | auto* ctx = &getContext(); 33 | 34 | // Define the set of patterns to use. 35 | mlir::RewritePatternSet patterns(ctx); 36 | populateCancelInversesPatterns(patterns); 37 | 38 | // Apply patterns in an iterative and greedy manner. 39 | if (mlir::failed(APPLY_PATTERNS_GREEDILY(op, std::move(patterns)))) { 40 | signalPassFailure(); 41 | } 42 | } 43 | }; 44 | 45 | } // namespace mqt::ir::opt 46 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/Transforms/MQTCoreRoundTrip.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "ir/QuantumComputation.hpp" 12 | #include "mlir/Dialect/Common/Compat.h" 13 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h" 14 | 15 | #include <mlir/IR/PatternMatch.h> 16 | #include <mlir/Support/LLVM.h> 17 | #include <utility> 18 | 19 | namespace mqt::ir::opt { 20 | 21 | #define GEN_PASS_DEF_MQTCOREROUNDTRIP 22 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h.inc" 23 | 24 | struct MQTCoreRoundTrip final : impl::MQTCoreRoundTripBase<MQTCoreRoundTrip> { 25 | 26 | qc::QuantumComputation circuit; 27 | 28 | void runOnOperation() override { 29 | // Get the current operation being operated on. 30 | auto op = getOperation(); 31 | auto* ctx = &getContext(); 32 | 33 | // Define the set of patterns to use. 34 | mlir::RewritePatternSet patterns(ctx); 35 | populateToQuantumComputationPatterns(patterns, circuit); 36 | populateFromQuantumComputationPatterns(patterns, circuit); 37 | 38 | // Apply patterns in an iterative and greedy manner. 39 | if (mlir::failed(APPLY_PATTERNS_GREEDILY(op, std::move(patterns)))) { 40 | signalPassFailure(); 41 | } 42 | } 43 | }; 44 | 45 | } // namespace mqt::ir::opt 46 | -------------------------------------------------------------------------------- /mlir/lib/Dialect/MQTOpt/Transforms/QuantumSinkPass.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/Common/Compat.h" 12 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h" 13 | 14 | #include <mlir/IR/PatternMatch.h> 15 | #include <mlir/Support/LLVM.h> 16 | #include <utility> 17 | 18 | namespace mqt::ir::opt { 19 | 20 | #define GEN_PASS_DEF_QUANTUMSINKPASS 21 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h.inc" 22 | 23 | /** 24 | * @brief This pass attempty to sink quantum operations into the block where 25 | * their results are used. 26 | */ 27 | struct QuantumSinkPass final : impl::QuantumSinkPassBase<QuantumSinkPass> { 28 | 29 | void runOnOperation() override { 30 | // Get the current operation being operated on. 31 | auto op = getOperation(); 32 | auto* ctx = &getContext(); 33 | 34 | // Define the set of patterns to use. 35 | mlir::RewritePatternSet patterns(ctx); 36 | populateQuantumSinkShiftPatterns(patterns); 37 | populateQuantumSinkPushPatterns(patterns); 38 | 39 | // Apply patterns in an iterative and greedy manner. 40 | if (mlir::failed(APPLY_PATTERNS_GREEDILY(op, std::move(patterns)))) { 41 | signalPassFailure(); 42 | } 43 | } 44 | }; 45 | 46 | } // namespace mqt::ir::opt 47 | -------------------------------------------------------------------------------- /mlir/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | configure_lit_site_cfg( 10 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in 11 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py 12 | MAIN_CONFIG 13 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py 14 | DEPENDS 15 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in 16 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py) 17 | 18 | set(QUANTUM_OPT_TEST_DEPENDS FileCheck count not quantum-opt) 19 | 20 | add_lit_testsuite(check-quantum-opt "Running the quantum-opt regression tests" 21 | ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${QUANTUM_OPT_TEST_DEPENDS}) 22 | set_target_properties(check-quantum-opt PROPERTIES FOLDER "Tests" EXCLUDE_FROM_ALL ON) 23 | 24 | add_lit_testsuites(QUANTUM_OPT ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${QUANTUM_OPT_TEST_DEPENDS}) 25 | -------------------------------------------------------------------------------- /mlir/test/Dialect/MQTDyn/IR/bell_state_reference_dialect.mlir: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | // Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | // All rights reserved. 4 | // 5 | // SPDX-License-Identifier: MIT 6 | // 7 | // Licensed under the MIT License 8 | 9 | // RUN: quantum-opt %s | FileCheck %s 10 | 11 | module { 12 | // CHECK-LABEL: func @bell_state() 13 | func.func @bell_state() -> (i1, i1) { 14 | %r0 = "mqtdyn.allocQubitRegister" () {"size_attr" = 2 : i64} : () -> !mqtdyn.QubitRegister 15 | %q0 = "mqtdyn.extractQubit" (%r0) {"index_attr" = 0 : i64} : (!mqtdyn.QubitRegister) -> !mqtdyn.Qubit 16 | 17 | %i = arith.constant 0 : i64 18 | %q1 = "mqtdyn.extractQubit" (%r0, %i) : (!mqtdyn.QubitRegister, i64) -> !mqtdyn.Qubit 19 | 20 | mqtdyn.x () %q0 21 | mqtdyn.x () %q1 ctrl %q0 22 | 23 | %c0 = "mqtdyn.measure" (%q0) : (!mqtdyn.Qubit) -> i1 24 | %c1 = "mqtdyn.measure" (%q1) : (!mqtdyn.Qubit) -> i1 25 | 26 | 27 | "mqtdyn.deallocQubitRegister" (%r0) : (!mqtdyn.QubitRegister) -> () 28 | 29 | return %c0, %c1 : i1, i1 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mlir/test/Dialect/MQTDyn/Transforms/constant-folding.mlir: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | // Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | // All rights reserved. 4 | // 5 | // SPDX-License-Identifier: MIT 6 | // 7 | // Licensed under the MIT License 8 | 9 | // RUN: quantum-opt %s -split-input-file --constant-folding | FileCheck %s 10 | 11 | 12 | // ----- 13 | // Tests that constant indices passed to `mqtdyn.extractQubit` are transformed into static attributes correctly. 14 | 15 | module { 16 | // CHECK-LABEL: @foldExtractQubitIndex 17 | func.func @foldExtractQubitIndex() { 18 | // CHECK: %[[Reg_0:.*]] = "mqtdyn.allocQubitRegister"() <{size_attr = 1 : i64}> 19 | %r0 = "mqtdyn.allocQubitRegister"() <{size_attr = 1 : i64}> : () -> !mqtdyn.QubitRegister 20 | 21 | %i = arith.constant 0 : i64 22 | %q0 = "mqtdyn.extractQubit"(%r0, %i) : (!mqtdyn.QubitRegister, i64) -> !mqtdyn.Qubit 23 | // CHECK-NOT: arith.constant 24 | // CHECK: %[[Q0:.*]] = "mqtdyn.extractQubit"(%[[Reg_0]]) <{index_attr = 0 : i64}> : (!mqtdyn.QubitRegister) -> !mqtdyn.Qubit 25 | 26 | // CHECK: mqtdyn.x() %[[Q0]] 27 | mqtdyn.x () %q0 28 | return 29 | } 30 | } 31 | 32 | 33 | // ----- 34 | // Tests that nothing is done with `mqtdyn.extractQubit` if index is already given as an attribute. 35 | 36 | module { 37 | // CHECK-LABEL: @extractQubitIndexDoNothing 38 | func.func @extractQubitIndexDoNothing() { 39 | // CHECK: %[[Reg_0:.*]] = "mqtdyn.allocQubitRegister"() <{size_attr = 1 : i64}> 40 | %r0 = "mqtdyn.allocQubitRegister"() <{size_attr = 1 : i64}> : () -> !mqtdyn.QubitRegister 41 | 42 | %q0 = "mqtdyn.extractQubit"(%r0) <{index_attr = 0 : i64}> : (!mqtdyn.QubitRegister) -> !mqtdyn.Qubit 43 | // CHECK: %[[Q0:.*]] = "mqtdyn.extractQubit"(%[[Reg_0]]) <{index_attr = 0 : i64}> : (!mqtdyn.QubitRegister) -> !mqtdyn.Qubit 44 | 45 | // CHECK: mqtdyn.x() %[[Q0]] 46 | mqtdyn.x () %q0 47 | return 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mlir/test/lit.cfg.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # ruff: noqa: INP001 10 | 11 | """LIT Configuration file for the MQT MLIR test suite. 12 | 13 | This file configures the LLVM LIT testing infrastructure for MLIR dialect tests. 14 | """ 15 | 16 | from __future__ import annotations 17 | 18 | from pathlib import Path 19 | 20 | import lit.formats 21 | from lit.llvm import llvm_config 22 | 23 | # Use `lit_config` to access `config` from lit.site.cfg.py 24 | config = globals().get("config") 25 | if config is None: 26 | msg = "LIT config object is missing. Ensure lit.site.cfg.py is loaded first." 27 | raise RuntimeError(msg) 28 | 29 | config.name = "MQT MLIR test suite" 30 | config.test_format = lit.formats.ShTest(execute_external=True) 31 | 32 | # Define the file extensions to treat as test files. 33 | config.suffixes = [".mlir"] 34 | config.excludes = ["lit.cfg.py"] 35 | 36 | # Define the root path of where to look for tests. 37 | config.test_source_root = Path(__file__).parent 38 | 39 | # Define where to execute tests (and produce the output). 40 | config.test_exec_root = getattr(config, "quantum_test_dir", ".lit") 41 | 42 | # Define PATH to include the various tools needed for our tests. 43 | try: 44 | # From within a build target we have access to cmake variables configured in lit.site.cfg.py.in. 45 | llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True) # FileCheck 46 | llvm_config.with_environment("PATH", config.quantum_bin_dir, append_path=True) # quantum-opt 47 | except AttributeError: 48 | # The system PATH is available by default. 49 | pass 50 | -------------------------------------------------------------------------------- /mlir/test/lit.site.cfg.py.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | @LIT_SITE_CFG_IN_HEADER@ 10 | 11 | config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@") 12 | config.quantum_build_dir = "@CMAKE_BINARY_DIR@" 13 | config.quantum_test_dir = "@CMAKE_BINARY_DIR@" + "/mlir/test" 14 | config.quantum_bin_dir = "@CMAKE_BINARY_DIR@" + "/mlir/tools/quantum-opt" 15 | 16 | import lit.llvm 17 | lit.llvm.initialize(lit_config, config) 18 | 19 | # Let the main config do the real work. 20 | lit_config.load_config(config, "@CMAKE_SOURCE_DIR@/mlir/test/lit.cfg.py") 21 | -------------------------------------------------------------------------------- /mlir/tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | add_subdirectory(quantum-opt) 10 | -------------------------------------------------------------------------------- /mlir/tools/quantum-opt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 10 | get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) 11 | get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS) 12 | set(LIBS 13 | ${dialect_libs} 14 | ${conversion_libs} 15 | ${extension_libs} 16 | ${transform_libs} 17 | ${passes_libs} 18 | MLIROptLib 19 | MLIRMQTOptTransforms 20 | MLIRMQTDynTransforms) 21 | 22 | add_mlir_tool(quantum-opt quantum-opt.cpp DEPENDS ${LIBS} SUPPORT_PLUGINS) 23 | target_compile_options(quantum-opt PRIVATE -fexceptions) 24 | target_link_libraries(quantum-opt PUBLIC ${LIBS}) 25 | llvm_update_compile_flags(quantum-opt) 26 | mlir_check_all_link_libraries(quantum-opt) 27 | export_executable_symbols_for_plugins(quantum-opt) 28 | -------------------------------------------------------------------------------- /mlir/tools/quantum-opt/quantum-opt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "mlir/Dialect/MQTDyn/IR/MQTDynDialect.h" // IWYU pragma: keep 12 | #include "mlir/Dialect/MQTDyn/Transforms/Passes.h" // IWYU pragma: keep 13 | #include "mlir/Dialect/MQTOpt/IR/MQTOptDialect.h" // IWYU pragma: keep 14 | #include "mlir/Dialect/MQTOpt/Transforms/Passes.h" // IWYU pragma: keep 15 | 16 | #include <mlir/Dialect/Func/Extensions/AllExtensions.h> 17 | #include <mlir/IR/DialectRegistry.h> 18 | #include <mlir/InitAllDialects.h> 19 | #include <mlir/InitAllPasses.h> 20 | #include <mlir/Tools/mlir-opt/MlirOptMain.h> 21 | 22 | int main(const int argc, char** argv) { 23 | mlir::registerAllPasses(); 24 | mqt::ir::opt::registerMQTOptPasses(); 25 | mqt::ir::dyn::registerMQTDynPasses(); 26 | 27 | mlir::DialectRegistry registry; 28 | mlir::registerAllDialects(registry); 29 | mlir::func::registerAllExtensions(registry); 30 | registry.insert<mqt::ir::opt::MQTOptDialect>(); 31 | registry.insert<mqt::ir::dyn::MQTDynDialect>(); 32 | 33 | return mlir::asMainReturnCode( 34 | MlirOptMain(argc, argv, "Quantum optimizer driver\n", registry)); 35 | } 36 | -------------------------------------------------------------------------------- /paper/codemeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld", 3 | "@type": "Code", 4 | "author": [ 5 | { 6 | "@id": "https://orcid.org/0000-0003-4699-1316", 7 | "@type": "Person", 8 | "email": "lukas.burgholzer@tum.de", 9 | "name": "Lukas Burgholzer", 10 | "affiliation": [ 11 | "Chair for Design Automation, Technical University of Munich, Germany", 12 | "Munich Quantum Software Company GmbH, Garching near Munich, Germany" 13 | ] 14 | }, 15 | { 16 | "@id": "https://orcid.org/0000-0001-5785-2528", 17 | "@type": "Person", 18 | "email": "yannick.stade@tum.de", 19 | "name": "Yannick Stade", 20 | "affiliation": "Chair for Design Automation, Technical University of Munich, Germany" 21 | }, 22 | { 23 | "@id": "https://orcid.org/0000-0003-3434-7881", 24 | "@type": "Person", 25 | "email": "tom.peham@tum.de", 26 | "name": "Tom Peham", 27 | "affiliation": "Chair for Design Automation, Technical University of Munich, Germany" 28 | }, 29 | { 30 | "@id": "https://orcid.org/0000-0002-4993-7860", 31 | "@type": "Person", 32 | "email": "robert.wille@tum.de", 33 | "name": "Robert Wille", 34 | "affiliation": [ 35 | "Chair for Design Automation, Technical University of Munich, Germany", 36 | "Munich Quantum Software Company GmbH, Garching near Munich, Germany", 37 | "Software Competence Center Hagenberg GmbH, Hagenberg, Austria" 38 | ] 39 | } 40 | ], 41 | "identifier": "", 42 | "codeRepository": "https://github.com/munich-quantum-toolkit/core", 43 | "datePublished": "2024-11-07", 44 | "dateModified": "2024-11-07", 45 | "dateCreated": "2024-11-07", 46 | "description": "MQT Core forms the backbone of the software tools developed as part of the Munich Quantum Toolkit (MQT).", 47 | "keywords": "Python, C++, MQT, Quantum Computing, Design Automation, Intermediate Representation, Data Structures, Decision Diagrams, ZX-Calculus", 48 | "license": "MIT", 49 | "title": "MQT Core", 50 | "version": "v3.0.0" 51 | } 52 | -------------------------------------------------------------------------------- /src/algorithms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET ${MQT_CORE_TARGET_NAME}-algorithms) 10 | # collect headers and source files 11 | file(GLOB_RECURSE ALGO_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/algorithms/**.hpp) 12 | file(GLOB_RECURSE ALGO_SOURCES **.cpp) 13 | 14 | # create the library target (initially empty) 15 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-algorithms) 16 | 17 | # add sources to target 18 | target_sources(${MQT_CORE_TARGET_NAME}-algorithms PRIVATE ${ALGO_SOURCES}) 19 | 20 | # add headers using file sets 21 | target_sources( 22 | ${MQT_CORE_TARGET_NAME}-algorithms PUBLIC FILE_SET HEADERS BASE_DIRS 23 | ${MQT_CORE_INCLUDE_BUILD_DIR} FILES ${ALGO_HEADERS}) 24 | 25 | # add link libraries 26 | target_link_libraries( 27 | ${MQT_CORE_TARGET_NAME}-algorithms 28 | PUBLIC MQT::CoreIR 29 | PRIVATE MQT::CoreCircuitOptimizer MQT::ProjectOptions MQT::ProjectWarnings) 30 | 31 | # set versioning information 32 | set_target_properties( 33 | ${MQT_CORE_TARGET_NAME}-algorithms 34 | PROPERTIES VERSION ${PROJECT_VERSION} 35 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 36 | EXPORT_NAME CoreAlgorithms) 37 | 38 | # generate export header 39 | include(GenerateExportHeader) 40 | generate_export_header(${MQT_CORE_TARGET_NAME}-algorithms BASE_NAME mqt_core_algorithms) 41 | target_sources( 42 | ${MQT_CORE_TARGET_NAME}-algorithms 43 | PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. FILES 44 | ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_algorithms_export.h) 45 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 46 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-algorithms 47 | PUBLIC MQT_CORE_ALGO_STATIC_DEFINE) 48 | endif() 49 | 50 | # add to list of MQT core targets 51 | set(MQT_CORE_TARGETS 52 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-algorithms 53 | PARENT_SCOPE) 54 | endif() 55 | -------------------------------------------------------------------------------- /src/algorithms/GHZState.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "algorithms/GHZState.hpp" 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | #include <string> 17 | 18 | namespace qc { 19 | auto createGHZState(const Qubit nq) -> QuantumComputation { 20 | auto qc = QuantumComputation(nq, nq); 21 | qc.setName("ghz_" + std::to_string(nq)); 22 | 23 | const auto top = nq - 1; 24 | qc.h(top); 25 | for (Qubit i = 0; i < top; i++) { 26 | qc.cx(top, i); 27 | } 28 | return qc; 29 | } 30 | } // namespace qc 31 | -------------------------------------------------------------------------------- /src/algorithms/WState.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "algorithms/WState.hpp" 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/QuantumComputation.hpp" 15 | 16 | #include <cmath> 17 | #include <string> 18 | 19 | namespace qc { 20 | namespace { 21 | void fGate(QuantumComputation& qc, const Qubit i, const Qubit j, const Qubit k, 22 | const Qubit n) { 23 | const auto theta = std::acos(std::sqrt(1.0 / static_cast<double>(k - n + 1))); 24 | qc.ry(-theta, j); 25 | qc.cz(i, j); 26 | qc.ry(theta, j); 27 | } 28 | } // namespace 29 | 30 | auto createWState(const Qubit nq) -> QuantumComputation { 31 | auto qc = QuantumComputation(nq, nq); 32 | qc.setName("wstate_" + std::to_string(nq)); 33 | 34 | qc.x(nq - 1); 35 | 36 | for (Qubit m = 1; m < nq; m++) { 37 | fGate(qc, nq - m, nq - m - 1, nq, m); 38 | } 39 | 40 | for (Qubit k = nq - 1; k > 0; k--) { 41 | qc.cx(k - 1, k); 42 | } 43 | 44 | return qc; 45 | } 46 | } // namespace qc 47 | -------------------------------------------------------------------------------- /src/circuit_optimizer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET ${MQT_CORE_TARGET_NAME}-circuit-optimizer) 10 | # collect headers and source files 11 | file(GLOB_RECURSE CIRCUIT_OPTIMIZER_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/circuit_optimizer/*.hpp) 12 | file(GLOB_RECURSE CIRCUIT_OPTIMIZER_SOURCES **.cpp) 13 | 14 | # create the library target (initially empty) 15 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-circuit-optimizer) 16 | 17 | # add sources to target 18 | target_sources(${MQT_CORE_TARGET_NAME}-circuit-optimizer PRIVATE ${CIRCUIT_OPTIMIZER_SOURCES}) 19 | 20 | # add headers using file sets 21 | target_sources( 22 | ${MQT_CORE_TARGET_NAME}-circuit-optimizer 23 | PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} FILES 24 | ${CIRCUIT_OPTIMIZER_HEADERS}) 25 | 26 | # add link libraries 27 | target_link_libraries( 28 | ${MQT_CORE_TARGET_NAME}-circuit-optimizer 29 | PUBLIC MQT::CoreIR 30 | PRIVATE MQT::ProjectOptions MQT::ProjectWarnings) 31 | 32 | # set versioning information 33 | set_target_properties( 34 | ${MQT_CORE_TARGET_NAME}-circuit-optimizer 35 | PROPERTIES VERSION ${PROJECT_VERSION} 36 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 37 | EXPORT_NAME CoreCircuitOptimizer) 38 | 39 | # generate export header 40 | include(GenerateExportHeader) 41 | generate_export_header(${MQT_CORE_TARGET_NAME}-circuit-optimizer BASE_NAME 42 | mqt_core_circuit_optimizer) 43 | target_sources( 44 | ${MQT_CORE_TARGET_NAME}-circuit-optimizer 45 | PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. FILES 46 | ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_circuit_optimizer_export.h) 47 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 48 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-circuit-optimizer 49 | PUBLIC MQT_CORE_CIRCUIT_OPTIMIZER_STATIC_DEFINE) 50 | endif() 51 | 52 | # add to list of MQT core targets 53 | set(MQT_CORE_TARGETS 54 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-circuit-optimizer 55 | PARENT_SCOPE) 56 | endif() 57 | -------------------------------------------------------------------------------- /src/datastructures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET ${MQT_CORE_TARGET_NAME}-ds) 10 | # collect headers and source files 11 | file(GLOB_RECURSE DS_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/datastructures/**.hpp) 12 | file(GLOB_RECURSE DS_SOURCES **.cpp) 13 | 14 | # create the library target (initially empty) 15 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-ds ALIAS_NAME DS) 16 | 17 | # add sources to target 18 | target_sources(${MQT_CORE_TARGET_NAME}-ds PRIVATE ${DS_SOURCES}) 19 | 20 | # add headers using file sets 21 | target_sources( 22 | ${MQT_CORE_TARGET_NAME}-ds PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} 23 | FILES ${DS_HEADERS}) 24 | 25 | # add link libraries 26 | target_link_libraries( 27 | ${MQT_CORE_TARGET_NAME}-ds 28 | PUBLIC MQT::CoreIR 29 | PRIVATE MQT::ProjectOptions MQT::ProjectWarnings) 30 | 31 | # set versioning information 32 | set_target_properties( 33 | ${MQT_CORE_TARGET_NAME}-ds 34 | PROPERTIES VERSION ${PROJECT_VERSION} 35 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 36 | EXPORT_NAME CoreDS) 37 | 38 | # generate export header 39 | include(GenerateExportHeader) 40 | generate_export_header(${MQT_CORE_TARGET_NAME}-ds BASE_NAME mqt_core_ds) 41 | target_sources( 42 | ${MQT_CORE_TARGET_NAME}-ds PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. 43 | FILES ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_ds_export.h) 44 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 45 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-ds PUBLIC MQT_CORE_DS_STATIC_DEFINE) 46 | endif() 47 | 48 | # add to list of MQT core target 49 | set(MQT_CORE_TARGETS 50 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-ds 51 | PARENT_SCOPE) 52 | endif() 53 | -------------------------------------------------------------------------------- /src/dd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET ${MQT_CORE_TARGET_NAME}-dd) 10 | # collect headers and source files 11 | file(GLOB_RECURSE DD_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/dd/*.hpp) 12 | file(GLOB_RECURSE DD_SOURCES **.cpp) 13 | 14 | # create the library target (initially empty) 15 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-dd ALIAS_NAME DD) 16 | 17 | # add sources to target 18 | target_sources(${MQT_CORE_TARGET_NAME}-dd PRIVATE ${DD_SOURCES}) 19 | 20 | # add headers using file sets 21 | target_sources( 22 | ${MQT_CORE_TARGET_NAME}-dd PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} 23 | FILES ${DD_HEADERS}) 24 | 25 | # add link libraries 26 | target_link_libraries( 27 | ${MQT_CORE_TARGET_NAME}-dd 28 | PUBLIC MQT::CoreIR nlohmann_json::nlohmann_json 29 | PRIVATE MQT::ProjectOptions MQT::ProjectWarnings) 30 | 31 | # set versioning information 32 | set_target_properties( 33 | mqt-core-dd 34 | PROPERTIES VERSION ${PROJECT_VERSION} 35 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 36 | EXPORT_NAME CoreDD) 37 | 38 | # generate export header 39 | include(GenerateExportHeader) 40 | generate_export_header(${MQT_CORE_TARGET_NAME}-dd BASE_NAME mqt_core_dd) 41 | target_sources( 42 | ${MQT_CORE_TARGET_NAME}-dd PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. 43 | FILES ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_dd_export.h) 44 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 45 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-dd PUBLIC MQT_CORE_DD_STATIC_DEFINE) 46 | endif() 47 | 48 | # add to list of MQT core targets 49 | set(MQT_CORE_TARGETS 50 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-dd 51 | PARENT_SCOPE) 52 | endif() 53 | -------------------------------------------------------------------------------- /src/dd/ComplexNumbers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "dd/ComplexNumbers.hpp" 12 | 13 | #include "dd/Complex.hpp" 14 | #include "dd/ComplexValue.hpp" 15 | #include "dd/DDDefinitions.hpp" 16 | #include "dd/RealNumber.hpp" 17 | 18 | #include <cmath> 19 | #include <complex> 20 | #include <cstddef> 21 | 22 | namespace dd { 23 | 24 | void ComplexNumbers::setTolerance(fp tol) noexcept { RealNumber::eps = tol; } 25 | 26 | fp ComplexNumbers::mag2(const Complex& a) noexcept { 27 | return static_cast<ComplexValue>(a).mag2(); 28 | } 29 | 30 | fp ComplexNumbers::mag(const Complex& a) noexcept { 31 | return static_cast<ComplexValue>(a).mag(); 32 | } 33 | 34 | fp ComplexNumbers::arg(const Complex& a) noexcept { 35 | const auto val = static_cast<ComplexValue>(a); 36 | return std::atan2(val.i, val.r); 37 | } 38 | 39 | Complex ComplexNumbers::conj(const Complex& a) noexcept { 40 | return {a.r, RealNumber::flipPointerSign(a.i)}; 41 | } 42 | 43 | Complex ComplexNumbers::neg(const Complex& a) noexcept { 44 | return {RealNumber::flipPointerSign(a.r), RealNumber::flipPointerSign(a.i)}; 45 | } 46 | 47 | Complex ComplexNumbers::lookup(const Complex& c) { 48 | if (isStaticComplex(c)) { 49 | return c; 50 | } 51 | 52 | const auto valr = RealNumber::val(c.r); 53 | const auto vali = RealNumber::val(c.i); 54 | return lookup(valr, vali); 55 | } 56 | 57 | void ComplexNumbers::incRef(const Complex& c) const noexcept { 58 | uniqueTable->incRef(c.r); 59 | uniqueTable->incRef(c.i); 60 | } 61 | 62 | void ComplexNumbers::decRef(const Complex& c) const noexcept { 63 | uniqueTable->decRef(c.r); 64 | uniqueTable->decRef(c.i); 65 | } 66 | 67 | Complex ComplexNumbers::lookup(const std::complex<fp>& c) { 68 | return lookup(c.real(), c.imag()); 69 | } 70 | 71 | Complex ComplexNumbers::lookup(const ComplexValue& c) { 72 | return lookup(c.r, c.i); 73 | } 74 | 75 | Complex ComplexNumbers::lookup(const fp r) { 76 | return {uniqueTable->lookup(r), &constants::zero}; 77 | } 78 | 79 | Complex ComplexNumbers::lookup(const fp r, const fp i) { 80 | return {uniqueTable->lookup(r), uniqueTable->lookup(i)}; 81 | } 82 | 83 | std::size_t ComplexNumbers::realCount() const noexcept { 84 | return uniqueTable->getStats().numEntries; 85 | } 86 | 87 | } // namespace dd 88 | -------------------------------------------------------------------------------- /src/dd/statistics/Statistics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "dd/statistics/Statistics.hpp" 12 | 13 | #include <nlohmann/json.hpp> 14 | #include <string> 15 | 16 | namespace dd { 17 | 18 | nlohmann::basic_json<> Statistics::json() const { return nlohmann::json{}; } 19 | 20 | std::string Statistics::toString() const { return json().dump(2U); } 21 | 22 | } // namespace dd 23 | -------------------------------------------------------------------------------- /src/dd/statistics/TableStatistics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "dd/statistics/TableStatistics.hpp" 12 | 13 | #include "dd/statistics/Statistics.hpp" 14 | 15 | #include <algorithm> 16 | #include <nlohmann/json.hpp> 17 | 18 | namespace dd { 19 | 20 | void TableStatistics::trackInsert() noexcept { 21 | ++inserts; 22 | ++numEntries; 23 | peakNumEntries = std::max(peakNumEntries, numEntries); 24 | } 25 | 26 | void TableStatistics::reset() noexcept { numEntries = 0U; } 27 | 28 | double TableStatistics::hitRatio() const noexcept { 29 | if (lookups == 0) { 30 | return 1.; 31 | } 32 | return static_cast<double>(hits) / static_cast<double>(lookups); 33 | } 34 | 35 | double TableStatistics::colRatio() const noexcept { 36 | if (lookups == 0) { 37 | return 0.; 38 | } 39 | return static_cast<double>(collisions) / static_cast<double>(lookups); 40 | } 41 | 42 | double TableStatistics::loadFactor() const noexcept { 43 | if (numBuckets == 0) { 44 | return 0.; 45 | } 46 | return static_cast<double>(numEntries) / static_cast<double>(numBuckets); 47 | } 48 | 49 | double TableStatistics::getEntrySizeMiB() const noexcept { 50 | return static_cast<double>(entrySize) / static_cast<double>(1ULL << 20U); 51 | } 52 | 53 | double TableStatistics::getMemoryMiB() const noexcept { 54 | return static_cast<double>(numBuckets) * getEntrySizeMiB(); 55 | } 56 | 57 | nlohmann::basic_json<> TableStatistics::json() const { 58 | if (lookups == 0) { 59 | return "unused"; 60 | } 61 | 62 | auto j = Statistics::json(); 63 | j["num_buckets"] = numBuckets; 64 | j["memory_MiB"] = getMemoryMiB(); 65 | j["num_entries"] = numEntries; 66 | j["peak_num_entries"] = peakNumEntries; 67 | j["collisions"] = collisions; 68 | j["hits"] = hits; 69 | j["lookups"] = lookups; 70 | j["inserts"] = inserts; 71 | j["hit_ratio"] = hitRatio(); 72 | j["col_ratio"] = colRatio(); 73 | j["load_factor"] = loadFactor(); 74 | return j; 75 | } 76 | 77 | } // namespace dd 78 | -------------------------------------------------------------------------------- /src/dd/statistics/UniqueTableStatistics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "dd/statistics/UniqueTableStatistics.hpp" 12 | 13 | #include "dd/statistics/TableStatistics.hpp" 14 | 15 | #include <algorithm> 16 | #include <nlohmann/json.hpp> 17 | 18 | namespace dd { 19 | 20 | void UniqueTableStatistics::trackActiveEntry() noexcept { 21 | ++numActiveEntries; 22 | peakNumActiveEntries = std::max(peakNumActiveEntries, numActiveEntries); 23 | } 24 | 25 | void UniqueTableStatistics::reset() noexcept { 26 | TableStatistics::reset(); 27 | numActiveEntries = 0U; 28 | } 29 | 30 | nlohmann::basic_json<> UniqueTableStatistics::json() const { 31 | if (lookups == 0) { 32 | return "unused"; 33 | } 34 | 35 | auto j = TableStatistics::json(); 36 | j["num_active_entries"] = numActiveEntries; 37 | j["peak_num_active_entries"] = peakNumActiveEntries; 38 | j["gc_runs"] = gcRuns; 39 | return j; 40 | } 41 | } // namespace dd 42 | -------------------------------------------------------------------------------- /src/ir/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET MQT::CoreIR) 10 | # collect headers and source files 11 | file(GLOB_RECURSE IR_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/ir/*.hpp 12 | ${MQT_CORE_INCLUDE_BUILD_DIR}/ir/*.inc) 13 | file(GLOB_RECURSE IR_SOURCES **.cpp) 14 | 15 | # create the library target (initially empty) 16 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-ir ALIAS_NAME IR) 17 | 18 | # add sources to target 19 | target_sources(${MQT_CORE_TARGET_NAME}-ir PRIVATE ${IR_SOURCES}) 20 | 21 | # add headers using file sets 22 | target_sources( 23 | ${MQT_CORE_TARGET_NAME}-ir PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} 24 | FILES ${IR_HEADERS}) 25 | 26 | # add link libraries 27 | target_link_libraries(${MQT_CORE_TARGET_NAME}-ir PRIVATE MQT::ProjectOptions MQT::ProjectWarnings) 28 | 29 | # set required C++ standard 30 | target_compile_features(${MQT_CORE_TARGET_NAME}-ir PUBLIC cxx_std_17) 31 | 32 | # set versioning information 33 | set_target_properties( 34 | ${MQT_CORE_TARGET_NAME}-ir 35 | PROPERTIES VERSION ${PROJECT_VERSION} 36 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 37 | EXPORT_NAME CoreIR) 38 | 39 | # generate export header 40 | include(GenerateExportHeader) 41 | generate_export_header(${MQT_CORE_TARGET_NAME}-ir BASE_NAME mqt_core_ir) 42 | target_sources( 43 | ${MQT_CORE_TARGET_NAME}-ir PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. 44 | FILES ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_ir_export.h) 45 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 46 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-ir PUBLIC MQT_CORE_IR_STATIC_DEFINE) 47 | endif() 48 | 49 | # add to list of MQT core target 50 | set(MQT_CORE_TARGETS 51 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-ir 52 | PARENT_SCOPE) 53 | endif() 54 | -------------------------------------------------------------------------------- /src/ir/Permutation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "ir/Permutation.hpp" 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "ir/operations/Control.hpp" 15 | 16 | #include <algorithm> 17 | 18 | namespace qc { 19 | [[nodiscard]] auto Permutation::apply(const Controls& controls) const 20 | -> Controls { 21 | if (empty()) { 22 | return controls; 23 | } 24 | Controls c{}; 25 | for (const auto& control : controls) { 26 | c.emplace(at(control.qubit), control.type); 27 | } 28 | return c; 29 | } 30 | [[nodiscard]] auto Permutation::apply(const Targets& targets) const -> Targets { 31 | if (empty()) { 32 | return targets; 33 | } 34 | Targets t{}; 35 | for (const auto& target : targets) { 36 | t.emplace_back(at(target)); 37 | } 38 | return t; 39 | } 40 | 41 | [[nodiscard]] auto Permutation::apply(const Qubit qubit) const -> Qubit { 42 | if (empty()) { 43 | return qubit; 44 | } 45 | return at(qubit); 46 | } 47 | 48 | [[nodiscard]] auto Permutation::maxKey() const -> Qubit { 49 | if (empty()) { 50 | return 0; 51 | } 52 | return crbegin()->first; 53 | } 54 | 55 | [[nodiscard]] auto Permutation::maxValue() const -> Qubit { 56 | if (empty()) { 57 | return 0; 58 | } 59 | return std::max_element( 60 | cbegin(), cend(), 61 | [](const auto& a, const auto& b) { return a.second < b.second; }) 62 | ->second; 63 | } 64 | } // namespace qc 65 | -------------------------------------------------------------------------------- /src/ir/operations/Expression.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "ir/operations/Expression.hpp" 12 | 13 | #include <ostream> 14 | #include <string> 15 | 16 | namespace sym { 17 | 18 | Variable::Variable(const std::string& name) { 19 | if (const auto it = registered.find(name); it != registered.end()) { 20 | id = it->second; 21 | } else { 22 | registered[name] = nextId; 23 | names[nextId] = name; 24 | id = nextId; 25 | ++nextId; 26 | } 27 | } 28 | 29 | std::string Variable::getName() const noexcept { return names[id]; } 30 | 31 | std::ostream& operator<<(std::ostream& os, const Variable& var) { 32 | os << var.getName(); 33 | return os; 34 | } 35 | } // namespace sym 36 | -------------------------------------------------------------------------------- /src/mqt/core/__main__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | """Command line interface for mqt-core.""" 10 | 11 | from __future__ import annotations 12 | 13 | import argparse 14 | import sys 15 | 16 | from ._commands import cmake_dir, include_dir 17 | from ._version import version as __version__ 18 | 19 | 20 | def main() -> None: 21 | """Entry point for the mqt-core command line interface. 22 | 23 | This function is called when running the `mqt-core-cli` script. 24 | 25 | .. code-block:: bash 26 | 27 | mqt-core-cli [--version] [--include_dir] [--cmake_dir] 28 | 29 | It provides the following command line options: 30 | 31 | - :code:`--version`: Print the version and exit. 32 | - :code:`--include_dir`: Print the path to the mqt-core C++ include directory. 33 | - :code:`--cmake_dir`: Print the path to the mqt-core CMake module directory. 34 | 35 | """ 36 | parser = argparse.ArgumentParser() 37 | parser.add_argument("--version", action="version", version=__version__, help="Print version and exit.") 38 | 39 | parser.add_argument( 40 | "--include_dir", action="store_true", help="Print the path to the mqt-core C++ include directory." 41 | ) 42 | parser.add_argument( 43 | "--cmake_dir", action="store_true", help="Print the path to the mqt-core CMake module directory." 44 | ) 45 | args = parser.parse_args() 46 | if not sys.argv[1:]: 47 | parser.print_help() 48 | if args.include_dir: 49 | print(include_dir().resolve()) 50 | if args.cmake_dir: 51 | print(cmake_dir().resolve()) 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /src/mqt/core/_commands.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | """Useful commands for obtaining information about mqt-core.""" 10 | 11 | from __future__ import annotations 12 | 13 | from importlib.metadata import PackageNotFoundError, distribution 14 | from pathlib import Path 15 | 16 | 17 | def include_dir() -> Path: 18 | """Return the path to the mqt-core include directory. 19 | 20 | Raises: 21 | FileNotFoundError: If the include directory is not found. 22 | ImportError: If mqt-core is not installed. 23 | """ 24 | try: 25 | dist = distribution("mqt-core") 26 | located_include_dir = Path(dist.locate_file("mqt/core/include/mqt-core")) 27 | if located_include_dir.exists() and located_include_dir.is_dir(): 28 | return located_include_dir 29 | msg = "mqt-core include files not found." 30 | raise FileNotFoundError(msg) 31 | except PackageNotFoundError: 32 | msg = "mqt-core not installed, installation required to access the include files." 33 | raise ImportError(msg) from None 34 | 35 | 36 | def cmake_dir() -> Path: 37 | """Return the path to the mqt-core CMake module directory. 38 | 39 | Raises: 40 | FileNotFoundError: If the CMake module directory is not found. 41 | ImportError: If mqt-core is not installed. 42 | """ 43 | try: 44 | dist = distribution("mqt-core") 45 | located_cmake_dir = Path(dist.locate_file("mqt/core/share/cmake")) 46 | if located_cmake_dir.exists() and located_cmake_dir.is_dir(): 47 | return located_cmake_dir 48 | msg = "mqt-core CMake files not found." 49 | raise FileNotFoundError(msg) 50 | except PackageNotFoundError: 51 | msg = "mqt-core not installed, installation required to access the CMake files." 52 | raise ImportError(msg) from None 53 | -------------------------------------------------------------------------------- /src/mqt/core/_compat/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | from __future__ import annotations 10 | 11 | __all__: list[str] = [] 12 | -------------------------------------------------------------------------------- /src/mqt/core/_compat/typing.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | from __future__ import annotations 10 | 11 | import sys 12 | from typing import TYPE_CHECKING 13 | 14 | if sys.version_info >= (3, 11): 15 | from typing import assert_never 16 | elif TYPE_CHECKING: 17 | from typing_extensions import assert_never 18 | else: 19 | 20 | def assert_never(_: object) -> None: 21 | msg = "Expected code to be unreachable" 22 | raise AssertionError(msg) 23 | 24 | 25 | __all__ = ["assert_never"] 26 | 27 | 28 | def __dir__() -> list[str]: 29 | return __all__ 30 | -------------------------------------------------------------------------------- /src/mqt/core/_version.pyi: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | __version__: str 10 | version: str 11 | __version_tuple__: tuple[int, int, int, str, str] | tuple[int, int, int] 12 | version_tuple: tuple[int, int, int, str, str] | tuple[int, int, int] 13 | -------------------------------------------------------------------------------- /src/mqt/core/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | """Plugins for the core package.""" 10 | 11 | from __future__ import annotations 12 | 13 | from . import qiskit 14 | 15 | __all__ = [ 16 | "qiskit", 17 | ] 18 | -------------------------------------------------------------------------------- /src/mqt/core/plugins/qiskit/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | """MQT Qiskit Plugin.""" 10 | 11 | from __future__ import annotations 12 | 13 | from .mqt_to_qiskit import mqt_to_qiskit 14 | from .qiskit_to_mqt import qiskit_to_mqt 15 | 16 | __all__ = [ 17 | "mqt_to_qiskit", 18 | "qiskit_to_mqt", 19 | ] 20 | -------------------------------------------------------------------------------- /src/mqt/core/py.typed: -------------------------------------------------------------------------------- 1 | # Instruct type checkers to look for inline type annotations in this package. 2 | # See PEP 561. 3 | -------------------------------------------------------------------------------- /src/na/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET ${MQT_CORE_TARGET_NAME}-na) 10 | # collect headers and source files 11 | file(GLOB_RECURSE NA_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/na/**.hpp) 12 | file(GLOB_RECURSE NA_SOURCES **.cpp) 13 | 14 | # create the library target (initially empty) 15 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-na ALIAS_NAME NA) 16 | 17 | # add sources to target 18 | target_sources(${MQT_CORE_TARGET_NAME}-na PRIVATE ${NA_SOURCES}) 19 | 20 | # add headers using file sets 21 | target_sources( 22 | ${MQT_CORE_TARGET_NAME}-na PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} 23 | FILES ${NA_HEADERS}) 24 | 25 | # add link libraries 26 | target_link_libraries( 27 | ${MQT_CORE_TARGET_NAME}-na 28 | PUBLIC MQT::CoreIR 29 | PRIVATE MQT::ProjectOptions MQT::ProjectWarnings) 30 | 31 | # set versioning information 32 | set_target_properties( 33 | ${MQT_CORE_TARGET_NAME}-na 34 | PROPERTIES VERSION ${PROJECT_VERSION} 35 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 36 | EXPORT_NAME CoreNA) 37 | 38 | # generate export header 39 | include(GenerateExportHeader) 40 | generate_export_header(${MQT_CORE_TARGET_NAME}-na BASE_NAME mqt_core_na) 41 | target_sources( 42 | ${MQT_CORE_TARGET_NAME}-na PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. 43 | FILES ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_na_export.h) 44 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 45 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-na PUBLIC MQT_CORE_NA_STATIC_DEFINE) 46 | endif() 47 | 48 | # add to list of MQT core targets 49 | set(MQT_CORE_TARGETS 50 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-na 51 | PARENT_SCOPE) 52 | endif() 53 | -------------------------------------------------------------------------------- /src/na/entities/Zone.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "na/entities/Zone.hpp" 12 | 13 | #include "na/entities/Location.hpp" 14 | 15 | #include <stdexcept> 16 | 17 | namespace na { 18 | 19 | auto Zone::contains(const Location& location) const -> bool { 20 | if (!extent_) { 21 | throw std::runtime_error("Zone's extent is not set."); 22 | } 23 | return extent_->minX <= location.x && location.x <= extent_->maxX && 24 | extent_->minY <= location.y && location.y <= extent_->maxY; 25 | } 26 | } // namespace na 27 | -------------------------------------------------------------------------------- /src/na/operations/GlobalOp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "na/operations/GlobalOp.hpp" 12 | 13 | #include "ir/Definitions.hpp" 14 | 15 | #include <iomanip> 16 | #include <ios> 17 | #include <sstream> 18 | #include <string> 19 | #include <vector> 20 | 21 | namespace na { 22 | namespace { 23 | auto printParams(const std::vector<qc::fp>& params, std::ostringstream& os) 24 | -> void { 25 | if (!params.empty()) { 26 | for (const auto& p : params) { 27 | os << p << " "; 28 | } 29 | } 30 | } 31 | } // namespace 32 | 33 | auto GlobalOp::toString() const -> std::string { 34 | std::ostringstream ss; 35 | ss << std::setprecision(5) << std::fixed; 36 | ss << "@+ " << name_ << " "; 37 | if (zones_.size() == 1) { 38 | printParams(params_, ss); 39 | ss << *zones_.front(); 40 | return ss.str(); 41 | } 42 | ss << "[\n"; 43 | for (const auto& atom : zones_) { 44 | ss << " "; 45 | printParams(params_, ss); 46 | ss << *atom << "\n"; 47 | } 48 | ss << "]"; 49 | return ss.str(); 50 | } 51 | } // namespace na 52 | -------------------------------------------------------------------------------- /src/na/operations/LoadOp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "na/operations/LoadOp.hpp" 12 | 13 | #include <cstddef> 14 | #include <sstream> 15 | #include <string> 16 | 17 | namespace na { 18 | auto LoadOp::toString() const -> std::string { 19 | std::stringstream ss; 20 | ss << "@+ load"; 21 | if (atoms_.size() == 1) { 22 | if (targetLocations_) { 23 | ss << " " << targetLocations_->front(); 24 | } 25 | ss << " " << *(atoms_.front()); 26 | return ss.str(); 27 | } 28 | ss << " [\n"; 29 | for (std::size_t i = 0; i < atoms_.size(); ++i) { 30 | ss << " "; 31 | if (targetLocations_) { 32 | ss << (*targetLocations_)[i] << " "; 33 | } 34 | ss << *(atoms_[i]) << "\n"; 35 | } 36 | ss << "]"; 37 | return ss.str(); 38 | } 39 | } // namespace na 40 | -------------------------------------------------------------------------------- /src/na/operations/LocalOp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "na/operations/LocalOp.hpp" 12 | 13 | #include "ir/Definitions.hpp" 14 | #include "na/entities/Atom.hpp" 15 | 16 | #include <iomanip> 17 | #include <ios> 18 | #include <sstream> 19 | #include <string> 20 | #include <vector> 21 | 22 | namespace na { 23 | namespace { 24 | auto printParams(const std::vector<qc::fp>& params, std::ostringstream& os) 25 | -> void { 26 | if (!params.empty()) { 27 | for (const auto& p : params) { 28 | os << p << " "; 29 | } 30 | } 31 | } 32 | } // namespace 33 | 34 | auto LocalOp::toString() const -> std::string { 35 | std::ostringstream ss; 36 | ss << std::setprecision(5) << std::fixed; 37 | ss << "@+ " << name_ << " "; 38 | if (atoms_.size() == 1) { 39 | printParams(params_, ss); 40 | ss << *atoms_.front(); 41 | return ss.str(); 42 | } 43 | ss << "[\n"; 44 | for (const auto& atom : atoms_) { 45 | ss << " "; 46 | printParams(params_, ss); 47 | ss << *atom << "\n"; 48 | } 49 | ss << "]"; 50 | return ss.str(); 51 | } 52 | } // namespace na 53 | -------------------------------------------------------------------------------- /src/na/operations/MoveOp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "na/operations/MoveOp.hpp" 12 | 13 | #include <cstddef> 14 | #include <sstream> 15 | #include <string> 16 | 17 | namespace na { 18 | auto MoveOp::toString() const -> std::string { 19 | std::stringstream ss; 20 | ss << "@+ move"; 21 | if (atoms_.size() == 1) { 22 | ss << " " << targetLocations_.front() << " " << *(atoms_.front()); 23 | return ss.str(); 24 | } 25 | ss << " [\n"; 26 | for (std::size_t i = 0; i < atoms_.size(); ++i) { 27 | ss << " " << targetLocations_[i] << " " << *(atoms_[i]) << "\n"; 28 | } 29 | ss << "]"; 30 | return ss.str(); 31 | } 32 | } // namespace na 33 | -------------------------------------------------------------------------------- /src/na/operations/StoreOp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "na/operations/StoreOp.hpp" 12 | 13 | #include <cstddef> 14 | #include <sstream> 15 | #include <string> 16 | 17 | namespace na { 18 | auto StoreOp::toString() const -> std::string { 19 | std::stringstream ss; 20 | ss << "@+ store"; 21 | if (atoms_.size() == 1) { 22 | if (targetLocations_) { 23 | ss << " " << targetLocations_->front(); 24 | } 25 | ss << " " << *(atoms_.front()); 26 | return ss.str(); 27 | } 28 | ss << " [\n"; 29 | for (std::size_t i = 0; i < atoms_.size(); ++i) { 30 | ss << " "; 31 | if (targetLocations_) { 32 | ss << (*targetLocations_)[i] << " "; 33 | } 34 | ss << *(atoms_[i]) << "\n"; 35 | } 36 | ss << "]"; 37 | return ss.str(); 38 | } 39 | } // namespace na 40 | -------------------------------------------------------------------------------- /src/python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # add the IR bindings package 10 | add_subdirectory(ir) 11 | 12 | # add the DD bindings package 13 | add_subdirectory(dd) 14 | -------------------------------------------------------------------------------- /src/python/dd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET dd) 10 | # collect source files 11 | file(GLOB_RECURSE DD_SOURCES **.cpp) 12 | 13 | # declare the Python module 14 | pybind11_add_module( 15 | # Name of the extension 16 | dd 17 | # Prefer thin LTO if available 18 | THIN_LTO 19 | # Optimize the bindings for size 20 | OPT_SIZE 21 | # Source code goes here 22 | ${DD_SOURCES}) 23 | target_link_libraries(dd PRIVATE MQT::CoreDD MQT::ProjectOptions MQT::ProjectWarnings) 24 | 25 | # Install directive for scikit-build-core 26 | install( 27 | TARGETS dd 28 | DESTINATION . 29 | COMPONENT ${MQT_CORE_TARGET_NAME}_Python) 30 | 31 | # Install the Python stub file in editable mode for better IDE support 32 | if(SKBUILD_STATE STREQUAL "editable") 33 | install( 34 | FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../mqt/core/dd.pyi 35 | DESTINATION . 36 | COMPONENT ${MQT_CORE_TARGET_NAME}_Python) 37 | endif() 38 | endif() 39 | -------------------------------------------------------------------------------- /src/python/ir/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET ir) 10 | # collect source files 11 | file(GLOB_RECURSE IR_SOURCES **.cpp) 12 | 13 | # declare the Python module 14 | pybind11_add_module( 15 | # Name of the extension 16 | ir 17 | # Prefer thin LTO if available 18 | THIN_LTO 19 | # Optimize the bindings for size 20 | OPT_SIZE 21 | # Source code goes here 22 | ${IR_SOURCES}) 23 | target_link_libraries(ir PRIVATE MQT::CoreIR MQT::CoreQASM MQT::ProjectOptions 24 | MQT::ProjectWarnings) 25 | 26 | # Install directive for scikit-build-core 27 | install( 28 | TARGETS ir 29 | DESTINATION . 30 | COMPONENT ${MQT_CORE_TARGET_NAME}_Python) 31 | 32 | # Install the Python stub files in editable mode for better IDE support 33 | if(SKBUILD_STATE STREQUAL "editable") 34 | file(GLOB_RECURSE IR_PYI_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../mqt/core/ir/*.pyi) 35 | install( 36 | FILES ${IR_PYI_FILES} 37 | DESTINATION ./ir 38 | COMPONENT ${MQT_CORE_TARGET_NAME}_Python) 39 | endif() 40 | endif() 41 | -------------------------------------------------------------------------------- /src/python/ir/register_ir.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | // These includes must be the first includes for any bindings code 12 | // clang-format off 13 | #include <pybind11/pybind11.h> 14 | #include <pybind11/stl.h> // NOLINT(misc-include-cleaner) 15 | // clang-format on 16 | 17 | namespace mqt { 18 | 19 | namespace py = pybind11; 20 | using namespace pybind11::literals; 21 | 22 | // forward declarations 23 | void registerRegisters(py::module& m); 24 | void registerPermutation(py::module& m); 25 | void registerOperations(py::module& m); 26 | void registerSymbolic(py::module& m); 27 | void registerQuantumComputation(py::module& m); 28 | 29 | PYBIND11_MODULE(ir, m, py::mod_gil_not_used()) { 30 | registerPermutation(m); 31 | py::module registers = m.def_submodule("registers"); 32 | registerRegisters(registers); 33 | 34 | py::module symbolic = m.def_submodule("symbolic"); 35 | registerSymbolic(symbolic); 36 | 37 | py::module operations = m.def_submodule("operations"); 38 | registerOperations(operations); 39 | 40 | registerQuantumComputation(m); 41 | } 42 | 43 | } // namespace mqt 44 | -------------------------------------------------------------------------------- /src/python/ir/register_operations.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | // These includes must be the first includes for any bindings code 12 | // clang-format off 13 | #include <pybind11/pybind11.h> 14 | #include <pybind11/stl.h> // NOLINT(misc-include-cleaner) 15 | // clang-format on 16 | 17 | namespace mqt { 18 | 19 | namespace py = pybind11; 20 | using namespace pybind11::literals; 21 | 22 | // forward declarations 23 | void registerOptype(const py::module& m); 24 | void registerControl(const py::module& m); 25 | void registerOperation(const py::module& m); 26 | void registerStandardOperation(const py::module& m); 27 | void registerCompoundOperation(const py::module& m); 28 | void registerNonUnitaryOperation(const py::module& m); 29 | void registerSymbolicOperation(const py::module& m); 30 | void registerClassicControlledOperation(const py::module& m); 31 | 32 | // NOLINTNEXTLINE(misc-use-internal-linkage) 33 | void registerOperations(py::module& m) { 34 | registerOptype(m); 35 | registerControl(m); 36 | registerOperation(m); 37 | registerStandardOperation(m); 38 | registerCompoundOperation(m); 39 | registerNonUnitaryOperation(m); 40 | registerSymbolicOperation(m); 41 | registerClassicControlledOperation(m); 42 | } 43 | } // namespace mqt 44 | -------------------------------------------------------------------------------- /src/python/ir/register_symbolic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | // These includes must be the first includes for any bindings code 12 | // clang-format off 13 | #include <pybind11/pybind11.h> 14 | #include <pybind11/stl.h> // NOLINT(misc-include-cleaner) 15 | // clang-format on 16 | 17 | namespace mqt { 18 | 19 | namespace py = pybind11; 20 | using namespace pybind11::literals; 21 | 22 | // forward declarations 23 | void registerVariable(py::module& m); 24 | void registerTerm(py::module& m); 25 | void registerExpression(py::module& m); 26 | 27 | // NOLINTNEXTLINE(misc-use-internal-linkage) 28 | void registerSymbolic(pybind11::module& m) { 29 | registerVariable(m); 30 | registerTerm(m); 31 | registerExpression(m); 32 | } 33 | } // namespace mqt 34 | -------------------------------------------------------------------------------- /src/python/ir/symbolic/register_term.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "ir/operations/Expression.hpp" 12 | 13 | // These includes must be the first includes for any bindings code 14 | // clang-format off 15 | #include <pybind11/pybind11.h> 16 | #include <pybind11/stl.h> // NOLINT(misc-include-cleaner) 17 | 18 | #include <pybind11/cast.h> 19 | #include <pybind11/operators.h> 20 | // clang-format on 21 | 22 | #include <sstream> 23 | 24 | namespace mqt { 25 | 26 | namespace py = pybind11; 27 | using namespace pybind11::literals; 28 | 29 | // NOLINTNEXTLINE(misc-use-internal-linkage) 30 | void registerTerm(py::module& m) { 31 | py::class_<sym::Term<double>>(m, "Term") 32 | .def(py::init<sym::Variable, double>(), "variable"_a, 33 | "coefficient"_a = 1.0) 34 | .def_property_readonly("variable", &sym::Term<double>::getVar) 35 | .def_property_readonly("coefficient", &sym::Term<double>::getCoeff) 36 | .def("has_zero_coefficient", &sym::Term<double>::hasZeroCoeff) 37 | .def("add_coefficient", &sym::Term<double>::addCoeff, "coeff"_a) 38 | .def("evaluate", &sym::Term<double>::evaluate, "assignment"_a) 39 | .def(py::self * double()) 40 | .def(double() * py::self) 41 | .def(py::self / double()) 42 | .def(double() / py::self) 43 | .def(py::self == py::self) // NOLINT(misc-redundant-expression) 44 | .def(py::self != py::self) // NOLINT(misc-redundant-expression) 45 | .def(hash(py::self)) 46 | .def("__str__", 47 | [](const sym::Term<double>& term) { 48 | std::stringstream ss; 49 | ss << term; 50 | return ss.str(); 51 | }) 52 | .def("__repr__", [](const sym::Term<double>& term) { 53 | std::stringstream ss; 54 | ss << term; 55 | return ss.str(); 56 | }); 57 | } 58 | } // namespace mqt 59 | -------------------------------------------------------------------------------- /src/python/ir/symbolic/register_variable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "ir/operations/Expression.hpp" 12 | 13 | // These includes must be the first includes for any bindings code 14 | // clang-format off 15 | #include <pybind11/pybind11.h> 16 | #include <pybind11/stl.h> // NOLINT(misc-include-cleaner) 17 | 18 | #include <pybind11/cast.h> 19 | #include <pybind11/operators.h> 20 | // clang-format on 21 | 22 | #include <string> 23 | 24 | namespace mqt { 25 | 26 | namespace py = pybind11; 27 | using namespace pybind11::literals; 28 | 29 | // NOLINTNEXTLINE(misc-use-internal-linkage) 30 | void registerVariable(py::module& m) { 31 | py::class_<sym::Variable>(m, "Variable") 32 | .def(py::init<std::string>(), "name"_a = "") 33 | .def_property_readonly("name", &sym::Variable::getName) 34 | .def("__str__", &sym::Variable::getName) 35 | .def("__repr__", &sym::Variable::getName) 36 | .def(py::self == py::self) // NOLINT(misc-redundant-expression) 37 | .def(py::self != py::self) // NOLINT(misc-redundant-expression) 38 | .def(hash(py::self)) 39 | .def(py::self < py::self) // NOLINT(misc-redundant-expression) 40 | .def(py::self > py::self); // NOLINT(misc-redundant-expression) 41 | } 42 | } // namespace mqt 43 | -------------------------------------------------------------------------------- /src/qasm3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(NOT TARGET MQT::CoreQASM) 10 | # collect headers and source files 11 | file(GLOB_RECURSE QASM_HEADERS ${MQT_CORE_INCLUDE_BUILD_DIR}/qasm3/*.hpp) 12 | file(GLOB_RECURSE QASM_SOURCES **.cpp) 13 | 14 | # create the library target (initially empty) 15 | add_mqt_core_library(${MQT_CORE_TARGET_NAME}-qasm ALIAS_NAME QASM) 16 | 17 | # add sources to target 18 | target_sources(${MQT_CORE_TARGET_NAME}-qasm PRIVATE ${QASM_SOURCES}) 19 | 20 | # add headers using file sets 21 | target_sources( 22 | ${MQT_CORE_TARGET_NAME}-qasm PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} 23 | FILES ${QASM_HEADERS}) 24 | 25 | # add link libraries 26 | target_link_libraries( 27 | ${MQT_CORE_TARGET_NAME}-qasm 28 | PRIVATE MQT::ProjectOptions MQT::ProjectWarnings 29 | PUBLIC MQT::CoreIR) 30 | 31 | # set versioning information 32 | set_target_properties( 33 | ${MQT_CORE_TARGET_NAME}-qasm 34 | PROPERTIES VERSION ${PROJECT_VERSION} 35 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} 36 | EXPORT_NAME CoreQASM) 37 | 38 | # generate export header 39 | include(GenerateExportHeader) 40 | generate_export_header(${MQT_CORE_TARGET_NAME}-qasm BASE_NAME mqt_core_qasm) 41 | target_sources( 42 | ${MQT_CORE_TARGET_NAME}-qasm PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/.. 43 | FILES ${CMAKE_CURRENT_BINARY_DIR}/mqt_core_qasm_export.h) 44 | if(NOT BUILD_MQT_CORE_SHARED_LIBS) 45 | target_compile_definitions(${MQT_CORE_TARGET_NAME}-qasm PUBLIC MQT_CORE_QASM_STATIC_DEFINE) 46 | endif() 47 | 48 | # add to list of MQT core target 49 | set(MQT_CORE_TARGETS 50 | ${MQT_CORE_TARGETS} ${MQT_CORE_TARGET_NAME}-qasm 51 | PARENT_SCOPE) 52 | endif() 53 | -------------------------------------------------------------------------------- /src/qasm3/Types.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "qasm3/Types.hpp" 12 | 13 | #include <cstdint> 14 | #include <memory> 15 | #include <string> 16 | 17 | namespace qasm3 { 18 | 19 | template <typename T> 20 | DesignatedType<T>::DesignatedType(DesignatedTy ty) 21 | : type(ty), designator(nullptr) {} 22 | template <> 23 | bool DesignatedType<std::shared_ptr<Expression>>::fits( 24 | const Type<std::shared_ptr<Expression>>& other) { 25 | if (const auto* o = dynamic_cast<const DesignatedType*>(&other)) { 26 | if (type == Int && o->type == Uint) { 27 | return true; 28 | } 29 | if (type == Float && (o->type == Int || o->type == Uint)) { 30 | return true; 31 | } 32 | 33 | return type == o->type; 34 | } 35 | return false; 36 | } 37 | 38 | template <> bool DesignatedType<uint64_t>::fits(const Type<uint64_t>& other) { 39 | if (const auto* o = dynamic_cast<const DesignatedType*>(&other)) { 40 | bool typeFits = type == o->type; 41 | if (type == Int && o->type == Uint) { 42 | typeFits = true; 43 | } 44 | if (type == Float && (o->type == Int || o->type == Uint)) { 45 | typeFits = true; 46 | } 47 | 48 | return typeFits && designator >= o->designator; 49 | } 50 | return false; 51 | } 52 | 53 | template <> 54 | DesignatedType<uint64_t>::DesignatedType(DesignatedTy ty) 55 | : type(ty), designator(0) { 56 | switch (ty) { 57 | case Qubit: 58 | case Bit: 59 | designator = 1; 60 | break; 61 | case Int: 62 | case Uint: 63 | designator = 32; 64 | break; 65 | case Float: 66 | case Angle: 67 | designator = 64; 68 | break; 69 | } 70 | } 71 | 72 | template <> 73 | std::string DesignatedType<std::shared_ptr<Expression>>::designatorToString() { 74 | return "expr"; 75 | } 76 | 77 | template <> std::string DesignatedType<uint64_t>::designatorToString() { 78 | return std::to_string(designator); 79 | } 80 | 81 | } // namespace qasm3 82 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | # add various subdirectories containing tests 10 | add_subdirectory(algorithms) 11 | add_subdirectory(circuit_optimizer) 12 | add_subdirectory(datastructures) 13 | add_subdirectory(dd) 14 | add_subdirectory(ir) 15 | add_subdirectory(na) 16 | add_subdirectory(zx) 17 | 18 | # copy test circuits to build directory 19 | file(COPY ${PROJECT_SOURCE_DIR}/test/circuits DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 20 | -------------------------------------------------------------------------------- /test/algorithms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreAlgorithms) 10 | file(GLOB_RECURSE ALGO_TEST_SOURCES *.cpp) 11 | package_add_test(mqt-core-algorithms-test MQT::CoreAlgorithms ${ALGO_TEST_SOURCES}) 12 | target_link_libraries(mqt-core-algorithms-test PRIVATE MQT::CoreDD MQT::CoreCircuitOptimizer) 13 | endif() 14 | -------------------------------------------------------------------------------- /test/algorithms/test_entanglement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "algorithms/GHZState.hpp" 12 | #include "dd/DDDefinitions.hpp" 13 | #include "dd/FunctionalityConstruction.hpp" 14 | #include "dd/Package.hpp" 15 | #include "dd/Simulation.hpp" 16 | #include "dd/StateGeneration.hpp" 17 | #include "ir/Definitions.hpp" 18 | 19 | #include <gtest/gtest.h> 20 | #include <memory> 21 | #include <sstream> 22 | #include <string> 23 | 24 | class Entanglement : public testing::TestWithParam<qc::Qubit> { 25 | protected: 26 | void TearDown() override {} 27 | void SetUp() override { 28 | nq = GetParam(); 29 | dd = std::make_unique<dd::Package>(nq); 30 | } 31 | qc::Qubit nq{}; 32 | std::unique_ptr<dd::Package> dd; 33 | }; 34 | 35 | INSTANTIATE_TEST_SUITE_P( 36 | Entanglement, Entanglement, testing::Range<qc::Qubit>(2U, 90U, 7U), 37 | [](const testing::TestParamInfo<Entanglement::ParamType>& inf) { 38 | // Generate names for test cases 39 | const auto nqubits = inf.param; 40 | std::stringstream ss{}; 41 | ss << nqubits << "_qubits"; 42 | return ss.str(); 43 | }); 44 | 45 | TEST_P(Entanglement, FunctionTest) { 46 | const auto qc = qc::createGHZState(nq); 47 | const auto e = dd::buildFunctionality(qc, *dd); 48 | ASSERT_EQ(qc.getNops(), nq); 49 | const auto r = dd->multiply(e, makeZeroState(nq, *dd)); 50 | ASSERT_EQ(r.getValueByPath(nq, std::string(nq, '0')), dd::SQRT2_2); 51 | ASSERT_EQ(r.getValueByPath(nq, std::string(nq, '1')), dd::SQRT2_2); 52 | } 53 | 54 | TEST_P(Entanglement, GHZRoutineFunctionTest) { 55 | const auto qc = qc::createGHZState(nq); 56 | const auto e = dd::simulate(qc, makeZeroState(nq, *dd), *dd); 57 | const auto f = makeGHZState(nq, *dd); 58 | EXPECT_EQ(e, f); 59 | } 60 | -------------------------------------------------------------------------------- /test/algorithms/test_random_clifford.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "algorithms/RandomCliffordCircuit.hpp" 12 | #include "dd/FunctionalityConstruction.hpp" 13 | #include "dd/Package.hpp" 14 | #include "dd/Simulation.hpp" 15 | #include "dd/StateGeneration.hpp" 16 | #include "ir/Definitions.hpp" 17 | 18 | #include <cstddef> 19 | #include <gtest/gtest.h> 20 | #include <iostream> 21 | #include <memory> 22 | #include <sstream> 23 | 24 | class RandomClifford : public testing::TestWithParam<qc::Qubit> { 25 | protected: 26 | void TearDown() override {} 27 | void SetUp() override {} 28 | }; 29 | 30 | INSTANTIATE_TEST_SUITE_P( 31 | RandomClifford, RandomClifford, testing::Range<qc::Qubit>(1U, 9U), 32 | [](const testing::TestParamInfo<RandomClifford::ParamType>& inf) { 33 | // Generate names for test cases 34 | const auto nqubits = inf.param; 35 | std::stringstream ss{}; 36 | ss << static_cast<std::size_t>(nqubits) << "_qubits"; 37 | return ss.str(); 38 | }); 39 | 40 | TEST_P(RandomClifford, simulate) { 41 | const auto nq = GetParam(); 42 | constexpr auto numReps = 16U; 43 | 44 | const auto dd = std::make_unique<dd::Package>(nq); 45 | for (size_t i = 0; i < numReps; ++i) { 46 | auto qc = 47 | qc::createRandomCliffordCircuit(nq, static_cast<std::size_t>(nq) * nq); 48 | auto in = makeZeroState(nq, *dd); 49 | ASSERT_NO_THROW({ dd::simulate(qc, in, *dd); }); 50 | qc.printStatistics(std::cout); 51 | } 52 | } 53 | 54 | TEST_P(RandomClifford, buildFunctionality) { 55 | const auto nq = GetParam(); 56 | 57 | const auto dd = std::make_unique<dd::Package>(nq); 58 | const auto qc = qc::createRandomCliffordCircuit( 59 | nq, static_cast<std::size_t>(nq) * nq, 12345); 60 | ASSERT_NO_THROW({ dd::buildFunctionality(qc, *dd); }); 61 | qc.printStatistics(std::cout); 62 | } 63 | -------------------------------------------------------------------------------- /test/algorithms/test_wstate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "algorithms/WState.hpp" 12 | #include "dd/Simulation.hpp" 13 | #include "dd/StateGeneration.hpp" 14 | #include "ir/Definitions.hpp" 15 | 16 | #include <cstddef> 17 | #include <gtest/gtest.h> 18 | #include <iostream> 19 | #include <sstream> 20 | #include <string> 21 | #include <vector> 22 | 23 | class WState : public testing::TestWithParam<qc::Qubit> {}; 24 | 25 | namespace { 26 | std::vector<std::string> generateWStateStrings(const std::size_t length) { 27 | std::vector<std::string> result; 28 | result.reserve(length); 29 | for (std::size_t i = 0U; i < length; ++i) { 30 | auto binaryString = std::string(length, '0'); 31 | binaryString[i] = '1'; 32 | result.emplace_back(binaryString); 33 | } 34 | return result; 35 | } 36 | } // namespace 37 | 38 | INSTANTIATE_TEST_SUITE_P( 39 | WState, WState, testing::Range<qc::Qubit>(1U, 128U, 7U), 40 | [](const testing::TestParamInfo<WState::ParamType>& inf) { 41 | // Generate names for test cases 42 | const auto nqubits = inf.param; 43 | std::stringstream ss{}; 44 | ss << nqubits << "_qubits"; 45 | return ss.str(); 46 | }); 47 | 48 | TEST_P(WState, FunctionTest) { 49 | const auto nq = GetParam(); 50 | const auto qc = qc::createWState(nq); 51 | constexpr std::size_t shots = 4096U; 52 | const auto measurements = dd::sample(qc, shots); 53 | for (const auto& result : generateWStateStrings(nq)) { 54 | EXPECT_TRUE(measurements.find(result) != measurements.end()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/circuit_optimizer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreCircuitOptimizer) 10 | file(GLOB_RECURSE CIRCUIT_OPTIMIZER_TEST_SOURCES *.cpp) 11 | package_add_test(mqt-core-circuit-optimizer-test MQT::CoreCircuitOptimizer 12 | ${CIRCUIT_OPTIMIZER_TEST_SOURCES}) 13 | target_link_libraries(mqt-core-circuit-optimizer-test PRIVATE MQT::CoreAlgorithms MQT::CoreQASM) 14 | endif() 15 | -------------------------------------------------------------------------------- /test/circuit_optimizer/test_swap_reconstruction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "circuit_optimizer/CircuitOptimizer.hpp" 12 | #include "ir/QuantumComputation.hpp" 13 | #include "ir/operations/OpType.hpp" 14 | 15 | #include <cstddef> 16 | #include <gtest/gtest.h> 17 | 18 | namespace qc { 19 | TEST(SwapReconstruction, fuseCxToSwap) { 20 | const std::size_t nqubits = 2; 21 | QuantumComputation qc(nqubits); 22 | qc.cx(0, 1); 23 | qc.cx(1, 0); 24 | qc.cx(0, 1); 25 | CircuitOptimizer::swapReconstruction(qc); 26 | const auto& op = qc.front(); 27 | EXPECT_TRUE(op->isStandardOperation()); 28 | EXPECT_EQ(op->getType(), SWAP); 29 | EXPECT_EQ(op->getTargets().at(0), 0); 30 | EXPECT_EQ(op->getTargets().at(1), 1); 31 | } 32 | 33 | TEST(SwapReconstruction, replaceCxToSwapAtEnd) { 34 | const std::size_t nqubits = 2; 35 | QuantumComputation qc(nqubits); 36 | qc.cx(0, 1); 37 | qc.cx(1, 0); 38 | CircuitOptimizer::swapReconstruction(qc); 39 | auto it = qc.begin(); 40 | const auto& op = *it; 41 | EXPECT_TRUE(op->isStandardOperation()); 42 | EXPECT_EQ(op->getType(), SWAP); 43 | EXPECT_EQ(op->getTargets().at(0), 0); 44 | EXPECT_EQ(op->getTargets().at(1), 1); 45 | 46 | ++it; 47 | const auto& op2 = *it; 48 | EXPECT_TRUE(op2->isStandardOperation()); 49 | EXPECT_EQ(op2->getType(), X); 50 | EXPECT_EQ(op2->getControls().begin()->qubit, 0); 51 | EXPECT_EQ(op2->getTargets().at(0), 1); 52 | } 53 | 54 | TEST(SwapReconstruction, replaceCxToSwap) { 55 | const std::size_t nqubits = 2; 56 | QuantumComputation qc(nqubits); 57 | qc.cx(0, 1); 58 | qc.cx(1, 0); 59 | qc.h(0); 60 | CircuitOptimizer::swapReconstruction(qc); 61 | auto it = qc.begin(); 62 | const auto& op = *it; 63 | EXPECT_TRUE(op->isStandardOperation()); 64 | EXPECT_EQ(op->getType(), SWAP); 65 | EXPECT_EQ(op->getTargets().at(0), 0); 66 | EXPECT_EQ(op->getTargets().at(1), 1); 67 | ++it; 68 | const auto& op2 = *it; 69 | EXPECT_TRUE(op2->isStandardOperation()); 70 | EXPECT_EQ(op2->getType(), X); 71 | EXPECT_EQ(op2->getControls().begin()->qubit, 0); 72 | EXPECT_EQ(op2->getTargets().at(0), 1); 73 | } 74 | } // namespace qc 75 | -------------------------------------------------------------------------------- /test/circuits/bell.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | //include "qelib1.inc"; 3 | qreg q[2]; 4 | U(pi/2,0,pi) q[0]; 5 | CX q[0],q[1]; 6 | -------------------------------------------------------------------------------- /test/circuits/test.qasm: -------------------------------------------------------------------------------- 1 | // i 0 1 2 3 2 | // o 0 1 2 3 3 | OPENQASM 3.0; 4 | include "stdgates.inc"; 5 | qubit[2] q; 6 | qubit[2] r; 7 | bit[2] c; 8 | bit[2] d; 9 | 10 | gphase(pi/4); 11 | id q[0]; 12 | h q[0]; 13 | x q; 14 | x q[0]; 15 | y q[0]; 16 | z q[0]; 17 | rx(pi/2) q[0]; 18 | rx(pi/4) q[0]; 19 | ry(pi/4) q[0]; 20 | ry(pi/2) q[0]; 21 | rz(-pi/8) q[0]; 22 | rz(-pi/0.7854) q[0]; 23 | s q[1]; 24 | sdg q[1]; 25 | sx q[1]; 26 | sxdg q[1]; 27 | U(0,0,-pi/4) q[1]; 28 | U(0,0,pi/4) q[0]; 29 | U(pi/2,pi/2,-pi/2) q[0]; 30 | U(pi/2,-pi/2,pi/2) q[0]; 31 | 32 | cx q[0],r[0]; 33 | cx q[0],r; 34 | cx q,r[0]; 35 | cx q,r; 36 | 37 | u3(1,2,3) r[0]; 38 | u2(1,2) r[1]; 39 | u1(1) q[0]; 40 | barrier q; 41 | measure q -> c; 42 | measure r[0] -> d[0]; 43 | measure q -> d; 44 | reset q; 45 | 46 | ctrl @ z q[0],q[1]; 47 | ctrl @ y q[0],q[1]; 48 | ctrl @ h q[0],q[1]; 49 | ctrl @ s q[0],q[1]; 50 | ctrl @ sdg q[0],q[1]; 51 | ctrl @ t q[0],q[1]; 52 | ctrl @ tdg q[0],q[1]; 53 | ctrl(2) @ x q[0],q[1],r[0]; 54 | ctrl @ rz(pi/8) q[0],q[1]; 55 | ctrl @ u1(pi/8) q[0],q[1]; 56 | ctrl @ u3(pi,0,pi) q[0],q[1]; 57 | swap q[0],q[1]; 58 | -------------------------------------------------------------------------------- /test/datastructures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreDS) 10 | file(GLOB_RECURSE DS_TEST_SOURCES *.cpp) 11 | package_add_test(mqt-core-ds-test MQT::CoreDS ${DS_TEST_SOURCES}) 12 | endif() 13 | -------------------------------------------------------------------------------- /test/datastructures/test_directed_acyclic_graph.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "datastructures/DirectedAcyclicGraph.hpp" 12 | 13 | #include <gtest/gtest.h> 14 | #include <vector> 15 | 16 | namespace qc { 17 | TEST(DirectedAcyclicGraph, Reachable) { 18 | DirectedAcyclicGraph<int> g; 19 | g.addVertex(0); 20 | g.addEdge(0, 1); 21 | g.addEdge(1, 2); 22 | g.addEdge(2, 3); 23 | EXPECT_ANY_THROW(g.addEdge(3, 1)); 24 | // 0 ────> 1 ———> 2 ———> 3 25 | // ^ | 26 | // └──────X──────┘ 27 | EXPECT_TRUE(g.isReachable(1, 3)); 28 | EXPECT_FALSE(g.isReachable(3, 1)); 29 | } 30 | 31 | TEST(DirectedAcyclicGraph, TopologicalOrder) { 32 | DirectedAcyclicGraph<int> g; 33 | g.addVertex(6); 34 | g.addVertex(2); 35 | g.addVertex(5); 36 | g.addVertex(4); 37 | g.addEdge(2, 6); 38 | g.addEdge(2, 5); 39 | g.addEdge(2, 4); 40 | g.addEdge(5, 6); 41 | g.addEdge(4, 6); 42 | g.addEdge(4, 5); 43 | // ┌─────────────┐ 44 | // ┌──────┼──────┐ │ 45 | // │ | v v 46 | // 2 ───> 4 ———> 5 ———> 6 47 | // │ ^ 48 | // └────────────────────┘ 49 | const auto& actual = g.orderTopologically(); 50 | const std::vector expected = {2, 4, 5, 6}; 51 | EXPECT_EQ(actual, expected); 52 | } 53 | } // namespace qc 54 | -------------------------------------------------------------------------------- /test/datastructures/test_directed_graph.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "datastructures/DirectedGraph.hpp" 12 | 13 | #include <gtest/gtest.h> 14 | #include <tuple> 15 | 16 | namespace qc { 17 | TEST(DirectedGraph, Numbered) { 18 | DirectedGraph<int> g; 19 | g.addVertex(0); 20 | g.addEdge(1, 1); 21 | g.addEdge(1, 2); 22 | g.addEdge(2, 3); 23 | g.addEdge(3, 1); 24 | // ┌────┐ 25 | // 0 └──> 1 ———> 2 ———> 3 26 | // ^ | 27 | // └─────────────┘ 28 | EXPECT_EQ(g.getNVertices(), 4); 29 | EXPECT_EQ(g.getNEdges(), 4); 30 | EXPECT_EQ(g.getInDegree(2), 1); 31 | EXPECT_EQ(g.getInDegree(1), 2); 32 | EXPECT_EQ(g.getOutDegree(2), 1); 33 | EXPECT_EQ(g.getOutDegree(1), 2); 34 | EXPECT_TRUE(g.isEdge(1, 2)); 35 | EXPECT_FALSE(g.isEdge(2, 1)); 36 | EXPECT_FALSE(g.isEdge(1, 0)); 37 | 38 | EXPECT_ANY_THROW(g.addVertex(1)); 39 | EXPECT_ANY_THROW(std::ignore = g.getInDegree(4)); 40 | EXPECT_ANY_THROW(std::ignore = g.getOutDegree(4)); 41 | } 42 | } // namespace qc 43 | -------------------------------------------------------------------------------- /test/datastructures/test_disjoint_set.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "datastructures/DisjointSet.hpp" 12 | 13 | #include <gtest/gtest.h> 14 | #include <vector> 15 | 16 | namespace qc { 17 | TEST(DisjointSet, FindSet) { 18 | std::vector elements = {1, 2, 3}; 19 | DisjointSet<int> ds(elements.begin(), elements.end()); 20 | EXPECT_EQ(ds.findSet(1), ds.findSet(1)); 21 | EXPECT_NE(ds.findSet(1), ds.findSet(2)); 22 | } 23 | 24 | TEST(DisjointSet, UnionSet) { 25 | std::vector elements = {1, 2, 3}; 26 | DisjointSet<int> ds(elements.begin(), elements.end()); 27 | ds.unionSet(1, 2); 28 | EXPECT_EQ(ds.findSet(1), ds.findSet(2)); 29 | EXPECT_NE(ds.findSet(1), ds.findSet(3)); 30 | EXPECT_NE(ds.findSet(2), ds.findSet(3)); 31 | ds.unionSet(1, 3); 32 | EXPECT_EQ(ds.findSet(1), ds.findSet(2)); 33 | EXPECT_EQ(ds.findSet(1), ds.findSet(3)); 34 | EXPECT_EQ(ds.findSet(2), ds.findSet(3)); 35 | } 36 | } // namespace qc 37 | -------------------------------------------------------------------------------- /test/datastructures/test_symmetric_matrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "datastructures/SymmetricMatrix.hpp" 12 | 13 | #include <cstddef> 14 | #include <gtest/gtest.h> 15 | #include <string> 16 | 17 | namespace qc { 18 | 19 | TEST(SymmetricMatrix, Constructors) { 20 | SymmetricMatrix<int> const m(3); 21 | EXPECT_EQ(m.size(), 3); 22 | SymmetricMatrix<int> m2(3, 1); 23 | EXPECT_EQ(m2.size(), 3); 24 | for (size_t i = 0; i < m2.size(); ++i) { 25 | for (size_t j = 0; j <= i; ++j) { 26 | EXPECT_EQ(m2(i, j), 1); 27 | EXPECT_EQ(m2(j, i), 1); 28 | } 29 | } 30 | } 31 | 32 | TEST(SymmetricMatrix, DifferentDataTypes) { 33 | SymmetricMatrix<double> const m(3); 34 | EXPECT_EQ(m.size(), 3); 35 | SymmetricMatrix<std::string> const m2(3, "1"); 36 | EXPECT_EQ(m2.size(), 3); 37 | EXPECT_EQ(m2(0, 2), m2(2, 0)); 38 | EXPECT_EQ(m2(0, 2), "1"); 39 | SymmetricMatrix<char> const m3(3, '1'); 40 | EXPECT_EQ(m3.size(), 3); 41 | EXPECT_EQ(m3(0, 1), m3(1, 0)); 42 | EXPECT_EQ(m3(0, 1), '1'); 43 | } 44 | 45 | TEST(SymmetricMatrix, Assignment) { 46 | SymmetricMatrix<int> m(3); 47 | m(0, 1) = 1; 48 | m(1, 2) = 2; 49 | m(0, 2) = 3; 50 | EXPECT_EQ(m(0, 1), 1); 51 | EXPECT_EQ(m(1, 0), 1); 52 | EXPECT_EQ(m(1, 2), 2); 53 | EXPECT_EQ(m(2, 1), 2); 54 | EXPECT_EQ(m(0, 2), 3); 55 | EXPECT_EQ(m(2, 0), 3); 56 | } 57 | 58 | } // namespace qc 59 | -------------------------------------------------------------------------------- /test/datastructures/test_undirected_graph.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 3 | * Copyright (c) 2025 Munich Quantum Software Company GmbH 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: MIT 7 | * 8 | * Licensed under the MIT License 9 | */ 10 | 11 | #include "datastructures/UndirectedGraph.hpp" 12 | 13 | #include <gtest/gtest.h> 14 | #include <stdexcept> 15 | #include <tuple> 16 | 17 | namespace qc { 18 | TEST(UndirectedGraph, Numbered) { 19 | UndirectedGraph<int, int> g; 20 | g.addVertex(0); 21 | g.addEdge(1, 1, 0); 22 | g.addEdge(1, 2, 1); 23 | g.addEdge(2, 3, 2); 24 | g.addEdge(3, 1, 3); 25 | EXPECT_EQ(g.getNVertices(), 4); 26 | EXPECT_EQ(g.getNEdges(), 4); 27 | EXPECT_EQ(g.getEdge(1, 2), 1); 28 | EXPECT_EQ(g.getEdge(1, 1), 0); 29 | EXPECT_EQ(g.getDegree(2), 2); 30 | EXPECT_EQ(g.getDegree(1), 3); 31 | EXPECT_TRUE(g.isAdjacent(1, 2)); 32 | EXPECT_FALSE(g.isAdjacent(1, 0)); 33 | EXPECT_TRUE(g.isAdjacentEdge({1, 2}, {2, 3})); 34 | 35 | EXPECT_THROW(g.addVertex(1), std::invalid_argument); 36 | EXPECT_THROW(g.addEdge(1, 2, 10), std::invalid_argument); 37 | EXPECT_THROW(g.addEdge(2, 1, 10), std::invalid_argument); 38 | EXPECT_THROW(std::ignore = g.getDegree(4), std::invalid_argument); 39 | EXPECT_THROW(std::ignore = g.getEdge(0, 1), std::invalid_argument); 40 | EXPECT_THROW(std::ignore = g.isAdjacent(0, 10), std::invalid_argument); 41 | EXPECT_THROW(std::ignore = g.isAdjacent(10, 1), std::invalid_argument); 42 | } 43 | } // namespace qc 44 | -------------------------------------------------------------------------------- /test/dd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreDD) 10 | file(GLOB_RECURSE DD_TEST_SOURCES *.cpp) 11 | package_add_test(mqt-core-dd-test MQT::CoreDD ${DD_TEST_SOURCES}) 12 | target_link_libraries(mqt-core-dd-test PRIVATE MQT::CoreCircuitOptimizer) 13 | target_link_libraries(mqt-core-dd-test PRIVATE MQT::CoreQASM) 14 | endif() 15 | -------------------------------------------------------------------------------- /test/ir/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreIR) 10 | file(GLOB_RECURSE IR_TEST_SOURCES *.cpp) 11 | package_add_test_with_working_dir(mqt-core-ir-test MQT::CoreIR ${CMAKE_CURRENT_BINARY_DIR} 12 | ${IR_TEST_SOURCES}) 13 | target_link_libraries(mqt-core-ir-test PRIVATE MQT::CoreQASM) 14 | endif() 15 | -------------------------------------------------------------------------------- /test/na/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreNA) 10 | file(GLOB_RECURSE NA_TEST_SOURCES *.cpp) 11 | package_add_test(mqt-core-na-test MQT::CoreNA ${NA_TEST_SOURCES}) 12 | target_link_libraries(mqt-core-na-test PRIVATE MQT::CoreQASM) 13 | endif() 14 | -------------------------------------------------------------------------------- /test/python/dd/evaluation/results_baseline.json: -------------------------------------------------------------------------------- 1 | { 2 | "BV": { 3 | "Functionality": { 4 | "1024": { 5 | "dd": { 6 | "active_memory_mib": 0.26538848876953125, 7 | "compute_tables": { 8 | "matrix_add": { 9 | "col_ratio": 0.005506607929515419, 10 | "collisions": 45, 11 | "hit_ratio": 0.5, 12 | "hits": 4086, 13 | "inserts": 4041, 14 | "load_factor": 0.0283203125, 15 | "lookups": 8172, 16 | "memory_MiB": 1.125, 17 | "num_buckets": 0, 18 | "num_entries": 0, 19 | "peak_num_entries": "unused" 20 | } 21 | } 22 | }, 23 | "runtime": 1.2 24 | }, 25 | "256": { 26 | "dd": { 27 | "active_memory_mib": 0.06616973876953125, 28 | "compute_tables": { 29 | "matrix_add": { 30 | "col_ratio": 0.008893280632411068, 31 | "collisions": 18 32 | } 33 | }, 34 | "matrix": { 35 | "unique_table": { 36 | "total": { 37 | "col_ratio": 0.00514176735528262, 38 | "collisions": 2475 39 | } 40 | } 41 | } 42 | }, 43 | "runtime": 0.440665166 44 | } 45 | }, 46 | "Simulation": { 47 | "256": { 48 | "dd": { 49 | "active_memory_mib": 0.021484375, 50 | "matrix": { 51 | "unique_table": { 52 | "total": { 53 | "col_ratio": 0.0029885811069223626, 54 | "collisions": 1094 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | }, 62 | "GHZ": { 63 | "Functionality": { 64 | "512": { 65 | "dd": { 66 | "compute_tables": { 67 | "matrix_add": { 68 | "col_ratio": 0.011530912659470068, 69 | "collisions": 47 70 | } 71 | } 72 | }, 73 | "runtime": 0.2 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /test/python/dd/evaluation/results_feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "BV": { 3 | "Functionality": { 4 | "1024": { 5 | "dd": { 6 | "active_memory_mib": 0.26538848876953125, 7 | "compute_tables": { 8 | "matrix_add": { 9 | "col_ratio": 0.00648556045031816, 10 | "collisions": 53, 11 | "hit_ratio": 0.8, 12 | "hits": 2000, 13 | "inserts": 4033, 14 | "load_factor": 0.028564453125, 15 | "lookups": 0, 16 | "num_buckets": 16384, 17 | "num_entries": 0, 18 | "peak_num_entries": 767 19 | } 20 | } 21 | }, 22 | "runtime": 0.579 23 | }, 24 | "256": { 25 | "dd": { 26 | "active_memory_mib": 0.06616973876953125, 27 | "compute_tables": { 28 | "matrix_add": { 29 | "col_ratio": 0.004940711462450593, 30 | "collisions": 10, 31 | "num_buckets": 16384 32 | } 33 | }, 34 | "matrix": { 35 | "unique_table": { 36 | "total": { 37 | "col_ratio": 0.0038910748341151494, 38 | "collisions": 1873 39 | } 40 | } 41 | } 42 | }, 43 | "runtime": 0.4284935 44 | } 45 | }, 46 | "Simulation": { 47 | "256": { 48 | "dd": { 49 | "active_memory_mib": 0.021484375, 50 | "matrix": { 51 | "unique_table": { 52 | "total": { 53 | "col_ratio": 0.0009288094847839152, 54 | "collisions": 340 55 | } 56 | } 57 | } 58 | }, 59 | "runtime": 0.56 60 | } 61 | } 62 | }, 63 | "GHZ": { 64 | "Functionality": { 65 | "512": { 66 | "dd": { 67 | "compute_tables": { 68 | "matrix_add": { 69 | "col_ratio": 0.009077526987242394, 70 | "collisions": 37 71 | } 72 | } 73 | }, 74 | "runtime": 0.4284935 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /test/python/dd/test_dd_package.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | """Tests for the MQT Core DD package.""" 10 | 11 | from __future__ import annotations 12 | 13 | import numpy as np 14 | 15 | from mqt.core.dd import DDPackage, build_functionality, sample, simulate 16 | from mqt.core.ir import QuantumComputation 17 | from mqt.core.ir.operations import OpType 18 | 19 | 20 | def test_sample_simple_circuit() -> None: 21 | """Test sampling a simple circuit.""" 22 | qc = QuantumComputation(2) 23 | qc.x(0) 24 | qc.measure_all() 25 | 26 | shots = 1000 27 | results = sample(qc, shots) 28 | assert results == {"01": shots} 29 | 30 | 31 | def test_sample_dynamic_circuit() -> None: 32 | """Test sampling a dynamic circuit.""" 33 | qc = QuantumComputation(1, 1) 34 | # put the qubit into superposition 35 | qc.h(0) 36 | # reset the qubit 37 | qc.measure(0, 0) 38 | qc.classic_controlled(OpType.x, target=0, cbit=0, expected_value=1) 39 | # flip to |1> 40 | qc.x(0) 41 | # measure the qubit 42 | qc.measure(0, 0) 43 | 44 | shots = 1000 45 | results = sample(qc, shots) 46 | assert results == {"1": shots} 47 | 48 | 49 | def test_build_functionality_simple_circuit() -> None: 50 | """Test building functionality for a simple circuit.""" 51 | qc = QuantumComputation(2) 52 | qc.h(0) 53 | qc.cx(0, 1) 54 | 55 | p = DDPackage(2) 56 | 57 | functionality = build_functionality(qc, p) 58 | mat = functionality.get_matrix(2) 59 | arr = np.array(mat, copy=False) 60 | assert arr.shape == (4, 4) 61 | assert np.allclose(arr, np.array([[1, 1, 0, 0], [0, 0, 1, -1], [0, 0, 1, 1], [1, -1, 0, 0]]) / np.sqrt(2)) 62 | 63 | 64 | def test_simulate_simple_circuit() -> None: 65 | """Test simulating a simple circuit.""" 66 | qc = QuantumComputation(2) 67 | qc.h(0) 68 | qc.cx(0, 1) 69 | 70 | p = DDPackage(2) 71 | in_state = p.zero_state(2) 72 | 73 | out_state = simulate(qc, in_state, p) 74 | vec = out_state.get_vector() 75 | arr = np.array(vec, copy=False) 76 | assert arr.shape == (4,) 77 | assert np.allclose(arr, np.array([1, 0, 0, 1]) / np.sqrt(2)) 78 | -------------------------------------------------------------------------------- /test/python/ir/test_ir.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | """Test the quantum computation IR.""" 10 | 11 | from __future__ import annotations 12 | 13 | from mqt.core.ir import QuantumComputation 14 | 15 | 16 | def test_bell_state_circuit() -> None: 17 | """Test the creation of a Bell state circuit.""" 18 | qc = QuantumComputation() 19 | q = qc.add_qubit_register(2) 20 | c = qc.add_classical_register(2) 21 | 22 | qc.h(q[0]) 23 | qc.cx(q[0], q[1]) 24 | qc.measure(q[0], c[0]) 25 | qc.measure(q[1], c[1]) 26 | 27 | qasm = qc.qasm3_str() 28 | expected = """ 29 | // i 0 1 30 | // o 0 1 31 | OPENQASM 3.0; 32 | include "stdgates.inc"; 33 | qubit[2] q; 34 | bit[2] c; 35 | h q[0]; 36 | cx q[0], q[1]; 37 | c[0] = measure q[0]; 38 | c[1] = measure q[1]; 39 | """ 40 | # Remove all whitespace from both strings before comparison 41 | assert "".join(qasm.split()) == "".join(expected.split()) 42 | -------------------------------------------------------------------------------- /test/zx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 - 2025 Chair for Design Automation, TUM 2 | # Copyright (c) 2025 Munich Quantum Software Company GmbH 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: MIT 6 | # 7 | # Licensed under the MIT License 8 | 9 | if(TARGET MQT::CoreZX) 10 | file(GLOB_RECURSE ZX_TEST_SOURCES *.cpp) 11 | package_add_test(mqt-core-zx-test MQT::CoreZX ${ZX_TEST_SOURCES}) 12 | target_link_libraries(mqt-core-zx-test PRIVATE MQT::CoreQASM) 13 | endif() 14 | --------------------------------------------------------------------------------