Skip to content
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
567 commits
Select commit Hold shift + click to select a range
434c500
fix
andrijapau Dec 1, 2025
cfa5f3b
add more tests
andrijapau Dec 1, 2025
a62f2b1
add dev comments
andrijapau Dec 1, 2025
d9026ef
more testing
andrijapau Dec 1, 2025
faf338f
move things around
andrijapau Dec 1, 2025
5d03a81
add more qol
andrijapau Dec 2, 2025
56e4756
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Dec 2, 2025
c95c45f
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Dec 2, 2025
18aa30b
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Dec 2, 2025
929bd23
add flattened ifop ability
andrijapau Dec 2, 2025
709e961
Merge branch 'feature/visualize-qnode' into feature/control-flow-clus…
andrijapau Dec 2, 2025
b51bb7b
fix
andrijapau Dec 2, 2025
89f45f3
fix
andrijapau Dec 2, 2025
b45b2f0
fix
andrijapau Dec 2, 2025
2028fa7
fix
andrijapau Dec 2, 2025
4e994e6
simplify PR by making it for ...
andrijapau Dec 2, 2025
e590847
format
andrijapau Dec 2, 2025
eb6a0c3
fix tests
andrijapau Dec 2, 2025
7eb31b6
format
andrijapau Dec 2, 2025
8e787c9
fix logic in flatten if op
andrijapau Dec 2, 2025
8b6287f
format
andrijapau Dec 2, 2025
83ebb18
fix type hinting
andrijapau Dec 2, 2025
6d84d36
add dev comment
andrijapau Dec 2, 2025
1d8ac14
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 2, 2025
3c42841
more deviceop tests
andrijapau Dec 2, 2025
e319aae
Apply suggestion from @andrijapau
andrijapau Dec 2, 2025
1c9c857
re-order changelog
andrijapau Dec 2, 2025
093a5d5
Merge branch 'feature/visualize-qnode' into feature/control-flow-clus…
andrijapau Dec 2, 2025
2ca7bb8
add cl entry
andrijapau Dec 2, 2025
9d724bf
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 2, 2025
61b70d9
add smaller fontsize for the conditional bit
andrijapau Dec 2, 2025
25aa04b
cl
andrijapau Dec 2, 2025
d613c1b
Apply suggestion from @andrijapau
andrijapau Dec 2, 2025
3a2ab18
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 2, 2025
e9c69d8
format
andrijapau Dec 2, 2025
73c8a0f
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 2, 2025
f47b1a5
fix id to uid
andrijapau Dec 2, 2025
98c9175
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 2, 2025
5e83fe4
fix
andrijapau Dec 2, 2025
3d80d1a
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 2, 2025
d5a0611
Apply suggestion from @andrijapau
andrijapau Dec 2, 2025
0cd2f7d
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 2, 2025
858f40e
add good static connectivity
andrijapau Dec 2, 2025
3d0af6a
rename
andrijapau Dec 2, 2025
98bf7ea
clean-up
andrijapau Dec 2, 2025
818448c
clean up
andrijapau Dec 2, 2025
b924c43
format
andrijapau Dec 2, 2025
046196f
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 2, 2025
08082d9
clean-up
andrijapau Dec 2, 2025
f23b550
refactor
andrijapau Dec 2, 2025
437c7d8
make sure data is not carried over between qnodes
andrijapau Dec 3, 2025
39d6ea6
format
andrijapau Dec 3, 2025
089cb14
both single and multi qnode have qjit bounding box
andrijapau Dec 3, 2025
2a2d55c
Apply suggestion from @andrijapau
andrijapau Dec 3, 2025
220c6d5
Merge branch 'feature/visualize-qnode' into feature/control-flow-clus…
andrijapau Dec 3, 2025
f7261a9
add more detail to the for loop label
andrijapau Dec 3, 2025
a8cd49c
format
andrijapau Dec 3, 2025
44bf9d3
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 3, 2025
9c907c4
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 3, 2025
70b0d93
fix test
andrijapau Dec 3, 2025
d983e97
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 3, 2025
68c6ec0
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 3, 2025
f25dd2a
Apply suggestion from @andrijapau
andrijapau Dec 4, 2025
cb05921
use counter instead of builtin id function
andrijapau Dec 4, 2025
1883fb3
whoops
andrijapau Dec 4, 2025
5e2d456
Apply suggestion from @andrijapau
andrijapau Dec 4, 2025
36b5f7d
Apply suggestion from @andrijapau
andrijapau Dec 4, 2025
ee15b67
Apply suggestion from @andrijapau
andrijapau Dec 4, 2025
16e003d
add two counters
andrijapau Dec 4, 2025
23561f7
Merge branch 'feature/visualize-qnode' into feature/control-flow-clus…
andrijapau Dec 4, 2025
d5ccaf7
use the counters for uid
andrijapau Dec 4, 2025
1dd9f38
update tests to be simpler
andrijapau Dec 4, 2025
6a9b01d
fix tests
andrijapau Dec 4, 2025
a2ac9ff
minor fix
andrijapau Dec 4, 2025
0dbe4fe
foramt
andrijapau Dec 4, 2025
d92aea4
Merge branch 'feature/visualize-qnode' into feature/control-flow-clus…
andrijapau Dec 4, 2025
8afc67a
Apply suggestion from @andrijapau
andrijapau Dec 4, 2025
c0d4d67
update tests
andrijapau Dec 4, 2025
9706967
update tests
andrijapau Dec 4, 2025
5e62c31
format
andrijapau Dec 4, 2025
1474a66
whoops fix test
andrijapau Dec 4, 2025
82430af
Merge branch 'feature/visualize-qnode' into feature/control-flow-clus…
andrijapau Dec 4, 2025
ced6f75
format
andrijapau Dec 4, 2025
649aed2
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 4, 2025
9c74b6a
update id
andrijapau Dec 4, 2025
6d46b94
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 4, 2025
56c70c9
update logic
andrijapau Dec 4, 2025
5641e68
fix test
andrijapau Dec 4, 2025
4ffc9d3
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 4, 2025
a544727
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 4, 2025
22c8ae1
add more nested testing
andrijapau Dec 4, 2025
ab7c471
format
andrijapau Dec 4, 2025
dd1df44
adjust test
andrijapau Dec 4, 2025
57409bd
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 4, 2025
336d2e5
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 4, 2025
9996684
fix test
andrijapau Dec 4, 2025
303fb03
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 4, 2025
c262df9
format
andrijapau Dec 4, 2025
05df88c
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 4, 2025
d66ff68
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 4, 2025
3175efa
add tests
andrijapau Dec 4, 2025
194b357
fix get_nodes -> nodes
andrijapau Dec 4, 2025
a9125f5
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 4, 2025
aea60d0
add test skeeltons
andrijapau Dec 4, 2025
506f839
fix labels
andrijapau Dec 4, 2025
f67802f
fix labels
andrijapau Dec 4, 2025
ad35efc
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 4, 2025
75bdd32
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 4, 2025
fac6150
fix measure
andrijapau Dec 5, 2025
6d3c256
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
9bdf8da
fix globalphase test
andrijapau Dec 5, 2025
df222e2
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
b9479b1
fix sample test
andrijapau Dec 5, 2025
e38737c
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
60e83c4
fix sample
andrijapau Dec 5, 2025
ebd108e
format
andrijapau Dec 5, 2025
bfd1d10
add dev comment
andrijapau Dec 5, 2025
aec9f83
fix code
andrijapau Dec 5, 2025
aa7dd72
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
c36a43e
fix naming
andrijapau Dec 5, 2025
6c1d825
add expected error messages
andrijapau Dec 5, 2025
4dddd74
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
7b56f89
fix test for probs
andrijapau Dec 5, 2025
1712a27
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
4f83355
format
andrijapau Dec 5, 2025
67759dd
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
9f6a131
add compileerror
andrijapau Dec 5, 2025
9855985
update
andrijapau Dec 5, 2025
4f0a8f4
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
30db67e
Merge branch 'feature/graph-visualization' into feature/control-flow-…
andrijapau Dec 5, 2025
2fe2074
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 5, 2025
d069fef
fix
andrijapau Dec 5, 2025
b65ae16
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 5, 2025
e29f546
bring back ssavalue
andrijapau Dec 5, 2025
b34d8e2
format
andrijapau Dec 5, 2025
aa1d90c
format
andrijapau Dec 5, 2025
d3fdfea
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 5, 2025
5d9f21c
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
27ff971
remove random import
andrijapau Dec 5, 2025
1a0ac68
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 5, 2025
19b326a
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
5e3a6d2
re-work node labels to be records with ports
andrijapau Dec 5, 2025
a25f7b4
format
andrijapau Dec 5, 2025
02d4a55
fix tests
andrijapau Dec 5, 2025
a9a89a9
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
b58602d
format
andrijapau Dec 5, 2025
68c2488
whoops
andrijapau Dec 5, 2025
7237a3f
move mid measure to an operator
andrijapau Dec 5, 2025
d28eb63
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 5, 2025
fc3ea2c
add connectivity to MCMs
andrijapau Dec 5, 2025
6410aae
fix test
andrijapau Dec 6, 2025
7cbfe6a
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 8, 2025
20efb54
get rid of unnecessary function
andrijapau Dec 9, 2025
81e9fe5
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Dec 9, 2025
dcf59ae
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
7eb1da4
Update frontend/test/pytest/python_interface/visualization/test_const…
andrijapau Dec 9, 2025
f7daa8a
Update doc/releases/changelog-dev.md
andrijapau Dec 9, 2025
80da43c
Update frontend/test/pytest/python_interface/visualization/test_const…
andrijapau Dec 9, 2025
5fc9cf1
fix bug and add test coverage
andrijapau Dec 9, 2025
ef5550f
fix test and format
andrijapau Dec 9, 2025
5476e6d
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
dfde76d
format
andrijapau Dec 9, 2025
ecddff7
fix
andrijapau Dec 9, 2025
c2bd854
remove ssa condition, not needed for now
andrijapau Dec 9, 2025
4176d03
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
f8b2922
refactor a bit
andrijapau Dec 9, 2025
89dad36
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
e58cc4e
add another test
andrijapau Dec 9, 2025
1877cf9
whoops
andrijapau Dec 9, 2025
8643a24
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
c35b8c1
Apply suggestion from @andrijapau
andrijapau Dec 9, 2025
5728859
Apply suggestion from @andrijapau
andrijapau Dec 9, 2025
5345dfc
format
andrijapau Dec 9, 2025
04ee8e2
update how the node labels look
andrijapau Dec 9, 2025
74e8358
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
77e63d9
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 9, 2025
63ea212
Apply suggestion from @andrijapau
andrijapau Dec 9, 2025
be6a32b
Apply suggestion from @andrijapau
andrijapau Dec 9, 2025
3e455bb
whoops
andrijapau Dec 9, 2025
d143ed0
fix test
andrijapau Dec 9, 2025
d8c1b7a
improve logic
andrijapau Dec 9, 2025
bafd278
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 9, 2025
44643f7
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 9, 2025
284f56b
Update frontend/catalyst/python_interface/visualization/construct_cir…
andrijapau Dec 9, 2025
8b2ec3c
remove redundant label
andrijapau Dec 9, 2025
488de58
add dev comment
andrijapau Dec 9, 2025
490949b
format
andrijapau Dec 9, 2025
4430396
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 9, 2025
3494f17
improve function naming
andrijapau Dec 9, 2025
0f49fb3
add more tests
andrijapau Dec 9, 2025
d682702
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 9, 2025
9e41561
Apply suggestion from @andrijapau
andrijapau Dec 9, 2025
7c4c552
fix tests
andrijapau Dec 10, 2025
5451853
fix test
andrijapau Dec 10, 2025
c8f39fb
adjust pydotdagbuilder to have orthogonal edges
andrijapau Dec 10, 2025
1d755ad
revert dag builder changes
andrijapau Dec 10, 2025
3a8628b
revert
andrijapau Dec 10, 2025
a128861
revert
andrijapau Dec 10, 2025
435aabb
add basic probs state test
andrijapau Dec 10, 2025
fee7e1b
fix labels for measurements
andrijapau Dec 10, 2025
c5c6e28
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
e15bdc0
add record
andrijapau Dec 10, 2025
895105d
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
e735e37
format
andrijapau Dec 10, 2025
2071360
Merge branch 'feature/graph-visualization' into feature/control-flow-…
andrijapau Dec 10, 2025
c86043f
remove node label
andrijapau Dec 10, 2025
5aeba5e
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 10, 2025
d542968
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
ea8c9b7
add labeljust
andrijapau Dec 10, 2025
d224c0c
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 10, 2025
5d27922
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
8392c2b
remove comment
andrijapau Dec 10, 2025
2fc5b7c
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
80798f9
fix cluster
andrijapau Dec 10, 2025
cb1e531
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 10, 2025
bf3607f
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
1f48498
fix
andrijapau Dec 10, 2025
f1b6a6f
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
ac5ffe7
Apply suggestion from @andrijapau
andrijapau Dec 10, 2025
5f3a208
fix test
andrijapau Dec 10, 2025
27cc772
Merge branch 'feature/control-flow-clusters' into feature/visualize-n…
andrijapau Dec 10, 2025
90e6588
fix
andrijapau Dec 10, 2025
2983d67
fix
andrijapau Dec 10, 2025
d914ed0
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
24ffa25
Merge branch 'feature/graph-visualization' into feature/visualize-nodes
andrijapau Dec 10, 2025
822f929
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
c9ec867
fix
andrijapau Dec 10, 2025
37a4f18
Merge branch 'feature/visualize-nodes' into feature/connect-nodes
andrijapau Dec 10, 2025
bd178e1
Merge branch 'feature/graph-visualization' into feature/connect-nodes
andrijapau Dec 10, 2025
c6e9eb0
Merge branch 'feature/graph-visualization' into feature/connect-nodes
andrijapau Dec 10, 2025
a094ca1
Merge branch 'feature/graph-visualization' into feature/connect-nodes
andrijapau Dec 11, 2025
e18cd6f
fix test
andrijapau Dec 11, 2025
d8c2ab8
Merge branch 'feature/graph-visualization' into feature/connect-nodes
andrijapau Dec 11, 2025
3620b5d
add more test
andrijapau Dec 11, 2025
5dc5437
format
andrijapau Dec 11, 2025
becf7ee
merge all measurements into one handler
andrijapau Dec 11, 2025
9216c4b
minor clean-up
andrijapau Dec 11, 2025
ccd9c65
Add back comment
andrijapau Dec 11, 2025
17d2f5d
Apply suggestion from @andrijapau
andrijapau Dec 11, 2025
e05f354
format
andrijapau Dec 11, 2025
c591c3a
add more tests
andrijapau Dec 11, 2025
94ec4af
Apply suggestion from @andrijapau
andrijapau Dec 11, 2025
9de7f94
add operator connectivity for multi wire
andrijapau Dec 11, 2025
6ba5541
multi wire connectivity for measurements
andrijapau Dec 11, 2025
b0e665e
add basic test
andrijapau Dec 11, 2025
d54a42a
clean up
andrijapau Dec 11, 2025
e203b15
whoops
andrijapau Dec 11, 2025
188dc06
fix
andrijapau Dec 11, 2025
ce238c4
fix
andrijapau Dec 11, 2025
2563a88
Trigger CI
andrijapau Dec 11, 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 @@ -11,6 +11,7 @@
[(#2285)](https://github.com/PennyLaneAI/catalyst/pull/2285)
[(#2234)](https://github.com/PennyLaneAI/catalyst/pull/2234)
[(#2218)](https://github.com/PennyLaneAI/catalyst/pull/2218)
[(#2260)](https://github.com/PennyLaneAI/catalyst/pull/2260)

* 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,24 @@

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

from collections import defaultdict
from functools import singledispatch, singledispatchmethod

from pennylane.measurements import ExpectationMP, MeasurementProcess, ProbabilityMP, VarianceMP
from pennylane.operation import Operator
from xdsl.dialects import builtin, func, scf
from xdsl.ir import Block, Operation, Region, SSAValue

from catalyst.python_interface.dialects import quantum
from catalyst.python_interface.inspection.xdsl_conversion import (
xdsl_to_qml_measurement,
xdsl_to_qml_op,
)
from catalyst.python_interface.visualization.dag_builder import DAGBuilder
from pennylane.measurements import (
ExpectationMP,
MeasurementProcess,
ProbabilityMP,
VarianceMP,
)
from pennylane.operation import Operator
from xdsl.dialects import builtin, func, scf
from xdsl.ir import Block, Operation, Region, SSAValue


class ConstructCircuitDAG:
Expand All @@ -50,6 +55,11 @@ def __init__(self, dag_builder: DAGBuilder) -> None:
# Keep track of nesting clusters using a stack
self._cluster_uid_stack: list[str] = []

# Create a map of wire to node uid
# Keys represent static (int) or dynamic wires (str)
# Values represent the set of all node uids that are on that wire.
self._wire_to_node_uids: dict[str | int, set[str]] = defaultdict(set)

# Use counter internally for UID
self._node_uid_counter: int = 0
self._cluster_uid_counter: int = 0
Expand All @@ -59,6 +69,7 @@ def _reset(self) -> None:
self._cluster_uid_stack: list[str] = []
self._node_uid_counter: int = 0
self._cluster_uid_counter: int = 0
self._wire_to_node_uids: dict[str | int, set[str]] = defaultdict(set)

def construct(self, module: builtin.ModuleOp) -> None:
"""Constructs the DAG from the module.
Expand Down Expand Up @@ -98,7 +109,10 @@ def _visit_block(self, block: Block) -> None:
@_visit_operation.register
def _gate_op(
self,
op: quantum.CustomOp | quantum.GlobalPhaseOp | quantum.QubitUnitaryOp | quantum.MultiRZOp,
op: quantum.CustomOp
| quantum.GlobalPhaseOp
| quantum.QubitUnitaryOp
| quantum.MultiRZOp,
) -> None:
"""Generic handler for unitary gates."""

Expand All @@ -116,6 +130,17 @@ def _gate_op(
)
self._node_uid_counter += 1

# Search through previous ops found on current wires and connect
prev_ops = set.union(
set(), *(self._wire_to_node_uids[wire] for wire in qml_op.wires)
)
for prev_op in prev_ops:
self.dag_builder.add_edge(prev_op, node_uid)

# Update affected wires to source from this node UID
for wire in qml_op.wires:
self._wire_to_node_uids[wire] = {node_uid}

@_visit_operation.register
def _projective_measure_op(self, op: quantum.MeasureOp) -> None:
"""Handler for the single-qubit projective measurement operation."""
Expand All @@ -134,82 +159,80 @@ def _projective_measure_op(self, op: quantum.MeasureOp) -> None:
)
self._node_uid_counter += 1

# Search through previous ops found on current wires and connect
prev_node_uids = set.union(
set(), *(self._wire_to_node_uids[wire] for wire in meas.wires)
)
for prev_node_uid in prev_node_uids:
self.dag_builder.add_edge(prev_node_uid, node_uid)

# Update affected wires to source from this node UID
for wire in meas.wires:
self._wire_to_node_uids[wire] = {node_uid}

# =====================
# QUANTUM MEASUREMENTS
# =====================

@_visit_operation.register
def _state_op(self, op: quantum.StateOp) -> None:
"""Handler for the terminal state measurement operation."""

# Create PennyLane instance
meas = xdsl_to_qml_measurement(op)

# Add node to current cluster
node_uid = f"node{self._node_uid_counter}"
self.dag_builder.add_node(
uid=node_uid,
label=get_label(meas),
cluster_uid=self._cluster_uid_stack[-1],
fillcolor="lightpink",
color="lightpink3",
# NOTE: "record" allows us to use ports (https://graphviz.org/doc/info/shapes.html#record)
shape="record",
)
self._node_uid_counter += 1

@_visit_operation.register
def _expval_and_var_ops(
def _handle_measurements(
self,
op: quantum.ExpvalOp | quantum.VarianceOp,
op: quantum.StateOp
| quantum.ExpvalOp
| quantum.VarianceOp
| quantum.SampleOp
| quantum.ProbsOp,
) -> None:
"""Handler for statistical measurement operations."""
"""Handler for all quantum measurement operations."""

# Create PennyLane instance
obs_op = op.obs.owner
meas = xdsl_to_qml_measurement(op, xdsl_to_qml_measurement(obs_op))
prev_wires = []
meas = None

# Add node to current cluster
node_uid = f"node{self._node_uid_counter}"
self.dag_builder.add_node(
uid=node_uid,
label=get_label(meas),
cluster_uid=self._cluster_uid_stack[-1],
fillcolor="lightpink",
color="lightpink3",
# NOTE: "record" allows us to use ports (https://graphviz.org/doc/info/shapes.html#record)
shape="record",
)
self._node_uid_counter += 1
match op:
case quantum.StateOp():
meas = xdsl_to_qml_measurement(op)
# NOTE: state can only handle all wires
prev_wires = self._wire_to_node_uids.keys()

@_visit_operation.register
def _sample_counts_probs_ops(
self,
op: quantum.SampleOp | quantum.ProbsOp,
) -> None:
"""Handler for sample operations."""
case quantum.ExpvalOp() | quantum.VarianceOp():
obs_op = op.obs.owner
meas = xdsl_to_qml_measurement(op, xdsl_to_qml_measurement(obs_op))
prev_wires = meas.wires.labels

# Create PennyLane instance
obs_op = op.obs.owner
case quantum.SampleOp() | quantum.ProbsOp():
obs_op = op.obs.owner

# TODO: This doesn't logically make sense, but quantum.compbasis
# is obs_op and function below just pulls out the static wires
wires = xdsl_to_qml_measurement(obs_op)
meas = xdsl_to_qml_measurement(op, wires=None if wires == [] else wires)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Bit of a rough diff but I essentially merged all handlers into one.

# TODO: This doesn't logically make sense, but quantum.compbasis
# is obs_op and function below just pulls out the static wires
wires = xdsl_to_qml_measurement(obs_op)
meas = xdsl_to_qml_measurement(op, wires=None if wires == [] else wires)

if wires == []:
# If no wires specified, connect to all seen current wires
prev_wires = self._wire_to_node_uids.keys()
else:
# Use the specific wires from the observable
prev_wires = wires

case _:
return

# Add node to current cluster
node_uid = f"node{self._node_uid_counter}"
self.dag_builder.add_node(
uid=node_uid,
label=get_label(meas),
cluster_uid=self._cluster_uid_stack[-1],
fillcolor="lightpink",
color="lightpink3",
# NOTE: "record" allows us to use ports (https://graphviz.org/doc/info/shapes.html#record)
shape="record",
)
self._node_uid_counter += 1

for wire in prev_wires:
if wire in self._wire_to_node_uids:
for seen_node in self._wire_to_node_uids[wire]:
self.dag_builder.add_edge(seen_node, node_uid, color="lightpink3")

# =============
# CONTROL FLOW
# =============
Expand Down Expand Up @@ -263,6 +286,10 @@ def _if_op(self, operation: scf.IfOp):
self._cluster_uid_stack.append(uid)
self._cluster_uid_counter += 1

# Save wires state before all of the branches
wire_map_before = self._wire_to_node_uids.copy()
region_wire_maps: list[dict[int | str, set[str]]] = []

# Loop through each branch and visualize as a cluster
flattened_if_op: list[Region] = _flatten_if_op(operation)
num_regions = len(flattened_if_op)
Expand All @@ -284,16 +311,42 @@ def _if_op(self, operation: scf.IfOp):
self._cluster_uid_stack.append(uid)
self._cluster_uid_counter += 1

# Make fresh wire map before going into region
self._wire_to_node_uids = wire_map_before.copy()

# Go recursively into the branch to process internals
self._visit_region(region)

# Update branch wire maps
if self._wire_to_node_uids != wire_map_before:
region_wire_maps.append(self._wire_to_node_uids)

# Pop branch cluster after processing to ensure
# logical branches are treated as 'parallel'
self._cluster_uid_stack.pop()

# Pop IfOp cluster before leaving this handler
self._cluster_uid_stack.pop()

# Check what wires were affected
affected_wires: set[str | int] = set(wire_map_before.keys())
for region_wire_map in region_wire_maps:
affected_wires.update(region_wire_map.keys())

# Update state to be the union of all branch wire maps
final_wire_map = defaultdict(set)
for wire in affected_wires:
all_nodes: set = set()
for region_wire_map in region_wire_maps:
if not wire in region_wire_map:
# IfOp region didn't apply anything on this wire
# so default to node before the IfOp
all_nodes.update(wire_map_before.get(wire, set()))
else:
all_nodes.update(region_wire_map.get(wire, set()))
final_wire_map[wire] = all_nodes
self._wire_to_node_uids = final_wire_map

# ============
# DEVICE NODE
# ============
Expand Down Expand Up @@ -326,7 +379,9 @@ def _func_op(self, operation: func.FuncOp) -> None:
label = "qjit"

uid = f"cluster{self._cluster_uid_counter}"
parent_cluster_uid = None if self._cluster_uid_stack == [] else self._cluster_uid_stack[-1]
parent_cluster_uid = (
None if self._cluster_uid_stack == [] else self._cluster_uid_stack[-1]
)
self.dag_builder.add_cluster(
uid,
label=label,
Expand All @@ -348,6 +403,9 @@ def _func_return(self, operation: func.ReturnOp) -> None:
# the FuncOp's scope and so we can pop the ID off the stack.
self._cluster_uid_stack.pop()

# Clear seen wires as we are exiting a FuncOp (qnode)
self._wire_to_node_uids = defaultdict(set)


def _flatten_if_op(op: scf.IfOp) -> list[Region]:
"""Recursively flattens a nested IfOp (if/elif/else chains)."""
Expand Down
Loading
Loading