Skip to content

MLIR Conversion(s) #880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 129 commits into
base: main
Choose a base branch
from
Open

MLIR Conversion(s) #880

wants to merge 129 commits into from

Conversation

flowerthrower
Copy link
Collaborator

Description

This PR originates from this mqt-mlir PR and introduces conversions between Catalysts quantum dialect and the MQTOpt dialect.

Checklist:

  • The pull request only contains commits that are related to it.
  • I have added appropriate tests and documentation.
  • I have made sure that all CI jobs on GitHub pass.
  • The pull request introduces no new warnings and follows the project's style guidelines.

@github-project-automation github-project-automation bot moved this to In Progress in MQT Core Mar 19, 2025
@flowerthrower flowerthrower self-assigned this Mar 19, 2025
@flowerthrower flowerthrower added MLIR Anything related to MLIR feature New feature or request labels Mar 19, 2025
@flowerthrower flowerthrower added this to the MLIR Support milestone Mar 19, 2025
Copy link

codecov bot commented Mar 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

📢 Thoughts on this report? Let us know!

@burgholzer
Copy link
Member

Now that #879 is merged, this needs to be rebased

burgholzer added a commit that referenced this pull request Apr 24, 2025
## Description

Reincarnate MLIR / LLVM 19.0 support.
Necessary for Catalyst-related efforts (like #880).

## Checklist:

<!---
This checklist serves as a reminder of a couple of things that ensure
your pull request will be merged swiftly.
-->

- [x] The pull request only contains commits that are related to it.
- [x] I have added appropriate tests and documentation.
- [x] I have made sure that all CI jobs on GitHub pass.
- [x] The pull request introduces no new warnings and follows the
project's style guidelines.

---------

Signed-off-by: Patrick Hopf <[email protected]>
Co-authored-by: flowerthrower <[email protected]>
Co-authored-by: Lukas Burgholzer <[email protected]>
Co-authored-by: Yannick Stade <[email protected]>
@flowerthrower flowerthrower marked this pull request as ready for review April 25, 2025 10:39
Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @flowerthrower for your tireless work on this!
I still haven't managed to fully review the actual conversion passes, but made another detailed pass on the infrastructure surrounding the conversions.

Most of the feedback is inline already.
The main reason for clang-tidy to report somewhat bogus results is that it simply cannot find the catalyst headers, so it gets confused.
This also points to one of the things, that is not an inline comment: We really want to be testing this integration in CI with an appropriate amount of tests.
The CI workflow should be set up to install Catalyst and successfully build the project. Otherwise, the confidence in the code working as expected will not be very high over time.
At some point, we want to distribute this integration to third parties, where this has to be seamless.

Ideally, we would add an optional python dependency group for catalyst, similar to qiskit (

core/pyproject.toml

Lines 49 to 51 in 79cb99f

qiskit = [
"qiskit[qasm3-import]>=1.0.0",
]
) and would use Python whenever available to detect the installed version of Catalyst or to point find_package to the right direction. We do something pretty similar for mqt-core and pybind11 in most of our projects: https://github.com/cda-tum/mqt-qcec/blob/aa833928fcd47ee132075e90a301aa0277e7f476/cmake/ExternalDependencies.cmake#L6-L33

Comment on lines 35 to 37
if(NOT MLIR_VERSION_MAJOR EQUAL 19)
message(FATAL_ERROR "Catalyst currently requires MLIR 19.x")
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still trying to understand if this is a hard requirement.
I'd like to see this in action in CI and see how/if/when it fails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this will probably be painfull to write, but can we please

  • split these tests up so that they are more fine-granular and test more specific things
  • explicitly test all supported operations as well as non-supported operations and their conversion.

https://github.com/munich-quantum-toolkit/core/blob/main/mlir/test/Dialect/MQTOpt/Transforms/consecutive-inverses.mlir is a good blueprint for more extensive tests at the moment.

If this is enough of a pain point to find a better way to test the infrastructure, then so be it.
We are adding quite some functionality here, so it should also be tested appropriately.
Most likely, we should be collecting coverage metrics for the MLIR part of the project. (this will have to wait for another PR though)

@@ -26,6 +25,13 @@ string(REPLACE "." ";" MLIR_VERSION_COMPONENTS ${MLIR_VERSION})
list(GET MLIR_VERSION_COMPONENTS 0 MLIR_VERSION_MAJOR)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because I stumbe over it right now: Is this gymnastic with the version string necessary or can the VERSION_LESS operator of cmake be used directly? That might make the code cleaner here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to use VERSION_LESS 👍🏼

Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of comments because the PR notifications where in my inbox 😌

uses: Chocobo1/setup-ccache-action@v1
with:
prepend_symlinks_to_path: false
override_cache_key: c++-tests-mlir
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fairly sure you need to use a different cache key here, otherwise there will be cache contention between the jobs.

Suggested change
override_cache_key: c++-tests-mlir
override_cache_key: c++-tests-mlir-catalyst

If we extend the matrix of CI workflows above, the cache key should also be updated.

Comment on lines +78 to +79
- name: Set macOS deployment target for linker
run: echo "MACOSX_DEPLOYMENT_TARGET=14.0" >> $GITHUB_ENV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary as you are running on macOS 14 already.

Comment on lines +78 to +79
- name: Set macOS deployment target for linker
run: echo "MACOSX_DEPLOYMENT_TARGET=14.0" >> $GITHUB_ENV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary as you are running on macOS 14 already.

# build MLIRQuantum
- name: Build MLIRQuantum dialect
run: |
ninja -C catalyst/mlir/build MLIRQuantum
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ninja -C catalyst/mlir/build MLIRQuantum
cmake --build catalyst/mlir/build --target MLIRQuantum

Comment on lines +22 to +25
runs-on: macos-14
strategy:
matrix:
llvm-version: [19]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be interesting to see this work on macos-13 (x86 runners) as well as llvm-version: 20.
The current build pipeline seems to pass, which is great already!

Unrelated to this PR in particular, but what could be a nice byproduct in a separate PR is that this already represents a functional macOS-14 CI pipeline for MLIR, which would be part of #925.

Comment on lines +89 to +94
if(Catalyst_DIR)
list(APPEND CMAKE_PREFIX_PATH "${Catalyst_DIR}")
find_package(Catalyst REQUIRED)
else()
message(STATUS "Could not detect Catalyst CMake directory")
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to fail hard if Catalyst cannot be found.

Suggested change
if(Catalyst_DIR)
list(APPEND CMAKE_PREFIX_PATH "${Catalyst_DIR}")
find_package(Catalyst REQUIRED)
else()
message(STATUS "Could not detect Catalyst CMake directory")
endif()
find_package(Catalyst REQUIRED)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once a compatible version of Catalyst is released, this will probably also require a version specifier to indicate the minimum version required.

Comment on lines +78 to +88
# Manually detect the installed Catalyst Python and get its cmake directory.
execute_process(
COMMAND "${Python_EXECUTABLE}" -c
"import catalyst, os; print(os.path.dirname(catalyst.__file__))"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE Python_Catalyst_DIR
ERROR_QUIET)
message(STATUS "Found Catalyst package: ${Python_Catalyst_DIR}")

# TODO: once the Catalyst Python package provides the necessary files set(Catalyst_DIR
# "${Python_Catalyst_DIR}/mlir/build/lib/cmake/catalyst")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, there would be no need to do something like set(Catalyst_DIR "${Python_Catalyst_DIR}/..., but Catalyst_DIR would already be a result of the execute_process call.
Either catalyst provides an entry point for that (similar to pybind, nanobind, or mqt-core), or we parse this somewhat from output similar to the existing command here by a simple Python script.

Comment on lines +15 to +16
# if(MLIR_VERSION VERSION_LESS MQT_MLIR_MIN_VERSION) message(FATAL_ERROR "MLIR version must be at
# least ${MQT_MLIR_MIN_VERSION} but found ${MLIR_VERSION}") endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this commented out?

Suggested change
# if(MLIR_VERSION VERSION_LESS MQT_MLIR_MIN_VERSION) message(FATAL_ERROR "MLIR version must be at
# least ${MQT_MLIR_MIN_VERSION} but found ${MLIR_VERSION}") endif()
if(MLIR_VERSION VERSION_LESS MQT_MLIR_MIN_VERSION)
message(FATAL_ERROR "MLIR version must be at least ${MQT_MLIR_MIN_VERSION}")
endif()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request MLIR Anything related to MLIR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants