Skip to content

Commit a9e2c1c

Browse files
authored
Add experimental xDSL plugin (#1707)
**Context:** We need a way to find out if we are running passes in xDSL or in MLIR. Plugins already kind of do this, so let's model xDSL as an MLIR plugin. **Description of the Change:** This commit adds a fake MLIR plugin that denotes the use of xDSL. Its sole purpose is to find out if the user requests to run passes from xDSL and it is removed before being sent to the compiler.
1 parent 85942a4 commit a9e2c1c

File tree

6 files changed

+88
-0
lines changed

6 files changed

+88
-0
lines changed

doc/releases/changelog-dev.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@
7878

7979
<h3>Internal changes ⚙️</h3>
8080

81+
* Add an xDSL MLIR plugin to denote whether we will be using xDSL to execute some passes.
82+
This changelog entry may be moved to new features once all branches are merged together.
83+
[(#1707)](https://github.com/PennyLaneAI/catalyst/pull/1707)
84+
8185
* Creates a function that allows developers to register an equivalent MLIR transform for a given
8286
PLxPR transform.
8387
[(#1705)](https://github.com/PennyLaneAI/catalyst/pull/1705)

frontend/catalyst/compiler.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,29 @@ def run_from_ir(self, ir: str, module_name: str, workspace: Directory):
467467

468468
return output_object_name, out_IR
469469

470+
@debug_logger
471+
def is_using_python_compiler(self):
472+
"""Returns true if we detect that there is an xdsl plugin in use.
473+
474+
Will also modify self.options.pass_plugins and self.options.dialect_plugins to remove
475+
the xdsl plugin.
476+
"""
477+
xdsl_path = pathlib.Path("xdsl-does-not-use-a-real-path")
478+
if not (
479+
xdsl_path in self.options.pass_plugins or xdsl_path in self.options.dialect_plugins
480+
):
481+
return False
482+
483+
if xdsl_path in self.options.pass_plugins:
484+
plugins = self.options.pass_plugins
485+
self.options.pass_plugins = tuple(elem for elem in plugins if elem != xdsl_path)
486+
487+
if xdsl_path in self.options.dialect_plugins:
488+
plugins = self.options.dialect_plugins
489+
self.options.dialect_plugins = tuple(elem for elem in plugins if elem != xdsl_path)
490+
491+
return True
492+
470493
@debug_logger
471494
def run(self, mlir_module, *args, **kwargs):
472495
"""Compile an MLIR module to a shared object.
@@ -483,6 +506,8 @@ def run(self, mlir_module, *args, **kwargs):
483506
(str): filename of shared object
484507
"""
485508

509+
self.is_using_python_compiler()
510+
486511
return self.run_from_ir(
487512
mlir_module.operation.get_asm(
488513
binary=False, print_generic_op_form=False, assume_verified=True
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright 2025 Xanadu Quantum Technologies Inc.
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""XDSL Plugin Interface"""
16+
17+
# This file contains what looks like a plugin
18+
# but in reality it is just not a "real" MLIR plugin.
19+
# It just follows the same convention to be able to add passes
20+
# that are implemented in xDSL
21+
22+
import importlib.util
23+
from pathlib import Path
24+
25+
26+
def getXDSLPluginAbsolutePath():
27+
"""Returns a fake path"""
28+
try:
29+
# pylint: disable-next=import-outside-toplevel,unused-import
30+
import xdsl
31+
except ImportError as e:
32+
# pragma: nocover
33+
msg = "The xdsl plugin requires the xdsl package to be installed"
34+
raise ImportError(msg) from e
35+
36+
return Path("xdsl-does-not-use-a-real-path")
37+
38+
39+
def name2pass(name):
40+
"""Identity function
41+
42+
This function is useful if we want a map from user-facing pass name
43+
to mlir-facing pass names.
44+
"""
45+
return getXDSLPluginAbsolutePath(), name

frontend/test/pytest/test_mlir_plugin_interface.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,15 @@ def test_get_options():
9191
== "an-option bn-option"
9292
)
9393
assert catalyst.passes.Pass("example-pass", option=True).get_options() == "option=True"
94+
95+
96+
def test_xdsl_plugin():
97+
"""Here, we just test that we are able to run."""
98+
99+
@catalyst.qjit
100+
@catalyst.passes.apply_pass("catalyst_xdsl_plugin.remove-chained-self-inverse")
101+
@qml.qnode(qml.device("null.qubit", wires=1))
102+
def example():
103+
return qml.state()
104+
105+
example()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ nbmake
2929
# optional rt/test dependencies
3030
pennylane-lightning-kokkos
3131
amazon-braket-pennylane-plugin>1.27.1
32+
xdsl

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ def parse_dep_versions():
147147
"cuda_quantum.ops = catalyst.api_extensions",
148148
"cuda_quantum.qjit = catalyst.third_party.cuda:cudaqjit",
149149
],
150+
"catalyst.passes_resolution": ["catalyst_xdsl_plugin.passes = catalyst.passes.xdsl_plugin"],
150151
}
151152

152153
classifiers = [

0 commit comments

Comments
 (0)