Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
265cd4d
copy files over
andrijapau Nov 19, 2025
e9ceaa7
add pydot to requirements.txt
andrijapau Nov 19, 2025
ae50ca1
add files
andrijapau Nov 19, 2025
a0e37b0
rename
andrijapau Nov 19, 2025
76b5565
add base class
andrijapau Nov 19, 2025
659f480
quick changes
andrijapau Nov 19, 2025
8699557
add control flow support
andrijapau Nov 19, 2025
db6edc9
clean-up
andrijapau Nov 19, 2025
2be63e4
Apply suggestion from @andrijapau
andrijapau Nov 20, 2025
12fa2af
Apply suggestion from @andrijapau
andrijapau Nov 20, 2025
2c93330
Apply suggestion from @andrijapau
andrijapau Nov 20, 2025
e68c3f4
Apply suggestion from @andrijapau
andrijapau Nov 20, 2025
4aad864
Apply suggestion from @andrijapau
andrijapau Nov 20, 2025
3be39dc
update cluster label logic
andrijapau Nov 20, 2025
a383ba8
fix dag builders test
andrijapau Nov 20, 2025
8ddaa5d
fix pydot dag builders test
andrijapau Nov 20, 2025
1166f40
update doc
andrijapau Nov 20, 2025
b0fbf7e
Merge branch 'feature/graph-visualization' into feature/dag-builders
andrijapau Nov 20, 2025
df9bf45
basic cl
andrijapau Nov 20, 2025
bd75450
Merge branch 'feature/dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 20, 2025
8ca5b1f
basic cl
andrijapau Nov 20, 2025
b579a3f
Trigger CI
andrijapau Nov 20, 2025
a94d843
Trigger CI
andrijapau Nov 20, 2025
331e349
Apply suggestion from @andrijapau
andrijapau Nov 20, 2025
a87d117
just do customop
andrijapau Nov 20, 2025
9713aa3
fix wording
andrijapau Nov 20, 2025
68e8453
Merge branch 'feature/graph-visualization' into feature/dag-builders
andrijapau Nov 20, 2025
8faae36
Merge branch 'feature/dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 20, 2025
7bbc224
rename
andrijapau Nov 20, 2025
d6db965
add back
andrijapau Nov 20, 2025
11b08f0
Update frontend/catalyst/python_interface/visualization/pydot_dag_bui…
andrijapau Nov 20, 2025
a76b5bd
Update frontend/catalyst/python_interface/visualization/pydot_dag_bui…
andrijapau Nov 20, 2025
66a87ab
Merge branch 'feature/dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 20, 2025
90e4ebd
fix
andrijapau Nov 20, 2025
3d9e4bb
fix
andrijapau Nov 20, 2025
e303ef1
Merge branch 'feature/graph-visualization' into feature/mlir-to-dag-pass
andrijapau Nov 20, 2025
2504c13
clean-up
andrijapau Nov 21, 2025
4e78777
remove unnecessary stuff
andrijapau Nov 21, 2025
e17c111
add test skeleton
andrijapau Nov 21, 2025
19ca1b5
add basic tests
andrijapau Nov 21, 2025
7f88834
basic test idea
andrijapau Nov 21, 2025
3d48c92
make visit private
andrijapau Nov 21, 2025
49b3834
make visit private
andrijapau Nov 21, 2025
80ca59d
fix tests
andrijapau Nov 21, 2025
430ceb8
fix tests
andrijapau Nov 22, 2025
0aff4e5
clean-up
andrijapau Nov 24, 2025
e22cbd2
fix: upgrade DAG builders to have get_ methods
andrijapau Nov 24, 2025
acf3da7
cl
andrijapau Nov 24, 2025
bc978ad
update pydot to adhere to new base class methods
andrijapau Nov 24, 2025
dc4cb1c
add test skeletons
andrijapau Nov 24, 2025
7e825d6
add tests
andrijapau Nov 24, 2025
41fc4d1
Apply suggestion from @andrijapau
andrijapau Nov 24, 2025
1868346
add tests
andrijapau Nov 24, 2025
fd8d721
fix tests
andrijapau Nov 24, 2025
284ba07
update tests
andrijapau Nov 24, 2025
95ace87
fix documentation
andrijapau Nov 24, 2025
ec9caae
fix documentation
andrijapau Nov 24, 2025
99bd602
fix tests
andrijapau Nov 24, 2025
7622b50
whoops
andrijapau Nov 24, 2025
86e8389
whoops
andrijapau Nov 24, 2025
a5dc1ac
rename a bunch of stuff
andrijapau Nov 24, 2025
fe7ef47
fix documentation
andrijapau Nov 24, 2025
b2a13cf
rename a bunch of stuff
andrijapau Nov 24, 2025
abfd932
add dev comment
andrijapau Nov 24, 2025
a481a04
rename
andrijapau Nov 24, 2025
9a18e5c
update test
andrijapau Nov 24, 2025
afa60ee
merge fix/upgrade-dag-builders to feature/mlir-to-dag-pass
andrijapau Nov 24, 2025
0f6ab76
add immutability tests
andrijapau Nov 24, 2025
5584c90
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 24, 2025
6d15d7b
clean-up
andrijapau Nov 25, 2025
888d025
clean-up
andrijapau Nov 25, 2025
d4b34f9
whoops
andrijapau Nov 25, 2025
2f27f08
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 25, 2025
33aa334
fix test
andrijapau Nov 25, 2025
d50cfdc
whoops
andrijapau Nov 25, 2025
a364869
cleanup
andrijapau Nov 25, 2025
cddb234
clean-up
andrijapau Nov 25, 2025
1b5210c
fix formatting issue
andrijapau Nov 25, 2025
14b28bb
isort
andrijapau Nov 25, 2025
a1e9211
update tests
andrijapau Nov 25, 2025
aad7449
Apply suggestion from @andrijapau
andrijapau Nov 25, 2025
8225658
isort
andrijapau Nov 25, 2025
b51016e
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 25, 2025
07a0597
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Nov 25, 2025
40b1eb4
move things around
andrijapau Nov 25, 2025
77dd502
minor cleanup
andrijapau Nov 25, 2025
b4ccd61
refactor the get_ to properties
andrijapau Nov 25, 2025
d354dba
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 25, 2025
d14c15b
update fake dag builder
andrijapau Nov 25, 2025
0e0ddfd
attempt to get rid of _subgraphs
andrijapau Nov 26, 2025
c41adb9
clean-up test
andrijapau Nov 26, 2025
e803543
rename __base__ to None
andrijapau Nov 26, 2025
42cede2
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
085ec57
clean-up
andrijapau Nov 26, 2025
c08a84c
whoops
andrijapau Nov 26, 2025
edc2076
add cluster_ prefix
andrijapau Nov 26, 2025
4c71876
add debug string
andrijapau Nov 26, 2025
f1e5849
bring back cache
andrijapau Nov 26, 2025
0ff2ce9
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
3c9ca3a
add good dev comment
andrijapau Nov 26, 2025
b83e2a4
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
bc54dbf
Apply suggestion from @andrijapau
andrijapau Nov 26, 2025
ee57f40
Apply suggestion from @andrijapau
andrijapau Nov 26, 2025
c341858
whoops
andrijapau Nov 26, 2025
2ded5dc
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
0460cac
refactor singledispatch
andrijapau Nov 26, 2025
0cbe9af
Update frontend/catalyst/python_interface/visualization/dag_builder.py
andrijapau Nov 26, 2025
4dbdb13
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
e752329
add more details to docstring
andrijapau Nov 26, 2025
86b5662
Update frontend/catalyst/python_interface/visualization/dag_builder.py
andrijapau Nov 26, 2025
9c26efd
Update frontend/catalyst/python_interface/visualization/pydot_dag_bui…
andrijapau Nov 26, 2025
81a9aa6
Update frontend/catalyst/python_interface/visualization/pydot_dag_bui…
andrijapau Nov 26, 2025
ab06276
Update frontend/test/pytest/python_interface/visualization/test_pydot…
andrijapau Nov 26, 2025
3e4102b
Update frontend/catalyst/python_interface/visualization/pydot_dag_bui…
andrijapau Nov 26, 2025
194f14a
Update frontend/catalyst/python_interface/visualization/dag_builder.py
andrijapau Nov 26, 2025
685842c
fix fakebackend
andrijapau Nov 26, 2025
986fb3f
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
8c64d81
isort
andrijapau Nov 26, 2025
606f5f5
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
f666a9f
add exceptions check
andrijapau Nov 26, 2025
e28b2b7
add better documentation
andrijapau Nov 26, 2025
952fd7f
fix typo
andrijapau Nov 26, 2025
99f9fc6
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
8f2dc98
Apply suggestion from @andrijapau
andrijapau Nov 26, 2025
eac25d5
Merge branch 'fix/upgrade-dag-builders' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
83225b3
Merge branch 'feature/graph-visualization' into feature/mlir-to-dag-pass
andrijapau Nov 26, 2025
ffc9726
fix naming
andrijapau Nov 26, 2025
08b1e6f
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Nov 28, 2025
3632ebe
mock in test
andrijapau Nov 28, 2025
aa16b2a
format
andrijapau Nov 28, 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
1 change: 1 addition & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Compiled programs can be visualized.
[(#2213)](https://github.com/PennyLaneAI/catalyst/pull/2213)
[(#2229)](https://github.com/PennyLaneAI/catalyst/pull/2229)
[(#2214)](https://github.com/PennyLaneAI/catalyst/pull/2214)

* Added ``catalyst.switch``, a qjit compatible, index-switch style control flow decorator.
[(#2171)](https://github.com/PennyLaneAI/catalyst/pull/2171)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 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.

"""Contains the ConstructCircuitDAG tool for constructing a DAG from an xDSL module."""

from functools import singledispatchmethod

from xdsl.dialects import builtin
from xdsl.ir import Block, Operation, Region

from catalyst.python_interface.visualization.dag_builder import DAGBuilder


class ConstructCircuitDAG:
"""Utility tool following the director pattern to build a DAG representation of a compiled quantum program.

This tool traverses an xDSL module and constructs a Directed Acyclic Graph (DAG)
of it's quantum program using an injected DAGBuilder instance. This tool does not mutate the xDSL module.

**Example**

>>> builder = PyDotDAGBuilder()
>>> director = ConstructCircuitDAG(builder)
>>> director.construct(module)
>>> director.dag_builder.to_string()
...
"""

def __init__(self, dag_builder: DAGBuilder) -> None:
self.dag_builder: DAGBuilder = dag_builder

def construct(self, module: builtin.ModuleOp) -> None:
"""Constructs the DAG from the module.

Args:
module (xdsl.builtin.ModuleOp): The module containing the quantum program to visualize.

"""
for op in module.ops:
self._visit_operation(op)

# =============
# IR TRAVERSAL
# =============

@singledispatchmethod
def _visit_operation(self, operation: Operation) -> None:
"""Visit an xDSL Operation. Default to visiting each region contained in the operation."""
for region in operation.regions:
self._visit_region(region)

def _visit_region(self, region: Region) -> None:
"""Visit an xDSL Region operation."""
for block in region.blocks:
self._visit_block(block)

def _visit_block(self, block: Block) -> None:
"""Visit an xDSL Block operation, dispatching handling for each contained Operation."""
for op in block.ops:
self._visit_operation(op)
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# 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.
"""Unit tests for the ConstructCircuitDAG utility."""

from unittest.mock import Mock

import pytest

pytestmark = pytest.mark.usefixtures("requires_xdsl")

from xdsl.dialects import test
from xdsl.dialects.builtin import ModuleOp
from xdsl.ir.core import Block, Region

# pylint: disable=wrong-import-position
# This import needs to be after pytest in order to prevent ImportErrors
from catalyst.python_interface.visualization.construct_circuit_dag import (
ConstructCircuitDAG,
)
from catalyst.python_interface.visualization.dag_builder import DAGBuilder


class FakeDAGBuilder(DAGBuilder):
"""
A concrete implementation of DAGBuilder used ONLY for testing.
It stores all graph manipulation calls in data structures
for easy assertion of the final graph state.
"""

def __init__(self):
self._nodes = {}
self._edges = []
self._clusters = {}

def add_node(self, id, label, cluster_id=None, **attrs) -> None:
self._nodes[id] = {
"id": id,
"label": label,
"parent_cluster_id": cluster_id,
"attrs": attrs,
}

def add_edge(self, from_id: str, to_id: str, **attrs) -> None:
self._edges.append(
{
"from_id": from_id,
"to_id": to_id,
"attrs": attrs,
}
)

def add_cluster(
self,
id,
node_label=None,
cluster_id=None,
**attrs,
) -> None:
self._clusters[id] = {
"id": id,
"node_label": node_label,
"cluster_label": attrs.get("label"),
"parent_cluster_id": cluster_id,
"attrs": attrs,
}

@property
def nodes(self):
return self._nodes

@property
def edges(self):
return self._edges

@property
def clusters(self):
return self._clusters

def to_file(self, output_filename):
pass

def to_string(self) -> str:
return "graph"


@pytest.mark.unit
def test_dependency_injection():
"""Tests that relevant dependencies are injected."""

mock_dag_builder = Mock(DAGBuilder)
utility = ConstructCircuitDAG(mock_dag_builder)
assert utility.dag_builder is mock_dag_builder


@pytest.mark.unit
def test_does_not_mutate_module():
"""Test that the module is not mutated."""

# Create module
op = test.TestOp()
block = Block(ops=[op])
region = Region(blocks=[block])
container_op = test.TestOp(regions=[region])
module_op = ModuleOp(ops=[container_op])

# Save state before
module_op_str_before = str(module_op)

# Process module
mock_dag_builder = Mock(DAGBuilder)
utility = ConstructCircuitDAG(mock_dag_builder)
utility.construct(module_op)

# Ensure not mutated
assert str(module_op) == module_op_str_before