diff --git a/.github/codecov.yml b/.github/codecov.yml index 11bcfe0257..2f6d5612c9 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -26,6 +26,7 @@ flag_management: paths: - "include" - "src" + - "mlir" - name: python paths: - "python/mqt/**/*.py" @@ -36,16 +37,6 @@ flag_management: - type: patch target: 95% threshold: 1% - - name: mlir - paths: - - "mlir" - statuses: - - type: project - threshold: 0.5% - removed_code_behavior: adjust_base - - type: patch - target: 95% - threshold: 1% parsers: gcov: diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index aa18432c9e..a14569ea15 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -12,7 +12,7 @@ permissions: jobs: build-sdist: name: 🐍 Packaging - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-sdist.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-sdist.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 # Builds wheels on all supported platforms using cibuildwheel. # The wheels are uploaded as GitHub artifacts `dev-cibw-*` or `cibw-*`, depending on whether @@ -31,7 +31,7 @@ jobs: windows-2025, windows-11-arm, ] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-wheel-cibuildwheel.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-wheel-cibuildwheel.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec976ab18d..dbbf0f0e58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ concurrency: jobs: change-detection: name: 🔍 Change - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-change-detection.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-change-detection.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 cpp-tests-ubuntu: name: 🇨‌ Test 🐧 @@ -30,11 +30,13 @@ jobs: - runs-on: ubuntu-24.04 compiler: gcc config: Debug - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-ubuntu.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-ubuntu.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} compiler: ${{ matrix.compiler }} config: ${{ matrix.config }} + setup-mlir: true + llvm-version: 21.1.8 cpp-tests-macos: name: 🇨‌ Test 🍎 @@ -50,12 +52,14 @@ jobs: - runs-on: macos-15 compiler: clang config: Debug - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-macos.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-macos.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} compiler: ${{ matrix.compiler }} config: ${{ matrix.config }} cmake-args: -DMQT_CORE_WITH_GMP=ON + setup-mlir: true + llvm-version: 21.1.8 cpp-tests-windows: name: 🇨‌ Test 🏁 @@ -71,11 +75,13 @@ jobs: - runs-on: windows-2025 compiler: msvc config: Debug - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-windows.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-windows.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} compiler: ${{ matrix.compiler }} config: ${{ matrix.config }} + setup-mlir: true + llvm-version: 21.1.8 # run extensive C++ tests on PRs labeled with the `extensive-cpp-ci` label cpp-tests-extensive-ubuntu: @@ -88,11 +94,13 @@ jobs: runs-on: [ubuntu-24.04, ubuntu-24.04-arm] compiler: [gcc, clang, clang-20, clang-21] config: [Release, Debug] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-ubuntu.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-ubuntu.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} compiler: ${{ matrix.compiler }} config: ${{ matrix.config }} + setup-mlir: true + llvm-version: 21.1.8 # run extensive C++ tests on PRs labeled with the `extensive-cpp-ci` label cpp-tests-extensive-macos: @@ -105,12 +113,14 @@ jobs: runs-on: [macos-14, macos-15, macos-15-intel] compiler: [clang, clang-20, clang-21, gcc-14, gcc-15] config: [Release, Debug] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-macos.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-macos.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} compiler: ${{ matrix.compiler }} config: ${{ matrix.config }} cmake-args: -DMQT_CORE_WITH_GMP=ON + setup-mlir: true + llvm-version: 21.1.8 # run extensive C++ tests on PRs labeled with the `extensive-cpp-ci` label cpp-tests-extensive-windows: @@ -122,18 +132,23 @@ jobs: matrix: runs-on: [windows-2022, windows-2025, windows-11-arm] compiler: [msvc, clang] - config: [Release] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-windows.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + config: [Release, Debug] + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-tests-windows.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} compiler: ${{ matrix.compiler }} config: ${{ matrix.config }} + setup-mlir: true + llvm-version: 21.1.8 cpp-coverage: name: 🇨‌ Coverage needs: change-detection if: fromJSON(needs.change-detection.outputs.run-cpp-tests) - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-coverage.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-coverage.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 + with: + setup-mlir: true + llvm-version: 21.1.8 permissions: contents: read id-token: write @@ -142,9 +157,9 @@ jobs: name: 🇨‌ Lint needs: change-detection if: fromJSON(needs.change-detection.outputs.run-cpp-linter) - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-linter.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-cpp-linter.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: - cmake-args: -DBUILD_MQT_CORE_BENCHMARKS=ON -DBUILD_MQT_CORE_MLIR=ON -DBUILD_MQT_CORE_BINDINGS=ON + cmake-args: -DBUILD_MQT_CORE_BENCHMARKS=ON -DBUILD_MQT_CORE_BINDINGS=ON clang-version: 21 build-project: true files-changed-only: true @@ -152,6 +167,7 @@ jobs: install-pkgs: "nanobind==2.10.2" cpp-linter-extra-args: "-std=c++20" setup-mlir: true + llvm-version: 21.1.8 python-tests: name: 🐍 Test @@ -168,7 +184,7 @@ jobs: macos-15, windows-2025, ] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-tests.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-tests.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} @@ -176,7 +192,7 @@ jobs: name: 🐍 Coverage needs: [change-detection, python-tests] if: fromJSON(needs.change-detection.outputs.run-python-tests) - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-coverage.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-coverage.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 permissions: contents: read id-token: write @@ -190,7 +206,7 @@ jobs: fail-fast: false matrix: runs-on: [macos-14, windows-2022] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-tests.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-tests.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} @@ -198,7 +214,7 @@ jobs: name: 🐍 Lint needs: change-detection if: fromJSON(needs.change-detection.outputs.run-python-tests) - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-linter.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-linter.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: check-stubs: true enable-ty: true @@ -207,7 +223,7 @@ jobs: name: 🚀 CD needs: change-detection if: fromJSON(needs.change-detection.outputs.run-cd) - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-sdist.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-sdist.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 build-wheel: name: 🚀 CD @@ -225,16 +241,10 @@ jobs: windows-2025, windows-11-arm, ] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-wheel-cibuildwheel.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-packaging-wheel-cibuildwheel.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} - mlir-tests: - name: 🐉 Test - needs: change-detection - if: fromJSON(needs.change-detection.outputs.run-mlir) - uses: ./.github/workflows/reusable-mlir-tests.yml - # this job does nothing and is only used for branch protection required-checks-pass: name: 🚦 Check @@ -254,7 +264,6 @@ jobs: - python-linter - build-sdist - build-wheel - - mlir-tests runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed @@ -289,8 +298,4 @@ jobs: fromJSON(needs.change-detection.outputs.run-cd) && '' || 'build-sdist,build-wheel,' }} - ${{ - fromJSON(needs.change-detection.outputs.run-mlir) - && '' || 'mlir-tests,' - }} jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/reusable-mlir-tests.yml b/.github/workflows/reusable-mlir-tests.yml deleted file mode 100644 index f389443dd6..0000000000 --- a/.github/workflows/reusable-mlir-tests.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: 🐉 • Tests -on: - workflow_call: - -jobs: - mlir: - name: >- - ${{ contains(matrix.os, 'ubuntu') && '🐧' || contains(matrix.os, 'windows') && '🏁' || '🍎' }} - ${{ matrix.coverage && 'Coverage' || matrix.os }} - runs-on: ${{ matrix.os }} - permissions: - contents: read - id-token: write - strategy: - fail-fast: false - matrix: - os: - [ - ubuntu-24.04, - ubuntu-24.04-arm, - macos-15-intel, - macos-15, - windows-2025, - windows-11-arm, - ] - coverage: [false] - include: - - os: ubuntu-24.04 - coverage: true - env: - CMAKE_BUILD_PARALLEL_LEVEL: 4 - CTEST_PARALLEL_LEVEL: 4 - FORCE_COLOR: 3 - steps: - - name: Checkout - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - fetch-depth: 0 - - - name: Set up MLIR - uses: munich-quantum-software/setup-mlir@81729fff6f2b938a65a059b7401cb9b0144afcaa # v1.0.1 - with: - llvm-version: 21.1.8 - - # Build acceleration and Python tooling - - name: Set up mold as linker (Linux) - uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 # v1 - - - name: Install the latest version of uv - uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6 - with: - python-version: 3.13 - activate-environment: true - enable-cache: true - save-cache: ${{ github.ref == 'refs/heads/main' }} - - - name: Install Ninja - run: uv tool install ninja - - - name: Install lit - run: uv pip install lit - - # Configure - - name: Configure CMake (Linux and macOS) - if: runner.os == 'Linux' || runner.os == 'macOS' - run: | - cmake -G Ninja -S . -B build \ - -DCMAKE_BUILD_TYPE=${{ matrix.coverage && 'Debug' || 'Release' }} \ - -DBUILD_MQT_CORE_MLIR=ON \ - -DLLVM_EXTERNAL_LIT=$(which lit) \ - ${{ matrix.coverage && '-DENABLE_COVERAGE=ON' || '' }} - - - name: Configure CMake (Windows) - if: runner.os == 'Windows' - run: | - cmake -S . -B build ` - -DCMAKE_BUILD_TYPE=${{ matrix.coverage && 'Debug' || 'Release' }} ` - -DBUILD_MQT_CORE_MLIR=ON ` - -DLLVM_EXTERNAL_LIT=${{ github.workspace }}\.venv\Scripts\lit.exe ` - ${{ matrix.coverage && '-DENABLE_COVERAGE=ON' || '' }} - - # Build - - name: Build MLIR lit target - run: cmake --build build --config ${{ matrix.coverage && 'Debug' || 'Release' }} --target mqt-core-mlir-lit-test-build-only - - - name: Build MLIR unittests - run: cmake --build build --config ${{ matrix.coverage && 'Debug' || 'Release' }} --target mqt-core-mlir-unittests - - # Test - - name: Run lit tests - run: cmake --build build --config ${{ matrix.coverage && 'Debug' || 'Release' }} --target mqt-core-mlir-lit-test - - - name: Run unit tests - run: ctest -C ${{ matrix.coverage && 'Debug' || 'Release' }} --output-on-failure --test-dir build/mlir --repeat until-pass:3 --timeout 600 - - # Coverage - - name: Generate coverage data as JSON (gcovr) - if: matrix.coverage - run: | - uvx gcovr \ - --gcov-executable "llvm-cov gcov" \ - --exclude build \ - --exclude-unreachable-branches \ - --exclude-noncode-lines \ - --exclude-throw-branches \ - --print-summary \ - --keep \ - --json \ - -o mlir-coverage.json - - - name: Upload coverage to Codecov - if: matrix.coverage - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 - with: - flags: mlir - name: mlir-coverage - fail_ci_if_error: true - use_oidc: true - files: mlir-coverage.json diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml index d8e651e6a1..a32e190874 100644 --- a/.github/workflows/upstream.yml +++ b/.github/workflows/upstream.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: runs-on: [ubuntu-24.04, macos-14, windows-2022] - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-qiskit-upstream-tests.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-qiskit-upstream-tests.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: runs-on: ${{ matrix.runs-on }} setup-z3: true @@ -28,7 +28,7 @@ jobs: name: Create issue on failure needs: qiskit-upstream-tests if: ${{ always() }} - uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-qiskit-upstream-issue.yml@99170045e26c2564e9573174b573310e211fca72 # v1.17.10 + uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-qiskit-upstream-issue.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11 with: tests-result: ${{ needs.qiskit-upstream-tests.result }} permissions: diff --git a/.license-tools-config.json b/.license-tools-config.json index 1172b134ef..972fa097cd 100644 --- a/.license-tools-config.json +++ b/.license-tools-config.json @@ -4,6 +4,7 @@ "years": [2023, 2025] }, "force_author": true, + "force_license": true, "license": "MIT", "title": false, "include": ["**/*"], diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 76076e39ee..3a7dc55fad 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,14 +9,11 @@ sphinx: build: os: ubuntu-24.04 tools: - python: "3.12" + python: "3.13" apt_packages: - - libmlir-19-dev - - mlir-19-tools - - clang-19 - - clang-tools-19 - graphviz - inkscape + - zstd jobs: post_checkout: # Skip docs build if the commit message contains "skip ci" @@ -34,13 +31,15 @@ build: - asdf plugin add uv - asdf install uv latest - asdf global uv latest + # Install MLIR + - curl -LsSf https://github.com/munich-quantum-software/setup-mlir/releases/latest/download/setup-mlir.sh | bash -s -- -v 21.1.8 -p $HOME/mlir # Build the MLIR documentation - - uvx cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_MQT_CORE_MLIR=ON -DMQT_MLIR_MIN_VERSION=19.0 -DMLIR_DIR=/usr/lib/llvm-19/lib/cmake/mlir -DLLVM_DIR=/usr/lib/llvm-19/lib/cmake/llvm + - uvx cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_MQT_CORE_MLIR=ON -DMLIR_DIR=$HOME/mlir/lib/cmake/mlir - uvx cmake --build build --target mlir-doc build: html: - - uv run --frozen --no-dev --group docs -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html + - MLIR_DIR=$HOME/mlir/lib/cmake/mlir uv run --frozen --no-dev --group docs -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html htmlzip: - - uv run --frozen --no-dev --group docs -m sphinx -T -b dirhtml -d docs/_build/doctrees -D language=en docs docs/_build/dirhtml + - MLIR_DIR=$HOME/mlir/lib/cmake/mlir uv run --frozen --no-dev --group docs -m sphinx -T -b dirhtml -d docs/_build/doctrees -D language=en docs docs/_build/dirhtml - mkdir -p $READTHEDOCS_OUTPUT/htmlzip - zip -r $READTHEDOCS_OUTPUT/htmlzip/html.zip docs/_build/dirhtml/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 117115556c..634dffdbaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel ### Changed +- 📦 Build MLIR by default for C++ library builds ([#1356]) ([**@burgholzer**], [**@denialhaag**]) - 📦🏁 Build Windows x86 wheels on windows-2025 runner for newer compiler ([#1415]) ([**@burgholzer**]) - 👷 Build on `macos-15`/`windows-2025` by default and `macos-14`/`windows-2022` for extensive tests ([#1414]) ([**@burgholzer**]) - 📦🍎 Build macOS arm64 wheels on macos-15 runner for newer compiler ([#1413]) ([**@burgholzer**]) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86f93ccc8e..bcf3ef907b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,29 @@ endif() set(MQT_CORE_TARGET_NAME "mqt-core") -option(BUILD_MQT_CORE_MLIR "Build the MLIR submodule of the MQT Core project" OFF) +option(BUILD_MQT_CORE_MLIR "Build the MLIR submodule of the MQT Core project" ON) +if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(BUILD_MQT_CORE_MLIR + OFF + CACHE BOOL + "Disable MLIR build on macOS with GCC to avoid ABI issues between STL and libstdc++" + FORCE) + message( + WARNING "Disabling MLIR build on macOS with GCC to avoid ABI issues between STL and libstdc++") +endif() +if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "17.0.0") + set(BUILD_MQT_CORE_MLIR + OFF + CACHE + BOOL + "Disable MLIR build on macOS with Apple Clang < 17 due to missing complete C++20 support" + FORCE) + message( + WARNING + "Disabling MLIR build on macOS with Apple Clang < 17 due to missing complete C++20 support") + endif() +endif() if(BUILD_MQT_CORE_MLIR) include(SetupMLIR) endif() diff --git a/UPGRADING.md b/UPGRADING.md index 803baa54e2..9a3cc9d634 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -4,6 +4,26 @@ This document describes breaking changes and how to upgrade. For a complete list ## [Unreleased] +### MLIR enabled by default for C++ builds + +The MLIR-based functionality within MQT Core has long been experimental and opt-in. +Starting with this release, MLIR is enabled by default for C++ library builds. +This means that LLVM (including MLIR) is now a required dependency for building MQT Core from source. + +We offer pre-built distributions for all supported platforms as part of the `setup-mlir` project at [munich-quantum-software/setup-mlir](https://github.com/munich-quantum-software/setup-mlir). +Please follow the instructions there to install the distribution for your platform. +You can then point CMake to the installation directory using the `-DMLIR_DIR=/path/to/mlir/installation/lib/cmake/mlir` option. + +The MLIR components can still be manually disabled by passing `-DBUILD_MQT_CORE_MLIR=OFF` to CMake. +MLIR is also not enabled for the Python package builds because no functionality depends on it yet. +This is expected to change in the future, when we expose the MLIR-based functionality via the Python package. + +Known limitations: + +- Our pre-built distributions are incompatible with GCC on macOS. Use (Apple)Clang instead or compile LLVM from source using your preferred compiler. +- AppleClang 17+ is required to build MQT Core with MLIR enabled due to some C++20 features being used that are not yet properly supported by older versions. +- Our pre-built distributions are compiled in Release mode. On Windows, this leads to ABI incompatibilities with debug builds. Either build in Release mode or build LLVM from source in Debug mode to resolve this. + ### QDMI-Qiskit integration This release introduces a Qiskit `BackendV2`-compatible interface to QDMI devices. diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 9c83db77ca..f4d694cec8 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -20,11 +20,14 @@ function(enable_project_options target_name) endif() if(MSVC) - target_compile_options(${target_name} INTERFACE /utf-8 /Zm10) + target_compile_options(${target_name} INTERFACE /utf-8 /Zm10 /EHsc) else() # always include debug symbols (avoids common problems with LTO) target_compile_options(${target_name} INTERFACE -g) + # ensure that exceptions are enabled + target_compile_options(${target_name} INTERFACE -fexceptions) + # enable coverage collection options option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) if(ENABLE_COVERAGE) diff --git a/cmake/SetupMLIR.cmake b/cmake/SetupMLIR.cmake index 096f48d739..1dea4707ef 100644 --- a/cmake/SetupMLIR.cmake +++ b/cmake/SetupMLIR.cmake @@ -29,6 +29,8 @@ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") include(TableGen) include(AddLLVM) include(AddMLIR) +set(LLVM_ENABLE_RTTI ON) +set(LLVM_ENABLE_EH ON) include(HandleLLVMOptions) include_directories(${LLVM_INCLUDE_DIRS}) diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index ffeb8670e8..029da1939a 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -37,6 +37,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") add_compile_options(-fcolor-diagnostics) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options(-fdiagnostics-color=always) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/diagnostics:color) else() message(STATUS "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler.") endif() diff --git a/eval/dd_evaluation.py b/eval/dd_evaluation.py index bd46847a12..f8c825dea1 100755 --- a/eval/dd_evaluation.py +++ b/eval/dd_evaluation.py @@ -6,7 +6,7 @@ # SPDX-License-Identifier: MIT # # Licensed under the MIT License -# + # /// script # requires-python = ">=3.10" # dependencies = [ diff --git a/include/mqt-core/qdmi/na/Generator.hpp b/include/mqt-core/qdmi/na/Generator.hpp index 40f0221cb5..c8803f46fc 100644 --- a/include/mqt-core/qdmi/na/Generator.hpp +++ b/include/mqt-core/qdmi/na/Generator.hpp @@ -186,12 +186,12 @@ struct Device { * @brief The interaction radius of the operation within which two qubits * can interact. */ - uint64_t interactionRadius = 0.0; + uint64_t interactionRadius = 0; /** * @brief The blocking radius of the operation within which no other * operation can be performed to avoid interference. */ - uint64_t blockingRadius = 0.0; + uint64_t blockingRadius = 0; /// @brief The number of qubits involved in the operation. uint64_t numQubits = 0; diff --git a/include/mqt-core/qir/runtime/QIR.h b/include/mqt-core/qir/runtime/QIR.h index f67818d681..b6275edec1 100644 --- a/include/mqt-core/qir/runtime/QIR.h +++ b/include/mqt-core/qir/runtime/QIR.h @@ -70,7 +70,7 @@ Array* __quantum__rt__array_create_1d(int32_t, int64_t); int64_t __quantum__rt__array_get_size_1d(const Array*); /// Returns a pointer to the element of the array at the zero-based index given -/// by the int64_t. +/// by the int64_t. Returns nullptr if the index is out of bounds. int8_t* __quantum__rt__array_get_element_ptr_1d(Array*, int64_t); /// Adds the given integer value to the reference count for the array. diff --git a/include/mqt-core/qir/runtime/Runtime.hpp b/include/mqt-core/qir/runtime/Runtime.hpp index 4d1272dd78..1108cd7a80 100644 --- a/include/mqt-core/qir/runtime/Runtime.hpp +++ b/include/mqt-core/qir/runtime/Runtime.hpp @@ -190,18 +190,18 @@ class Utils { */ class Runtime { public: - static constexpr auto RESULT_ZERO_ADDRESS = 0x10000; - static constexpr auto RESULT_ONE_ADDRESS = 0x10001; + static constexpr uintptr_t RESULT_ZERO_ADDRESS = 0x10000; + static constexpr uintptr_t RESULT_ONE_ADDRESS = 0x10001; private: - static constexpr auto MIN_DYN_QUBIT_ADDRESS = 0x10000; + static constexpr uintptr_t MIN_DYN_QUBIT_ADDRESS = 0x10000; enum class AddressMode : uint8_t { UNKNOWN, DYNAMIC, STATIC }; AddressMode addressMode; std::unordered_map qRegister; // swap gates are not executed, they are tracked here std::vector qubitPermutation; - static constexpr auto MIN_DYN_RESULT_ADDRESS = 0x10000; + static constexpr uintptr_t MIN_DYN_RESULT_ADDRESS = 0x10000; std::unordered_map rRegister; uintptr_t currentMaxQubitAddress; qc::Qubit currentMaxQubitId; diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index 70879df3de..cc9b2d709c 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -10,6 +10,10 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "C++ standard to conform to") +if(MSVC) + add_compile_definitions(_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING) +endif() + if(ENABLE_COVERAGE) add_compile_options(--coverage -O0) add_link_options(--coverage) diff --git a/mlir/include/mlir/Dialect/MQTOpt/IR/MQTOptDialect.h b/mlir/include/mlir/Dialect/MQTOpt/IR/MQTOptDialect.h index e6aabed593..7e330c02d9 100644 --- a/mlir/include/mlir/Dialect/MQTOpt/IR/MQTOptDialect.h +++ b/mlir/include/mlir/Dialect/MQTOpt/IR/MQTOptDialect.h @@ -14,12 +14,12 @@ // Suppress warnings about ambiguous reversed operators in MLIR // (see https://github.com/llvm/llvm-project/issues/45853) -#if defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wambiguous-reversed-operator" #endif #include "mlir/Interfaces/InferTypeOpInterface.h" -#if defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic pop #endif diff --git a/mlir/include/mlir/Dialect/QC/IR/QCDialect.h b/mlir/include/mlir/Dialect/QC/IR/QCDialect.h index f07fc0afe0..1c9a637ab8 100644 --- a/mlir/include/mlir/Dialect/QC/IR/QCDialect.h +++ b/mlir/include/mlir/Dialect/QC/IR/QCDialect.h @@ -12,12 +12,12 @@ // Suppress warnings about ambiguous reversed operators in MLIR // (see https://github.com/llvm/llvm-project/issues/45853) -#if defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wambiguous-reversed-operator" #endif #include -#if defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic pop #endif diff --git a/mlir/include/mlir/Dialect/QCO/IR/QCODialect.h b/mlir/include/mlir/Dialect/QCO/IR/QCODialect.h index d1087ab6f7..6faeba9938 100644 --- a/mlir/include/mlir/Dialect/QCO/IR/QCODialect.h +++ b/mlir/include/mlir/Dialect/QCO/IR/QCODialect.h @@ -12,12 +12,12 @@ // Suppress warnings about ambiguous reversed operators in MLIR // (see https://github.com/llvm/llvm-project/issues/45853) -#if defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wambiguous-reversed-operator" #endif #include -#if defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic pop #endif diff --git a/mlir/lib/Compiler/CMakeLists.txt b/mlir/lib/Compiler/CMakeLists.txt index 1e4483754d..ca566825da 100644 --- a/mlir/lib/Compiler/CMakeLists.txt +++ b/mlir/lib/Compiler/CMakeLists.txt @@ -21,7 +21,8 @@ add_mlir_library( QCOToQC QCToQIR MQT::MLIRSupport - MQT::ProjectOptions) + MQT::ProjectOptions + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE COMPILER_HEADERS_SOURCE "${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Compiler/*.h") diff --git a/mlir/lib/Conversion/MQTOptToMQTRef/CMakeLists.txt b/mlir/lib/Conversion/MQTOptToMQTRef/CMakeLists.txt index 0b8e9cc3c3..9d82c52f66 100644 --- a/mlir/lib/Conversion/MQTOptToMQTRef/CMakeLists.txt +++ b/mlir/lib/Conversion/MQTOptToMQTRef/CMakeLists.txt @@ -8,4 +8,16 @@ file(GLOB CONVERSION_SOURCES *.cpp) -add_mlir_library(MQTOptToMQTRef ${CONVERSION_SOURCES} DEPENDS MQTOptToMQTRefIncGen) +add_mlir_library( + MQTOptToMQTRef + ${CONVERSION_SOURCES} + DEPENDS + MQTOptToMQTRefIncGen + LINK_LIBS + MLIRMQTOpt + MLIRMQTRef + MLIRMemRefDialect + MLIRTransforms + MLIRFuncDialect + MLIRFuncTransforms + DISABLE_INSTALL) diff --git a/mlir/lib/Conversion/MQTRefToMQTOpt/CMakeLists.txt b/mlir/lib/Conversion/MQTRefToMQTOpt/CMakeLists.txt index d08135c396..decb9c0ca6 100644 --- a/mlir/lib/Conversion/MQTRefToMQTOpt/CMakeLists.txt +++ b/mlir/lib/Conversion/MQTRefToMQTOpt/CMakeLists.txt @@ -8,4 +8,16 @@ file(GLOB CONVERSION_SOURCES *.cpp) -add_mlir_library(MQTRefToMQTOpt ${CONVERSION_SOURCES} DEPENDS MQTRefToMQTOptIncGen) +add_mlir_library( + MQTRefToMQTOpt + ${CONVERSION_SOURCES} + DEPENDS + MQTRefToMQTOptIncGen + LINK_LIBS + MLIRMQTOpt + MLIRMQTRef + MLIRMemRefDialect + MLIRTransforms + MLIRFuncDialect + MLIRFuncTransforms + DISABLE_INSTALL) diff --git a/mlir/lib/Conversion/MQTRefToQIR/CMakeLists.txt b/mlir/lib/Conversion/MQTRefToQIR/CMakeLists.txt index 5336be4af6..50da77a5e0 100644 --- a/mlir/lib/Conversion/MQTRefToQIR/CMakeLists.txt +++ b/mlir/lib/Conversion/MQTRefToQIR/CMakeLists.txt @@ -8,4 +8,16 @@ file(GLOB CONVERSION_SOURCES *.cpp) -add_mlir_library(MQTRefToQIR ${CONVERSION_SOURCES} DEPENDS MQTRefToQIRIncGen) +add_mlir_library( + MQTRefToQIR + ${CONVERSION_SOURCES} + DEPENDS + MQTRefToQIRIncGen + LINK_LIBS + MLIRMQTRef + MLIRMemRefDialect + MLIRTransforms + MLIRLLVMDialect + MLIRFuncToLLVM + MLIRReconcileUnrealizedCasts + DISABLE_INSTALL) diff --git a/mlir/lib/Conversion/QCOToQC/CMakeLists.txt b/mlir/lib/Conversion/QCOToQC/CMakeLists.txt index 1c4a8d1f0a..198096656d 100644 --- a/mlir/lib/Conversion/QCOToQC/CMakeLists.txt +++ b/mlir/lib/Conversion/QCOToQC/CMakeLists.txt @@ -14,8 +14,10 @@ add_mlir_library( DEPENDS QCOToQCIncGen LINK_LIBS - PUBLIC MLIRQCDialect MLIRQCODialect MLIRArithDialect - MLIRFuncDialect) + MLIRFuncDialect + MLIRTransforms + MLIRFuncTransforms + DISABLE_INSTALL) diff --git a/mlir/lib/Conversion/QCToQCO/CMakeLists.txt b/mlir/lib/Conversion/QCToQCO/CMakeLists.txt index a4ffcfebbe..8dd695175e 100644 --- a/mlir/lib/Conversion/QCToQCO/CMakeLists.txt +++ b/mlir/lib/Conversion/QCToQCO/CMakeLists.txt @@ -14,8 +14,10 @@ add_mlir_library( DEPENDS QCToQCOIncGen LINK_LIBS - PUBLIC MLIRQCDialect MLIRQCODialect MLIRArithDialect - MLIRFuncDialect) + MLIRFuncDialect + MLIRTransforms + MLIRFuncTransforms + DISABLE_INSTALL) diff --git a/mlir/lib/Conversion/QCToQIR/CMakeLists.txt b/mlir/lib/Conversion/QCToQIR/CMakeLists.txt index a2715355f5..ded97f3f87 100644 --- a/mlir/lib/Conversion/QCToQIR/CMakeLists.txt +++ b/mlir/lib/Conversion/QCToQIR/CMakeLists.txt @@ -14,11 +14,12 @@ add_mlir_library( DEPENDS QCToQIRIncGen LINK_LIBS - PUBLIC MLIRQIRUtils MLIRLLVMDialect MLIRQCDialect MLIRArithDialect + MLIRTransforms MLIRFuncDialect MLIRFuncToLLVM - MLIRReconcileUnrealizedCasts) + MLIRReconcileUnrealizedCasts + DISABLE_INSTALL) diff --git a/mlir/lib/Conversion/QIRToMQTRef/CMakeLists.txt b/mlir/lib/Conversion/QIRToMQTRef/CMakeLists.txt index 91cb08c6a6..b854f648d4 100644 --- a/mlir/lib/Conversion/QIRToMQTRef/CMakeLists.txt +++ b/mlir/lib/Conversion/QIRToMQTRef/CMakeLists.txt @@ -8,4 +8,14 @@ file(GLOB CONVERSION_SOURCES *.cpp) -add_mlir_library(QIRToMQTRef ${CONVERSION_SOURCES} DEPENDS QIRToMQTRefIncGen) +add_mlir_library( + QIRToMQTRef + ${CONVERSION_SOURCES} + DEPENDS + QIRToMQTRefIncGen + LINK_LIBS + MLIRMQTRef + MLIRMemRefDialect + MLIRTransforms + MLIRLLVMDialect + DISABLE_INSTALL) diff --git a/mlir/lib/Dialect/MQTOpt/IR/CMakeLists.txt b/mlir/lib/Dialect/MQTOpt/IR/CMakeLists.txt index 8e962287d3..ffc4f84f86 100644 --- a/mlir/lib/Dialect/MQTOpt/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/MQTOpt/IR/CMakeLists.txt @@ -6,8 +6,17 @@ # # Licensed under the MIT License -add_mlir_dialect_library(MLIRMQTOpt MQTOptOps.cpp DEPENDS MLIRMQTOptOpsIncGen - MLIRMQTOptInterfacesIncGen) +add_mlir_dialect_library( + MLIRMQTOpt + MQTOptOps.cpp + DEPENDS + MLIRMQTOptOpsIncGen + MLIRMQTOptInterfacesIncGen + LINK_LIBS + MLIRIR + MLIRInferTypeOpInterface + DISABLE_INSTALL) + # collect header files file(GLOB_RECURSE IR_HEADERS_SOURCE "${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/MQTOpt/IR/*.h") file(GLOB_RECURSE IR_HEADERS_BUILD "${MQT_MLIR_BUILD_INCLUDE_DIR}/mlir/Dialect/MQTOpt/IR/*.inc") diff --git a/mlir/lib/Dialect/MQTOpt/Transforms/CMakeLists.txt b/mlir/lib/Dialect/MQTOpt/Transforms/CMakeLists.txt index e7f1f55dac..27bad4b5d8 100644 --- a/mlir/lib/Dialect/MQTOpt/Transforms/CMakeLists.txt +++ b/mlir/lib/Dialect/MQTOpt/Transforms/CMakeLists.txt @@ -8,12 +8,17 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) set(LIBRARIES ${dialect_libs} MQT::CoreIR) -add_compile_options(-fexceptions) file(GLOB_RECURSE TRANSFORMS_SOURCES *.cpp) -add_mlir_library(MLIRMQTOptTransforms ${TRANSFORMS_SOURCES} LINK_LIBS ${LIBRARIES} DEPENDS - MLIRMQTOptTransformsIncGen) +add_mlir_library( + MLIRMQTOptTransforms + ${TRANSFORMS_SOURCES} + LINK_LIBS + ${LIBRARIES} + DEPENDS + MLIRMQTOptTransformsIncGen + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE TRANSFORMS_HEADERS_SOURCE diff --git a/mlir/lib/Dialect/MQTOpt/Transforms/MergeRotationGatesPattern.cpp b/mlir/lib/Dialect/MQTOpt/Transforms/MergeRotationGatesPattern.cpp index d67d149028..9f32fff467 100644 --- a/mlir/lib/Dialect/MQTOpt/Transforms/MergeRotationGatesPattern.cpp +++ b/mlir/lib/Dialect/MQTOpt/Transforms/MergeRotationGatesPattern.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,6 @@ #include #include #include -#include #include #include @@ -169,7 +169,7 @@ struct MergeRotationGatesPattern final } else if (type == "rzx") { newUser = createOpAdditiveAngle(op, user, rewriter); } else { - throw std::runtime_error("Unsupported operation type: " + type); + llvm_unreachable("Unsupported operation type"); } // Prepare erasure of op diff --git a/mlir/lib/Dialect/MQTOpt/Transforms/ToQuantumComputationPattern.cpp b/mlir/lib/Dialect/MQTOpt/Transforms/ToQuantumComputationPattern.cpp index 3387ec26b3..c66fb72713 100644 --- a/mlir/lib/Dialect/MQTOpt/Transforms/ToQuantumComputationPattern.cpp +++ b/mlir/lib/Dialect/MQTOpt/Transforms/ToQuantumComputationPattern.cpp @@ -187,8 +187,9 @@ struct ToQuantumComputationPattern final const std::string type = op->getName().stripDialect().str(); opType = qc::opTypeFromString(type); } catch (const std::invalid_argument& e) { - throw std::runtime_error("Unsupported operation type: " + - op->getName().getStringRef().str()); + throw std::runtime_error( + "Unsupported operation type: " + op->getName().getStringRef().str() + + " (" + e.what() + ")"); } const auto in = op.getInQubits(); diff --git a/mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/LayeredUnit.cpp b/mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/LayeredUnit.cpp index 05809e188e..eebefb0325 100644 --- a/mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/LayeredUnit.cpp +++ b/mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/LayeredUnit.cpp @@ -166,7 +166,7 @@ LayeredUnit::LayeredUnit(Layout layout, mlir::Region* region) bool haltOnWire{}; - for (auto [it, index] : curr) { + for (auto& [it, index] : curr) { while (it != std::default_sentinel) { haltOnWire = mlir::TypeSwitch(*it) @@ -300,7 +300,7 @@ mlir::SmallVector LayeredUnit::nextImpl() { #ifndef NDEBUG LLVM_DUMP_METHOD void LayeredUnit::dump(llvm::raw_ostream& os) const { os << "schedule: layers=\n"; - for (const auto [i, layer] : llvm::enumerate(layers_)) { + for (const auto& [i, layer] : llvm::enumerate(layers_)) { os << '\t' << '[' << i << "]:\n"; os << "\t #ops= " << layer.ops.size(); if (!layer.ops.empty()) { @@ -309,7 +309,7 @@ LLVM_DUMP_METHOD void LayeredUnit::dump(llvm::raw_ostream& os) const { os << '\n'; os << "\t gates= "; if (!layer.hasZero2QOps()) { - for (const auto [prog0, prog1] : layer.twoQubitProgs) { + for (const auto& [prog0, prog1] : layer.twoQubitProgs) { os << "(" << prog0 << "," << prog1 << "), "; } } else { diff --git a/mlir/lib/Dialect/MQTRef/IR/CMakeLists.txt b/mlir/lib/Dialect/MQTRef/IR/CMakeLists.txt index 7f1b275ebc..64c3fab8e8 100644 --- a/mlir/lib/Dialect/MQTRef/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/MQTRef/IR/CMakeLists.txt @@ -6,8 +6,16 @@ # # Licensed under the MIT License -add_mlir_dialect_library(MLIRMQTRef MQTRefOps.cpp DEPENDS MLIRMQTRefOpsIncGen - MLIRMQTRefInterfacesIncGen) +add_mlir_dialect_library( + MLIRMQTRef + MQTRefOps.cpp + DEPENDS + MLIRMQTRefOpsIncGen + MLIRMQTRefInterfacesIncGen + LINK_LIBS + MLIRIR + MLIRInferTypeOpInterface + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE IR_HEADERS_SOURCE "${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/MQTRef/IR/*.h") diff --git a/mlir/lib/Dialect/MQTRef/Translation/CMakeLists.txt b/mlir/lib/Dialect/MQTRef/Translation/CMakeLists.txt index c093fd04f0..a65b107a41 100644 --- a/mlir/lib/Dialect/MQTRef/Translation/CMakeLists.txt +++ b/mlir/lib/Dialect/MQTRef/Translation/CMakeLists.txt @@ -6,8 +6,6 @@ # # Licensed under the MIT License -add_compile_options(-fexceptions) - add_mlir_library( MLIRMQTRefTranslation ImportQuantumComputation.cpp @@ -17,7 +15,8 @@ add_mlir_library( MLIRMemRefDialect MLIRSCFDialect MLIRMQTRef - MQT::CoreIR) + MQT::CoreIR + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE TRANSLATION_HEADERS_SOURCE diff --git a/mlir/lib/Dialect/QC/Builder/CMakeLists.txt b/mlir/lib/Dialect/QC/Builder/CMakeLists.txt index ddd7989417..bfb71993e8 100644 --- a/mlir/lib/Dialect/QC/Builder/CMakeLists.txt +++ b/mlir/lib/Dialect/QC/Builder/CMakeLists.txt @@ -14,7 +14,8 @@ add_mlir_library( MLIRArithDialect MLIRFuncDialect MLIRSCFDialect - MLIRQCDialect) + MLIRQCDialect + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE BUILDER_HEADERS_SOURCE ${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/QC/Builder/*.h) diff --git a/mlir/lib/Dialect/QC/IR/CMakeLists.txt b/mlir/lib/Dialect/QC/IR/CMakeLists.txt index e76c161d66..cfddda5067 100644 --- a/mlir/lib/Dialect/QC/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/QC/IR/CMakeLists.txt @@ -24,7 +24,9 @@ add_mlir_dialect_library( LINK_LIBS PUBLIC MLIRIR - MLIRSideEffectInterfaces) + MLIRInferTypeOpInterface + MLIRSideEffectInterfaces + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE IR_HEADERS_SOURCE "${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/QC/IR/*.h") diff --git a/mlir/lib/Dialect/QC/Translation/CMakeLists.txt b/mlir/lib/Dialect/QC/Translation/CMakeLists.txt index 5414559cb6..d1a5bb86fd 100644 --- a/mlir/lib/Dialect/QC/Translation/CMakeLists.txt +++ b/mlir/lib/Dialect/QC/Translation/CMakeLists.txt @@ -6,8 +6,6 @@ # # Licensed under the MIT License -add_compile_options("-fexceptions") - add_mlir_library( MLIRQCTranslation TranslateQuantumComputationToQC.cpp @@ -16,7 +14,9 @@ add_mlir_library( MLIRFuncDialect MLIRSCFDialect MLIRQCDialect - MQT::CoreIR) + MLIRQCProgramBuilder + MQT::CoreIR + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE TRANSLATION_HEADERS_SOURCE diff --git a/mlir/lib/Dialect/QCO/Builder/CMakeLists.txt b/mlir/lib/Dialect/QCO/Builder/CMakeLists.txt index 6446970949..2dc40770de 100644 --- a/mlir/lib/Dialect/QCO/Builder/CMakeLists.txt +++ b/mlir/lib/Dialect/QCO/Builder/CMakeLists.txt @@ -14,7 +14,8 @@ add_mlir_library( MLIRArithDialect MLIRFuncDialect MLIRSCFDialect - MLIRQCODialect) + MLIRQCODialect + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE BUILDER_HEADERS_SOURCE diff --git a/mlir/lib/Dialect/QCO/IR/CMakeLists.txt b/mlir/lib/Dialect/QCO/IR/CMakeLists.txt index 567a80611b..39bfc60a0a 100644 --- a/mlir/lib/Dialect/QCO/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/QCO/IR/CMakeLists.txt @@ -24,7 +24,10 @@ add_mlir_dialect_library( LINK_LIBS PUBLIC MLIRIR - MLIRSideEffectInterfaces) + MLIRArithDialect + MLIRInferTypeOpInterface + MLIRSideEffectInterfaces + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE IR_HEADERS_SOURCE "${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/QCO/IR/*.h") diff --git a/mlir/lib/Dialect/QIR/Builder/CMakeLists.txt b/mlir/lib/Dialect/QIR/Builder/CMakeLists.txt index aab1a2caad..de8548452e 100644 --- a/mlir/lib/Dialect/QIR/Builder/CMakeLists.txt +++ b/mlir/lib/Dialect/QIR/Builder/CMakeLists.txt @@ -14,7 +14,8 @@ add_mlir_library( MLIRLLVMDialect MLIRQIRUtils MLIRIR - MLIRSupport) + MLIRSupport + DISABLE_INSTALL) # collect header files file(GLOB_RECURSE QIR_BUILDER_HEADERS_SOURCE diff --git a/mlir/lib/Dialect/QIR/Utils/CMakeLists.txt b/mlir/lib/Dialect/QIR/Utils/CMakeLists.txt index 4280d86d1e..33bec3e098 100644 --- a/mlir/lib/Dialect/QIR/Utils/CMakeLists.txt +++ b/mlir/lib/Dialect/QIR/Utils/CMakeLists.txt @@ -8,8 +8,17 @@ file(GLOB QIR_UTILS_SOURCES *.cpp) -add_mlir_library(MLIRQIRUtils ${QIR_UTILS_SOURCES} LINK_LIBS PUBLIC MLIRLLVMDialect MLIRIR) +add_mlir_library( + MLIRQIRUtils + ${QIR_UTILS_SOURCES} + LINK_LIBS + PUBLIC + MLIRLLVMDialect + MLIRIR + DISABLE_INSTALL) -target_include_directories( - MLIRQIRUtils PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_MLIR_SOURCE_INCLUDE_DIR} FILES - ${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/QIR/Utils/QIRUtils.h) +file(GLOB_RECURSE QIR_UTILS_HEADERS_SOURCE + ${MQT_MLIR_SOURCE_INCLUDE_DIR}/mlir/Dialect/QIR/Utils/*.h) + +target_sources(MLIRQIRUtils PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_MLIR_SOURCE_INCLUDE_DIR} FILES + ${QIR_UTILS_HEADERS_SOURCE}) diff --git a/mlir/lib/Support/CMakeLists.txt b/mlir/lib/Support/CMakeLists.txt index cd368aad5e..5922f2ec04 100644 --- a/mlir/lib/Support/CMakeLists.txt +++ b/mlir/lib/Support/CMakeLists.txt @@ -3,6 +3,8 @@ # All rights reserved. # # SPDX-License-Identifier: MIT +# +# Licensed under the MIT License add_mlir_library( MLIRSupportMQT @@ -12,7 +14,8 @@ add_mlir_library( LINK_LIBS PUBLIC MLIRSupport - MLIRIR) + MLIRIR + DISABLE_INSTALL) # add library alias add_library(MQT::MLIRSupport ALIAS MLIRSupportMQT) diff --git a/mlir/test/CMakeLists.txt b/mlir/test/CMakeLists.txt index 4dbdf3f440..6ab43c355f 100644 --- a/mlir/test/CMakeLists.txt +++ b/mlir/test/CMakeLists.txt @@ -23,3 +23,6 @@ set_target_properties(mqt-core-mlir-lit-test-build-only PROPERTIES FOLDER "Tests add_lit_testsuite(mqt-core-mlir-lit-test "Running the MQT MLIR tests" ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${MQT_CORE_MLIR_TEST_DEPENDS}) set_target_properties(mqt-core-mlir-lit-test PROPERTIES FOLDER "Tests") + +add_test(NAME mqt-core-mlir-lit-test COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target + mqt-core-mlir-lit-test --config $) diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py index e51242713d..2135f42007 100644 --- a/mlir/test/lit.cfg.py +++ b/mlir/test/lit.cfg.py @@ -15,6 +15,7 @@ from __future__ import annotations +import sys from pathlib import Path import lit.formats @@ -38,7 +39,31 @@ # Define where to execute tests (and produce the output). config.test_exec_root = Path(config.mqt_core_mlir_test_dir) -multi_config_path = Path(config.mqt_core_mlir_tools_dir) / config.cmake_build_type -tool_dirs = [config.llvm_tools_dir, config.mqt_core_mlir_tools_dir, str(multi_config_path)] -tools = ["not", "FileCheck", "quantum-opt"] -llvm_config.add_tool_substitutions(tools, tool_dirs) +# Add substitutions for the required tools. +found = llvm_config.add_tool_substitutions(tools=["not", "FileCheck", "split-file"]) +if not found: + msg = "Could not find one or more required LLVM tools: 'not', 'FileCheck', 'split-file'." + raise RuntimeError(msg) + +# Successively check directories whether they contain the quantum-opt tool +tool_name = "quantum-opt" if sys.platform != "win32" else "quantum-opt.exe" +base_tool_dir = Path(config.mqt_core_mlir_tools_dir) + +candidate_dirs = [base_tool_dir] +if config.cmake_build_type: + candidate_dirs.append(base_tool_dir / config.cmake_build_type) +for cfg in ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"]: + cfg_dir = base_tool_dir / cfg + if cfg_dir not in candidate_dirs: + candidate_dirs.append(cfg_dir) + +found = False +for candidate_dir in candidate_dirs: + if (candidate_dir / tool_name).exists(): + llvm_config.add_tool_substitutions(["quantum-opt"], [str(candidate_dir)]) + found = True + break + +if not found: + msg = f"Could not find {tool_name} anywhere under {base_tool_dir}." + raise RuntimeError(msg) diff --git a/mlir/tools/mqt-cc/CMakeLists.txt b/mlir/tools/mqt-cc/CMakeLists.txt index bae241ddd0..4c326e48d6 100644 --- a/mlir/tools/mqt-cc/CMakeLists.txt +++ b/mlir/tools/mqt-cc/CMakeLists.txt @@ -8,7 +8,6 @@ # Build the compiler driver executable add_mlir_tool(mqt-cc mqt-cc.cpp DEPENDS MQTCompilerPipeline SUPPORT_PLUGINS) -target_compile_options(mqt-cc PRIVATE -fexceptions) target_link_libraries( mqt-cc PRIVATE MQTCompilerPipeline diff --git a/mlir/tools/quantum-opt/CMakeLists.txt b/mlir/tools/quantum-opt/CMakeLists.txt index 3614044814..866af6e4d8 100644 --- a/mlir/tools/quantum-opt/CMakeLists.txt +++ b/mlir/tools/quantum-opt/CMakeLists.txt @@ -23,7 +23,6 @@ set(LIBS QIRToMQTRef) add_mlir_tool(quantum-opt quantum-opt.cpp DEPENDS ${LIBS} SUPPORT_PLUGINS) -target_compile_options(quantum-opt PRIVATE -fexceptions) target_link_libraries(quantum-opt PUBLIC ${LIBS}) llvm_update_compile_flags(quantum-opt) mlir_check_all_link_libraries(quantum-opt) diff --git a/mlir/unittests/translation/CMakeLists.txt b/mlir/unittests/translation/CMakeLists.txt index 6ca1f46aa3..04ebc46b75 100644 --- a/mlir/unittests/translation/CMakeLists.txt +++ b/mlir/unittests/translation/CMakeLists.txt @@ -25,4 +25,10 @@ if(NOT TARGET ${testname}) # discover tests gtest_discover_tests(${testname} DISCOVERY_TIMEOUT 60) set_target_properties(${testname} PROPERTIES FOLDER unittests) + + if(MSVC) + target_compile_options(${testname} PRIVATE /EHsc) + else() + target_compile_options(${testname} PRIVATE -fexceptions) + endif() endif() diff --git a/pyproject.toml b/pyproject.toml index 6eaa95aa4a..f2756aedbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -128,6 +128,7 @@ git-only = [ BUILD_MQT_CORE_BINDINGS = "ON" BUILD_MQT_CORE_TESTS = "OFF" BUILD_MQT_CORE_SHARED_LIBS = "ON" +BUILD_MQT_CORE_MLIR = "OFF" [[tool.scikit-build.overrides]] if.python-version = ">=3.13" diff --git a/src/algorithms/StatePreparation.cpp b/src/algorithms/StatePreparation.cpp index e99c5ad537..9be404ded5 100644 --- a/src/algorithms/StatePreparation.cpp +++ b/src/algorithms/StatePreparation.cpp @@ -119,7 +119,7 @@ template } Matrix const matrix{std::vector{0.5, 0.5}, std::vector{0.5, -0.5}}; - Matrix const identity = createIdentity(1 << (localNumQubits - 2)); + Matrix const identity = createIdentity(1ULL << (localNumQubits - 2)); Matrix const angleWeights = kroneckerProduct(matrix, identity); angles = matrixVectorProd(angleWeights, angles); diff --git a/src/qasm3/passes/TypeCheckPass.cpp b/src/qasm3/passes/TypeCheckPass.cpp index 126c10d4c4..2776aae569 100644 --- a/src/qasm3/passes/TypeCheckPass.cpp +++ b/src/qasm3/passes/TypeCheckPass.cpp @@ -332,13 +332,17 @@ InferredType TypeCheckPass::visitIdentifierExpression( return type->second; } +#ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" +#endif InferredType TypeCheckPass::visitIdentifierList( std::shared_ptr /*identifierList*/) { throw TypeCheckError("TypeCheckPass::visitIdentifierList not implemented"); } +#ifdef __GNUC__ #pragma GCC diagnostic pop +#endif InferredType TypeCheckPass::visitIndexedIdentifier( const std::shared_ptr indexedIdentifier) { diff --git a/src/qdmi/CMakeLists.txt b/src/qdmi/CMakeLists.txt index 81c14e835a..5e57979d35 100644 --- a/src/qdmi/CMakeLists.txt +++ b/src/qdmi/CMakeLists.txt @@ -51,7 +51,7 @@ if(NOT TARGET ${TARGET_NAME}) ${TARGET_NAME} PUBLIC qdmi::qdmi MQT::CoreQDMICommon PRIVATE MQT::CoreQDMINaDevice MQT::CoreQDMIScDevice MQT::CoreQDMI_DDSIM_Device - qdmi::qdmi_project_warnings spdlog::spdlog) + qdmi::qdmi_project_warnings spdlog::spdlog ${CMAKE_DL_LIBS}) # add to list of MQT core targets list(APPEND MQT_CORE_TARGETS ${TARGET_NAME}) diff --git a/src/qdmi/Driver.cpp b/src/qdmi/Driver.cpp index a6912fd346..4b6bab7db3 100644 --- a/src/qdmi/Driver.cpp +++ b/src/qdmi/Driver.cpp @@ -87,7 +87,8 @@ DEFINE_STATIC_LIBRARY(MQT_SC) #ifdef _WIN32 #define DL_OPEN(lib) LoadLibraryA((lib)) -#define DL_SYM(lib, sym) GetProcAddress(static_cast((lib)), (sym)) +#define DL_SYM(lib, sym) \ + reinterpret_cast(GetProcAddress(static_cast((lib)), (sym))) #define DL_CLOSE(lib) FreeLibrary(static_cast((lib))) #else #define DL_OPEN(lib) dlopen((lib), RTLD_NOW | RTLD_LOCAL) diff --git a/src/qdmi/na/App.cpp b/src/qdmi/na/App.cpp index 0d31c80f09..b56d5a0eae 100644 --- a/src/qdmi/na/App.cpp +++ b/src/qdmi/na/App.cpp @@ -400,8 +400,8 @@ int main(int argc, char* argv[]) { // `main` functions should not throw exceptions. Apparently, the // initialization of a vector can throw exceptions, so we catch them here. try { - argVec.reserve(argc); - for (const auto& arg : std::span(argv, argc)) { + argVec.reserve(static_cast(argc)); + for (const auto& arg : std::span(argv, static_cast(argc))) { argVec.emplace_back(arg); } } catch (std::exception& e) { diff --git a/src/qdmi/na/CMakeLists.txt b/src/qdmi/na/CMakeLists.txt index 266799f974..896d0367ae 100644 --- a/src/qdmi/na/CMakeLists.txt +++ b/src/qdmi/na/CMakeLists.txt @@ -51,7 +51,8 @@ if(NOT TARGET ${TARGET_NAME}) target_sources(${TARGET_NAME} PRIVATE App.cpp) # Link Generator library - target_link_libraries(${TARGET_NAME} PRIVATE MQT::CoreQDMINaDeviceGen spdlog::spdlog) + target_link_libraries(${TARGET_NAME} PRIVATE MQT::CoreQDMINaDeviceGen MQT::ProjectOptions + MQT::ProjectWarnings spdlog::spdlog) # set versioning information set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${PROJECT_VERSION} EXPORT_NAME @@ -147,7 +148,6 @@ if(NOT TARGET ${TARGET_NAME}) file(GLOB_RECURSE QDMI_HDRS ${CMAKE_CURRENT_BINARY_DIR}/include/mqt_na_dyn_qdmi/**.hpp) # Add dynamic library target add_library(${DYN_TARGET_NAME} SHARED) - add_dependencies(${DYN_TARGET_NAME} ${TARGET_NAME}) # add sources to target target_sources(${DYN_TARGET_NAME} PRIVATE DynDevice.cpp) # add headers using file sets @@ -176,6 +176,12 @@ if(NOT TARGET ${TARGET_NAME}) PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} EXPORT_NAME CoreQDMINaDeviceDyn) + if(MSVC) + # Disable link-time code generation for dynamic library on Windows to avoid issues with + # missing symbols and other link errors + set_target_properties(${DYN_TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION FALSE) + target_link_options(${DYN_TARGET_NAME} PRIVATE /LTCG:OFF) + endif() add_library(MQT::CoreQDMINaDeviceDyn ALIAS ${DYN_TARGET_NAME}) list(APPEND MQT_CORE_TARGETS ${DYN_TARGET_NAME}) endif() diff --git a/src/qdmi/sc/App.cpp b/src/qdmi/sc/App.cpp index c9c33f493f..facc3b28ee 100644 --- a/src/qdmi/sc/App.cpp +++ b/src/qdmi/sc/App.cpp @@ -454,8 +454,8 @@ int main(int argc, char* argv[]) { // `main` functions should not throw exceptions. Apparently, the // initialization of a vector can throw exceptions, so we catch them here. try { - argVec.reserve(argc); - for (const auto& arg : std::span(argv, argc)) { + argVec.reserve(static_cast(argc)); + for (const auto& arg : std::span(argv, static_cast(argc))) { argVec.emplace_back(arg); } } catch (std::exception& e) { diff --git a/src/qdmi/sc/CMakeLists.txt b/src/qdmi/sc/CMakeLists.txt index f328832fde..fcbbe03cde 100644 --- a/src/qdmi/sc/CMakeLists.txt +++ b/src/qdmi/sc/CMakeLists.txt @@ -48,7 +48,8 @@ if(NOT TARGET ${TARGET_NAME}) target_sources(${TARGET_NAME} PRIVATE App.cpp) # Link Generator library - target_link_libraries(${TARGET_NAME} PRIVATE MQT::CoreQDMIScDeviceGen spdlog::spdlog) + target_link_libraries(${TARGET_NAME} PRIVATE MQT::CoreQDMIScDeviceGen MQT::ProjectOptions + MQT::ProjectWarnings spdlog::spdlog) # set versioning information set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${PROJECT_VERSION} EXPORT_NAME @@ -144,7 +145,6 @@ if(NOT TARGET ${TARGET_NAME}) file(GLOB_RECURSE QDMI_HDRS ${CMAKE_CURRENT_BINARY_DIR}/include/mqt_sc_dyn_qdmi/**.hpp) # Add dynamic library target add_library(${DYN_TARGET_NAME} SHARED) - add_dependencies(${DYN_TARGET_NAME} ${TARGET_NAME}) # add sources to target target_sources(${DYN_TARGET_NAME} PRIVATE DynDevice.cpp) # add headers using file sets @@ -173,6 +173,12 @@ if(NOT TARGET ${TARGET_NAME}) PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} EXPORT_NAME CoreQDMIScDeviceDyn) + if(MSVC) + # Disable link-time code generation for dynamic library on Windows to avoid issues with + # missing symbols and other link errors + set_target_properties(${DYN_TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION FALSE) + target_link_options(${DYN_TARGET_NAME} PRIVATE /LTCG:OFF) + endif() add_library(MQT::CoreQDMIScDeviceDyn ALIAS ${DYN_TARGET_NAME}) list(APPEND MQT_CORE_TARGETS ${DYN_TARGET_NAME}) endif() diff --git a/src/qir/runner/CMakeLists.txt b/src/qir/runner/CMakeLists.txt index bc2155e40e..dbfdb973a1 100644 --- a/src/qir/runner/CMakeLists.txt +++ b/src/qir/runner/CMakeLists.txt @@ -9,12 +9,7 @@ set(TARGET_NAME ${MQT_CORE_TARGET_NAME}-qir-runner) if(NOT TARGET ${TARGET_NAME}) - if(MLIR_VERSION VERSION_GREATER_EQUAL 20.0) - add_llvm_tool(${TARGET_NAME} Runner.cpp DEPENDS intrinsics_gen EXPORT_SYMBOLS) - else() - add_llvm_tool(${TARGET_NAME} Runner.cpp DEPENDS intrinsics_gen) - export_executable_symbols(${TARGET_NAME}) - endif() + add_llvm_tool(${TARGET_NAME} Runner.cpp DEPENDS intrinsics_gen EXPORT_SYMBOLS) # Get the native target libraries llvm_map_components_to_libnames(llvm_native_libs native) @@ -26,9 +21,12 @@ if(NOT TARGET ${TARGET_NAME}) # Set versioning information set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${PROJECT_VERSION} EXPORT_NAME CoreQIRRunner) - # place in the bin directory - set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/bin") + # Set the appropriate output directories + set_target_properties( + ${TARGET_NAME} + PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}") # Set c++ standard target_compile_features(${TARGET_NAME} PRIVATE cxx_std_20) diff --git a/src/qir/runner/Runner.cpp b/src/qir/runner/Runner.cpp index 879758d480..a3202a06ea 100644 --- a/src/qir/runner/Runner.cpp +++ b/src/qir/runner/Runner.cpp @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -46,6 +48,7 @@ #include #include #include +#include #define DEBUG_TYPE "mqt-core-qir-runner" @@ -64,6 +67,14 @@ const llvm::cl::list // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) llvm::ExitOnError exitOnErr; +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +std::vector> manualSymbols; + +#define REGISTER_SYMBOL(name) \ + llvm::sys::DynamicLibrary::AddSymbol(#name, \ + reinterpret_cast(&(name))); \ + manualSymbols.emplace_back(#name, reinterpret_cast(&(name))); + void exitOnLazyCallThroughFailure() { exit(1); } llvm::Expected @@ -167,6 +178,18 @@ int runOrcJIT() { const auto jit = exitOnErr(builder.create()); + auto& jd = jit->getMainJITDylib(); + llvm::orc::SymbolMap hostSymbols; + for (const auto& [name, ptr] : manualSymbols) { + hostSymbols[jit->mangleAndIntern(name)] = { + llvm::orc::ExecutorAddr::fromPtr(ptr), llvm::JITSymbolFlags::Exported}; + } + exitOnErr(jd.define(llvm::orc::absoluteSymbols(hostSymbols))); + + jit->getMainJITDylib().addGenerator( + exitOnErr(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess( + jit->getDataLayout().getGlobalPrefix()))); + auto* objLayer = &jit->getObjLinkingLayer(); if (auto* rtDyldObjLayer = dyn_cast(objLayer)) { @@ -232,189 +255,67 @@ auto main(int argc, char* argv[]) -> int { llvm::cl::ParseCommandLineOptions(argc, argv, "qir interpreter & dynamic compiler\n"); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__result_get_zero", - reinterpret_cast(&__quantum__rt__result_get_zero)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__result_get_one", - reinterpret_cast(&__quantum__rt__result_get_one)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__result_equal", - reinterpret_cast(&__quantum__rt__result_equal)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__result_update_reference_count", - reinterpret_cast(&__quantum__rt__result_update_reference_count)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__array_create_1d", - reinterpret_cast(&__quantum__rt__array_create_1d)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__array_get_size_1d", - reinterpret_cast(&__quantum__rt__array_get_size_1d)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__array_get_element_ptr_1d", - reinterpret_cast(&__quantum__rt__array_get_element_ptr_1d)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__array_update_reference_count", - reinterpret_cast(&__quantum__rt__array_update_reference_count)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__qubit_allocate", - reinterpret_cast(&__quantum__rt__qubit_allocate)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__qubit_allocate_array", - reinterpret_cast(&__quantum__rt__qubit_allocate_array)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__qubit_release", - reinterpret_cast(&__quantum__rt__qubit_release)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__qubit_release_array", - reinterpret_cast(&__quantum__rt__qubit_release_array)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__x__body", - reinterpret_cast(&__quantum__qis__x__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__y__body", - reinterpret_cast(&__quantum__qis__y__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__z__body", - reinterpret_cast(&__quantum__qis__z__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__h__body", - reinterpret_cast(&__quantum__qis__h__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__s__body", - reinterpret_cast(&__quantum__qis__s__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__sdg__body", - reinterpret_cast(&__quantum__qis__sdg__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__sx__body", - reinterpret_cast(&__quantum__qis__sx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__sxdg__body", - reinterpret_cast(&__quantum__qis__sxdg__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__sqrtx__body", - reinterpret_cast(&__quantum__qis__sqrtx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__sqrtxdg__body", - reinterpret_cast(&__quantum__qis__sqrtxdg__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__t__body", - reinterpret_cast(&__quantum__qis__t__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__tdg__body", - reinterpret_cast(&__quantum__qis__tdg__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__r__body", - reinterpret_cast(&__quantum__qis__r__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__prx__body", - reinterpret_cast(&__quantum__qis__prx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__rx__body", - reinterpret_cast(&__quantum__qis__rx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__ry__body", - reinterpret_cast(&__quantum__qis__ry__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__rz__body", - reinterpret_cast(&__quantum__qis__rz__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__p__body", - reinterpret_cast(&__quantum__qis__p__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__rxx__body", - reinterpret_cast(&__quantum__qis__rxx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__ryy__body", - reinterpret_cast(&__quantum__qis__ryy__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__rzz__body", - reinterpret_cast(&__quantum__qis__rzz__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__rzx__body", - reinterpret_cast(&__quantum__qis__rzx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__u__body", - reinterpret_cast(&__quantum__qis__u__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__u3__body", - reinterpret_cast(&__quantum__qis__u3__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__u2__body", - reinterpret_cast(&__quantum__qis__u2__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__u1__body", - reinterpret_cast(&__quantum__qis__u1__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cu1__body", - reinterpret_cast(&__quantum__qis__cu1__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cu3__body", - reinterpret_cast(&__quantum__qis__cu3__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cnot__body", - reinterpret_cast(&__quantum__qis__cnot__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cx__body", - reinterpret_cast(&__quantum__qis__cx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cy__body", - reinterpret_cast(&__quantum__qis__cy__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cz__body", - reinterpret_cast(&__quantum__qis__cz__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__ch__body", - reinterpret_cast(&__quantum__qis__ch__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__swap__body", - reinterpret_cast(&__quantum__qis__swap__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cswap__body", - reinterpret_cast(&__quantum__qis__cswap__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__crz__body", - reinterpret_cast(&__quantum__qis__crz__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cry__body", - reinterpret_cast(&__quantum__qis__cry__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__crx__body", - reinterpret_cast(&__quantum__qis__crx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__cp__body", - reinterpret_cast(&__quantum__qis__cp__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__ccx__body", - reinterpret_cast(&__quantum__qis__ccx__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__ccy__body", - reinterpret_cast(&__quantum__qis__ccy__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__ccz__body", - reinterpret_cast(&__quantum__qis__ccz__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__m__body", - reinterpret_cast(&__quantum__qis__m__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__measure__body", - reinterpret_cast(&__quantum__qis__measure__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__mz__body", - reinterpret_cast(&__quantum__qis__mz__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__qis__reset__body", - reinterpret_cast(&__quantum__qis__reset__body)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__initialize", - reinterpret_cast(&__quantum__rt__initialize)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__read_result", - reinterpret_cast(&__quantum__rt__read_result)); - llvm::sys::DynamicLibrary::AddSymbol( - "__quantum__rt__result_record_output", - reinterpret_cast(&__quantum__rt__result_record_output)); + REGISTER_SYMBOL(__quantum__rt__result_get_zero); + REGISTER_SYMBOL(__quantum__rt__result_get_one); + REGISTER_SYMBOL(__quantum__rt__result_equal); + REGISTER_SYMBOL(__quantum__rt__result_update_reference_count); + REGISTER_SYMBOL(__quantum__rt__array_create_1d); + REGISTER_SYMBOL(__quantum__rt__array_get_size_1d); + REGISTER_SYMBOL(__quantum__rt__array_get_element_ptr_1d); + REGISTER_SYMBOL(__quantum__rt__array_update_reference_count); + REGISTER_SYMBOL(__quantum__rt__qubit_allocate); + REGISTER_SYMBOL(__quantum__rt__qubit_allocate_array); + REGISTER_SYMBOL(__quantum__rt__qubit_release); + REGISTER_SYMBOL(__quantum__rt__qubit_release_array); + REGISTER_SYMBOL(__quantum__qis__x__body); + REGISTER_SYMBOL(__quantum__qis__y__body); + REGISTER_SYMBOL(__quantum__qis__z__body); + REGISTER_SYMBOL(__quantum__qis__h__body); + REGISTER_SYMBOL(__quantum__qis__s__body); + REGISTER_SYMBOL(__quantum__qis__sdg__body); + REGISTER_SYMBOL(__quantum__qis__sx__body); + REGISTER_SYMBOL(__quantum__qis__sxdg__body); + REGISTER_SYMBOL(__quantum__qis__sqrtx__body); + REGISTER_SYMBOL(__quantum__qis__sqrtxdg__body); + REGISTER_SYMBOL(__quantum__qis__t__body); + REGISTER_SYMBOL(__quantum__qis__tdg__body); + REGISTER_SYMBOL(__quantum__qis__r__body); + REGISTER_SYMBOL(__quantum__qis__prx__body); + REGISTER_SYMBOL(__quantum__qis__rx__body); + REGISTER_SYMBOL(__quantum__qis__ry__body); + REGISTER_SYMBOL(__quantum__qis__rz__body); + REGISTER_SYMBOL(__quantum__qis__p__body); + REGISTER_SYMBOL(__quantum__qis__rxx__body); + REGISTER_SYMBOL(__quantum__qis__ryy__body); + REGISTER_SYMBOL(__quantum__qis__rzz__body); + REGISTER_SYMBOL(__quantum__qis__rzx__body); + REGISTER_SYMBOL(__quantum__qis__u__body); + REGISTER_SYMBOL(__quantum__qis__u3__body); + REGISTER_SYMBOL(__quantum__qis__u2__body); + REGISTER_SYMBOL(__quantum__qis__u1__body); + REGISTER_SYMBOL(__quantum__qis__cu1__body); + REGISTER_SYMBOL(__quantum__qis__cu3__body); + REGISTER_SYMBOL(__quantum__qis__cnot__body); + REGISTER_SYMBOL(__quantum__qis__cx__body); + REGISTER_SYMBOL(__quantum__qis__cy__body); + REGISTER_SYMBOL(__quantum__qis__cz__body); + REGISTER_SYMBOL(__quantum__qis__ch__body); + REGISTER_SYMBOL(__quantum__qis__swap__body); + REGISTER_SYMBOL(__quantum__qis__cswap__body); + REGISTER_SYMBOL(__quantum__qis__crz__body); + REGISTER_SYMBOL(__quantum__qis__cry__body); + REGISTER_SYMBOL(__quantum__qis__crx__body); + REGISTER_SYMBOL(__quantum__qis__cp__body); + REGISTER_SYMBOL(__quantum__qis__ccx__body); + REGISTER_SYMBOL(__quantum__qis__ccy__body); + REGISTER_SYMBOL(__quantum__qis__ccz__body); + REGISTER_SYMBOL(__quantum__qis__m__body); + REGISTER_SYMBOL(__quantum__qis__measure__body); + REGISTER_SYMBOL(__quantum__qis__mz__body); + REGISTER_SYMBOL(__quantum__qis__reset__body); + REGISTER_SYMBOL(__quantum__rt__initialize); + REGISTER_SYMBOL(__quantum__rt__read_result); + REGISTER_SYMBOL(__quantum__rt__result_record_output); return runOrcJIT(); } diff --git a/src/qir/runtime/QIR.cpp b/src/qir/runtime/QIR.cpp index 04439c421d..67b3a51645 100644 --- a/src/qir/runtime/QIR.cpp +++ b/src/qir/runtime/QIR.cpp @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include extern "C" { @@ -71,13 +69,9 @@ int64_t __quantum__rt__array_get_size_1d(const Array* array) { } int8_t* __quantum__rt__array_get_element_ptr_1d(Array* array, const int64_t i) { - if (i < 0) { - throw std::out_of_range("Index out of bounds (negative): " + - std::to_string(i)); - } - if (const auto size = __quantum__rt__array_get_size_1d(array); i >= size) { - throw std::out_of_range("Index out of bounds (size: " + - std::to_string(size) + "): " + std::to_string(i)); + if (array == nullptr || i < 0 || + i >= __quantum__rt__array_get_size_1d(array)) { + return nullptr; } return &array->data[static_cast(array->elementSize * i)]; } diff --git a/test/qir/runner/CMakeLists.txt b/test/qir/runner/CMakeLists.txt index 17ab32f8f3..aefa15ad6b 100644 --- a/test/qir/runner/CMakeLists.txt +++ b/test/qir/runner/CMakeLists.txt @@ -14,8 +14,9 @@ if(TARGET MQT::CoreQIRRunner) # Collect QIR files set(QIR_FILES "") set(QIR_FILES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) + file(REAL_PATH "${QIR_FILES_DIR}" QIR_FILES_DIR) file(GLOB QIR_FILES "${QIR_FILES_DIR}/*.ll") - # transform QIR_EXECUTABLES to comma separated list of string ("...") + # transform QIR_FILES to comma separated list of string ("...") string(REPLACE ";" "\",\"" QIR_FILES "\"${QIR_FILES}\"") # Set the executable path and version information target_compile_definitions( diff --git a/test/qir/runner/test_qir_runner.cpp b/test/qir/runner/test_qir_runner.cpp index fba8b6c46d..2156763f71 100644 --- a/test/qir/runner/test_qir_runner.cpp +++ b/test/qir/runner/test_qir_runner.cpp @@ -22,16 +22,16 @@ INSTANTIATE_TEST_SUITE_P( QIRRunnerTest, //< Test suite name // Parameters to test with ::testing::Values(QIR_FILES), - [](const testing::TestParamInfo& info) { + [](const testing::TestParamInfo& paramInfo) { // Extract the last part of the file path - auto filename = info.param.stem().string(); + auto filename = paramInfo.param.stem().string(); return filename; }); TEST_P(QIRRunnerTest, QIRFile) { const auto& file = GetParam(); std::ostringstream command; - command << "\"" << EXECUTABLE_PATH << "\" \"" << file << "\""; + command << EXECUTABLE_PATH << " " << file; const auto result = std::system(command.str().c_str()); EXPECT_EQ(result, 0); }