Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
df8b97b
Migrate unified compiler to Catalyst
mudit2812 Nov 17, 2025
9536707
Fixing migration artifacts; linting
mudit2812 Nov 17, 2025
1453aae
Fix CI errors; Ignore unified compiler in coverage reports
mudit2812 Nov 17, 2025
efc0f88
Test out how graphviz is installed
mudit2812 Nov 17, 2025
10cd749
Lint some more
mudit2812 Nov 17, 2025
27de22d
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 17, 2025
f7aa2b6
[skip ci] Skip CI
mudit2812 Nov 17, 2025
012f58b
[skip ci] Skip CI
mudit2812 Nov 17, 2025
f0a0c90
Merge branch 'migrate-unified-compiler' of https://github.com/PennyLa…
mudit2812 Nov 17, 2025
c98755e
Try installing graphviz with apt
mudit2812 Nov 17, 2025
bb5bd00
Fix codefactor complaints
mudit2812 Nov 17, 2025
1448472
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 17, 2025
5e745f5
Try appeasing codefactor again
mudit2812 Nov 17, 2025
0409933
Try appeasing codefactor once again
mudit2812 Nov 17, 2025
e786a12
Pylint suppression
mudit2812 Nov 17, 2025
4ae10ff
Reduce complexity of stablehlo.reduce and stablehlo.dynamic_broadcast…
mudit2812 Nov 17, 2025
dc41a7b
Fix some failures
mudit2812 Nov 18, 2025
58b13e4
Try change to graphviz installation
mudit2812 Nov 18, 2025
4e5f904
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 18, 2025
637d2cf
Try installing graphviz with pip
mudit2812 Nov 18, 2025
091c5e1
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 18, 2025
64e0fd4
Try installing graphviz with both apt and pip
mudit2812 Nov 18, 2025
dc15d3a
Add utils file to remove conftest imports
mudit2812 Nov 18, 2025
e7e33d6
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 18, 2025
f919e8d
Remove unused imports
mudit2812 Nov 18, 2025
005ba9f
Add graphviz dependencies to lightning.kokkos testing workflow
mudit2812 Nov 18, 2025
6117189
Update cookbook
mudit2812 Nov 18, 2025
6961324
Migrate all changelog entries from PennyLane
mudit2812 Nov 18, 2025
0fdbb46
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 18, 2025
a868bc3
Add EOF new line to .codecov.yml
mudit2812 Nov 18, 2025
8f00b2f
change changelog entry slightly
mudit2812 Nov 18, 2025
22a6e6e
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 20, 2025
b4a321d
Merge branch 'main' into migrate-unified-compiler
mudit2812 Nov 26, 2025
4cbe02a
Remove reference to 'remove-chained-self-inverses'
mudit2812 Nov 26, 2025
c5f08c3
Remove leftover references to pennylane.compiler.python_compiler
mudit2812 Nov 27, 2025
fe76357
Streamline circuit inspection utilities (#2237)
jzaia18 Dec 1, 2025
3395581
Merge branch 'main' into migrate-unified-compiler
mudit2812 Dec 1, 2025
a69c9ba
Remove more references to python_compiler
mudit2812 Dec 1, 2025
9d208f9
Address more code review comments
mudit2812 Dec 1, 2025
8ce6f96
Fix jit
mudit2812 Dec 1, 2025
664d24a
Fix jit again
mudit2812 Dec 1, 2025
e07a332
Merge branch 'main' into migrate-unified-compiler
mudit2812 Dec 1, 2025
f9035c0
Fix line-too-long
mudit2812 Dec 1, 2025
ca1aa3a
Merge branch 'migrate-unified-compiler' of https://github.com/PennyLa…
mudit2812 Dec 1, 2025
7f4eb06
Remove the local transform dialect (#2261)
mehrdad2m Dec 3, 2025
24eb758
Merge branch 'main' into migrate-unified-compiler
dime10 Dec 3, 2025
b6fb585
[skip ci] add importorskip for graphviz to mlir_graph tests
mudit2812 Dec 5, 2025
0b1f237
Merge branch 'migrate-unified-compiler' of https://github.com/PennyLa…
mudit2812 Dec 5, 2025
8ef2b58
Merge branch 'main' into migrate-unified-compiler
mudit2812 Dec 5, 2025
848795d
[skip ci] Skip CI
mudit2812 Dec 5, 2025
58e06f0
Merge branch 'migrate-unified-compiler' of https://github.com/PennyLa…
mudit2812 Dec 5, 2025
14eb727
Update .codecov.yml
mudit2812 Dec 5, 2025
d7fac31
Add importorskip xdsl
mudit2812 Dec 5, 2025
f07194e
Merge branch 'migrate-unified-compiler' of https://github.com/PennyLa…
mudit2812 Dec 5, 2025
58ee0d9
Add xdsl marker
mudit2812 Dec 5, 2025
bc123b1
Separate xdsl tests into isolated steps
mudit2812 Dec 5, 2025
87d05f9
codefactor
mudit2812 Dec 5, 2025
4a7986a
Merge branch 'main' into migrate-unified-compiler
mudit2812 Dec 5, 2025
40deba6
Try to fix failures
mudit2812 Dec 5, 2025
08c6bc0
Remove unnecessary testing from wheel workflows
mudit2812 Dec 5, 2025
22019e4
Remove markers
mudit2812 Dec 5, 2025
0d3d055
Add eof newline
mudit2812 Dec 5, 2025
f8c338b
Use brew to install graphviz in macos wheel build
mudit2812 Dec 5, 2025
e56c163
Organize changelog entries
mudit2812 Dec 5, 2025
54f5756
Remove xdsl kokkos tests from check-catalyst
mudit2812 Dec 5, 2025
f26c6f2
Apply suggestions from code review
mudit2812 Dec 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ coverage:
status:
project: false
patch: true

# TODO: add coverage for the python compiler interface
ignore:
- "frontend/catalyst/python_interface"
13 changes: 13 additions & 0 deletions .github/workflows/build-wheel-linux-arm64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -501,3 +501,16 @@ jobs:
if: env.BUILD_STANDALONE_PLUGIN == 'true'
run: |
python${{ matrix.python_version }} -m pytest standalone_plugin_wheel/standalone_plugin/test -n auto
- name: Install Unified Compiler Dependencies
run: |
python${{ matrix.python_version }} -m pip install xdsl~=0.55.0 xdsl-jax==0.1.1
# Install graphviz for testing the mlir-op-graph integration
sudo apt-get install -y graphviz
python${{ matrix.python_version }} -m pip install graphviz
- name: Run Unified Compiler Tests
run: |
python${{ matrix.python_version }} -m pytest frontend/test/pytest -n auto -m "xdsl"
11 changes: 11 additions & 0 deletions .github/workflows/build-wheel-linux-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -520,3 +520,14 @@ jobs:
if: env.BUILD_STANDALONE_PLUGIN == 'true'
run: |
python${{ matrix.python_version }} -m pytest standalone_plugin_wheel/standalone_plugin/test -n auto
- name: Install Unified Compiler Dependencies
run: |
python${{ matrix.python_version }} -m pip install xdsl~=0.55.0 xdsl-jax==0.1.1
# Install graphviz for testing the mlir-op-graph integration
sudo apt-get install -y graphviz
python${{ matrix.python_version }} -m pip install graphviz
- name: Run Unified Compiler Tests
run: |
python${{ matrix.python_version }} -m pytest frontend/test/pytest -n auto -m "xdsl"
11 changes: 11 additions & 0 deletions .github/workflows/build-wheel-macos-arm64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -501,3 +501,14 @@ jobs:
if: env.BUILD_STANDALONE_PLUGIN == 'true'
run: |
python${{ matrix.python_version }} -m pytest standalone_plugin_wheel/standalone_plugin/test -n auto
- name: Install Unified Compiler Dependencies
run: |
python${{ matrix.python_version }} -m pip install xdsl~=0.55.0 xdsl-jax==0.1.1
# Install graphviz for testing the mlir-op-graph integration
brew install graphviz
python${{ matrix.python_version }} -m pip install graphviz
- name: Run Unified Compiler Tests
run: |
python${{ matrix.python_version }} -m pytest frontend/test/pytest -n auto -m "xdsl"
11 changes: 11 additions & 0 deletions .github/workflows/check-catalyst.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,17 @@ jobs:
MDD_BENCHMARK_PRECISION=1 \
python3 -m pytest demos -k "tutorial_qft_arithmetics.ipynb" --nbmake

- name: Install Unified Compiler Dependencies
run: |
python3 -m pip install xdsl~=0.55.0 xdsl-jax==0.1.1
# Install graphviz for testing the mlir-op-graph integration
sudo apt-get install -y graphviz
python3 -m pip install graphviz

- name: Run Unified Compiler Tests
run: |
python3 -m pytest frontend/test/pytest -n auto -m "xdsl"

frontend-tests-lightning-kokkos:
name: Frontend Tests (backend="lightning.kokkos")
needs: [constants, llvm, runtime, quantum, determine_runner]
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/check-pl-compat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,36 @@ jobs:
# We skip them for now. These demos should be properly moved to the qml repo.
MDD_BENCHMARK_PRECISION=1 \
python3 -m pytest demos -k "tutorial_qft_arithmetics.ipynb" --nbmake

- name: Check If Unified Compiler Tests Should Execute
id: check_unified_compiler
run: |
# Check if installed pennylane has python_compiler module
EXIT_CODE=0
python3 -c "from pennylane.compiler import python_compiler" || EXIT_CODE=$?

# For Unified Compiler tests to execute, PennyLane must NOT have the 'compiler.python_compiler'
# submodule, and Catalyst MUST have the 'python_interface' submodule
if [[ -d "$GITHUB_WORKSPACE/frontend/catalyst/python_interface" && EXIT_CODE -ne 0 ]]; then
echo "unified_compiler_available='true'" >> $GITHUB_OUTPUT
else
echo "unified_compiler_available='false'" >> $GITHUB_OUTPUT
fi

- name: Install Unified Compiler Dependencies
if: steps.check_unified_compiler.outputs.unified_compiler_available == 'true'
run: |
python3 -m pip install xdsl~=0.55.0 xdsl-jax==0.1.1
# Install graphviz for testing the mlir-op-graph integration
sudo apt-get install -y graphviz
python3 -m pip install graphviz

- name: Run Unified Compiler Tests
if: steps.check_unified_compiler.outputs.unified_compiler_available == 'true'
run: |
python3 -m pytest frontend/test/pytest -n auto -m "xdsl"

- name: Run Unified Compiler Tests (Kokkos)
if: steps.check_unified_compiler.outputs.unified_compiler_available == 'true'
run: |
python3 -m pytest frontend/test/pytest --backend="lightning.kokkos" -n auto -m "xdsl"
103 changes: 92 additions & 11 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,98 @@

<h3>New features since last release</h3>

* Catalyst now features a unified compilation framework, which enables users and developers to design
and implement compilation passes in Python in addition to C++, on the same Catalyst IR. The Python
interface relies on the xDSL library to represent and manipulate programs (analogous to the MLIR library
in C++). As a result, transformations can be quickly prototyped, easily debugged, and dynamically integrated
into Catalyst without changes to the compiled Catalyst package. The new module is available under the
`catalyst.python_interface` namespace.
[(#2199)](https://github.com/PennyLaneAI/catalyst/pull/2199)

This functionality was originally developed as part of the PennyLane package, and has been migrated here.
For earlier development notes to the feature, please refer to the
[PennyLane release notes](https://docs.pennylane.ai/en/stable/development/release_notes.html#release-0-43-0).
In addition, the following changes have been made since the last release:

* Add an experimental `outline_state_evolution_pass` xDSL pass to `catalyst.python_interface.transforms`,
which moves all quantum gate operations to a private callable.
[(#8367)](https://github.com/PennyLaneAI/pennylane/pull/8367)

* A new experimental `split_non_commuting_pass` compiler pass has been added to
`catalyst.python_interface.transforms`. This pass splits quantum functions that
measure observables on the same wires into multiple function executions, where
each execution measures observables on different wires (using the "wires" grouping
strategy). The original function is replaced with calls to these generated functions,
and the results are combined appropriately.
[(#8531)](https://github.com/PennyLaneAI/pennylane/pull/8531)

* Add the `PCPhaseOp` operation to the xDSL Quantum dialect.
[(#8621)](https://github.com/PennyLaneAI/pennylane/pull/8621)

* Users can now apply xDSL passes without the need to pass the `pass_plugins` argument to
the `qjit` decorator.
[(#8572)](https://github.com/PennyLaneAI/pennylane/pull/8572)
[(#8573)](https://github.com/PennyLaneAI/pennylane/pull/8573)
[(#2169)](https://github.com/PennyLaneAI/catalyst/pull/2169)
[(#2183)](https://github.com/PennyLaneAI/catalyst/pull/2183)

* The :meth:`catalyst.python_interface.transforms.convert_to_mbqc_formalism_pass` now
supports :class:`~xdsl.dialects.scf.IndexSwitchOp` in IR and ignores regions that have no body.
[(#8632)](https://github.com/PennyLaneAI/pennylane/pull/8632)

* The `convert_to_mbqc_formalism` compilation pass now outlines the operations to represent a gate
in the MBQC formalism into subroutines in order to reduce the IR size for large programs.
[(#8619)](https://github.com/PennyLaneAI/pennylane/pull/8619)

* The :meth:`catalyst.python_interface.Compiler.run` method now accepts a string as input,
which is parsed and transformed with xDSL.
[(#8587)](https://github.com/PennyLaneAI/pennylane/pull/8587)

* An `is_xdsl_pass` function has been added to the `catalyst.python_interface.pass_api` module.
This function checks if a pass name corresponds to an xDSL implemented pass.
[(#8572)](https://github.com/PennyLaneAI/pennylane/pull/8572)

* A new `catalyst.python_interface.utils` submodule has been added, containing general-purpose utilities for
working with xDSL. This includes a function that extracts the concrete value of scalar, constant SSA values.
[(#8514)](https://github.com/PennyLaneAI/pennylane/pull/8514)

* The `catalyst.python_interface.visualization` module has been renamed to
`catalyst.python_interface.inspection`, and various utility functions within this module
have been streamlined.
[(#2237)](https://github.com/PennyLaneAI/catalyst/pull/2237)

* The experimental xDSL :func:`~catalyst.python_interface.transforms.measurements_from_samples_pass`
pass has been updated to support `shots` defined by an `arith.constant` operation.
[(#8460)](https://github.com/PennyLaneAI/pennylane/pull/8460)

* The experimental xDSL :func:`~catalyst.python_interface.transforms.diagonalize_measurements`
pass has been updated to fix a bug that included the wrong SSA value for final qubit insertion
and deallocation at the end of the circuit. A clear error is now also raised when there are
observables with overlapping wires.
[(#8383)](https://github.com/PennyLaneAI/pennylane/pull/8383)

* Fixes a bug in the constructor of the xDSL Quantum dialect's `QubitUnitaryOp` that
prevented an instance from being constructed.
[(#8456)](https://github.com/PennyLaneAI/pennylane/pull/8456)

* Removed the `catalyst.python_interface.dialects.transform` module in favor of
using the `xdsl.dialects.transform` module directly.
[(#2261)](https://github.com/PennyLaneAI/catalyst/pull/2261)

* Added a "Unified Compiler Cookbook" RST file, along with tutorials, to `catalyst.python_interface.doc`,
which provides a quickstart guide for getting started with xDSL and its integration with PennyLane and
Catalyst.
[(#8571)](https://github.com/PennyLaneAI/pennylane/pull/8571)

* xDSL passes are now automatically detected when using the `qjit` decorator.
This removes the need to pass the `pass_plugins` argument to the `qjit` decorator.
[(#2169)](https://github.com/PennyLaneAI/catalyst/pull/2169)
[(#2183)](https://github.com/PennyLaneAI/catalyst/pull/2183)

* The ``mlir_opt`` property now correctly handles xDSL passes by automatically
detecting when the Python compiler is being used and routing through it appropriately.
[(#2190)](https://github.com/PennyLaneAI/catalyst/pull/2190)

* RTIO dialect is added to bypass the compilation flow from OpenAPL to ARTIQ’s LLVM IR. It is introduced to bridge the gap between ION dialect and ARTIQ’s LLVM IR. The design philosophy of RTIO dialect is primarily event-based. Every operation is asynchronous; sync behaviour occurs only via `rtio.sync` or `wait operand` in event operation.
[(#2185)](https://github.com/PennyLaneAI/catalyst/pull/2185)

Expand Down Expand Up @@ -127,15 +219,6 @@
* `qml.grad` and `qml.jacobian` can now be used with `qjit` when program capture is enabled.
[(#2078)](https://github.com/PennyLaneAI/catalyst/pull/2078)

* xDSL passes are now automatically detected when using the `qjit` decorator.
This removes the need to pass the `pass_plugins` argument to the `qjit` decorator.
[(#2169)](https://github.com/PennyLaneAI/catalyst/pull/2169)
[(#2183)](https://github.com/PennyLaneAI/catalyst/pull/2183)

* The ``mlir_opt`` property now correctly handles xDSL passes by automatically
detecting when the Python compiler is being used and routing through it appropriately.
[(#2190)](https://github.com/PennyLaneAI/catalyst/pull/2190)

* Dynamically allocated wires can now be passed into control flow and subroutines.
[(#2130)](https://github.com/PennyLaneAI/catalyst/pull/2130)

Expand Down Expand Up @@ -340,11 +423,9 @@
[(#2245)](https://github.com/PennyLaneAI/catalyst/pull/2245)
[(#2254)](https://github.com/PennyLaneAI/catalyst/pull/2254)


* Refactor QEC tablegen files to separate QEC operations into a new `QECOp.td` file
[(#2253](https://github.com/PennyLaneAI/catalyst/pull/2253)


* Removed the `getRotationKind` and `setRotationKind` methods from
the QEC interface `QECOpInterface` to simplify the interface.
[(#2250)](https://github.com/PennyLaneAI/catalyst/pull/2250)
Expand Down
19 changes: 10 additions & 9 deletions frontend/catalyst/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,13 @@ def to_mlir_opt(
*args, stdin=None, options: Optional[CompileOptions] = None, using_python_compiler=False
):
"""echo ${input} | catalyst --tool=opt *args *opts -"""
# Check if we need to use Python compiler for xDSL passes
# Check if we need to use the Python interface for xDSL passes
if using_python_compiler:
# Use Python compiler path for xDSL passes
# Use the Python interface path for xDSL passes
# pylint: disable-next=import-outside-toplevel
from pennylane.compiler.python_compiler import Compiler as PythonCompiler
from catalyst.python_interface import Compiler as UnifiedCompiler

compiler = PythonCompiler()
compiler = UnifiedCompiler()
stdin = compiler.run(stdin, callback=None)

# These are the options that may affect compilation
Expand Down Expand Up @@ -548,7 +548,7 @@ def check_nested_operations(op):

@debug_logger
def is_using_python_compiler(self, mlir_module=None):
"""Returns true if we need the Python compiler path.
"""Returns true if we need the Python interface path.

This happens when:
1. xDSL plugin is explicitly loaded (legacy), OR
Expand Down Expand Up @@ -594,7 +594,8 @@ def _create_xdsl_pass_save_callback(self, workspace):
workspace: The workspace directory path

Returns:
Callable or None: The callback function if intermediate saving is enabled, None otherwise
Callable or None: The callback function if intermediate saving is enabled, None
otherwise
"""
if not (workspace and self.options.keep_intermediate >= KeepIntermediateLevel.CHANGED):
return None
Expand All @@ -606,7 +607,7 @@ def _create_xdsl_pass_save_callback(self, workspace):
os.makedirs(user_transform_dir, exist_ok=True)

class SavePassIRCallback:
"""Callback to save IR after each pass in python_compiler."""
"""Callback to save IR after each pass in python_interface."""

def __init__(self, transform_dir):
self.transform_dir = transform_dir
Expand Down Expand Up @@ -666,10 +667,10 @@ def run(self, mlir_module, *args, **kwargs):
# We keep this module here to keep xDSL requirement optional
# Only move this is it has been decided that xDSL is no longer optional.
# pylint: disable-next=import-outside-toplevel
from pennylane.compiler.python_compiler import Compiler as PythonCompiler
from catalyst.python_interface import Compiler as UnifiedCompiler

callback = self._create_xdsl_pass_save_callback(workspace)
compiler = PythonCompiler()
compiler = UnifiedCompiler()
ir = compiler.run(ir, callback=callback)

return self.run_from_ir(
Expand Down
4 changes: 1 addition & 3 deletions frontend/catalyst/jax_primitives_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,7 @@ def transform_named_sequence_lowering(jax_ctx: mlir.LoweringRuleContext, pipelin

try:
# pylint: disable=import-outside-toplevel
from pennylane.compiler.python_compiler.pass_api import (
is_xdsl_pass,
)
from catalyst.python_interface.pass_api import is_xdsl_pass

if is_xdsl_pass(name):
uses_xdsl_passes = True
Expand Down
26 changes: 26 additions & 0 deletions frontend/catalyst/python_interface/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2025 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unified Compiler API for integration of Catalyst with xDSL."""

from .compiler import Compiler
from .inspection import QMLCollector
from .parser import QuantumParser
from .pass_api import compiler_transform

__all__ = [
"Compiler",
"compiler_transform",
"QuantumParser",
"QMLCollector",
]
Loading