Skip to content
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

Circuit cutting: Remove circuit cuts that do not result in a disconnection #2260

Merged
merged 26 commits into from
Mar 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
67e57ff
Add check to ensure all fragments are connected to the output
trbromley Feb 28, 2022
4dcc37d
Add test
trbromley Feb 28, 2022
597905e
Merge branch 'master' into qcut_remove_unneeded_subgraphs
trbromley Feb 28, 2022
4477238
Fix test
trbromley Feb 28, 2022
98106f8
Merge branch 'qcut_remove_unneeded_subgraphs' of github.com:XanaduAI/…
trbromley Feb 28, 2022
7dbad6f
Remove nodes
trbromley Feb 28, 2022
387cc78
Merge branch 'master' into qcut_remove_unneeded_subgraphs
trbromley Mar 1, 2022
9d19b7e
Update changelog
trbromley Mar 1, 2022
ce83dbb
Switch order
trbromley Mar 1, 2022
8369fc1
Add integration test
trbromley Mar 1, 2022
7e4dead
Fix CI
trbromley Mar 1, 2022
a1dad8e
Merge branch 'master' into qcut_remove_unneeded_subgraphs
trbromley Mar 1, 2022
81c660d
Don't use JAX
trbromley Mar 1, 2022
8e6bc60
Add test
trbromley Mar 1, 2022
d23eb90
Remove contained nodes
trbromley Mar 1, 2022
809d818
Add to changelog
trbromley Mar 1, 2022
b0111c9
Add unit test
trbromley Mar 1, 2022
d36c2f7
Merge branch 'master' into qcut_remove_contained_cuts
trbromley Mar 2, 2022
5982e32
Fix changelog
trbromley Mar 2, 2022
2116399
Remove test
trbromley Mar 2, 2022
5d47925
Fix test
trbromley Mar 2, 2022
68507be
Fix pylint
trbromley Mar 2, 2022
8d07e90
Merge branch 'master' into qcut_remove_contained_cuts
trbromley Mar 2, 2022
b358d1d
Add clarification
trbromley Mar 2, 2022
5a2d8e3
Merge branch 'master' into qcut_remove_contained_cuts
trbromley Mar 3, 2022
b3236fa
Merge branch 'master' into qcut_remove_contained_cuts
trbromley Mar 3, 2022
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
3 changes: 3 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@

Circuit fragments that are disconnected from the terminal measurements are now removed.
[(#2254)](https://github.com/PennyLaneAI/pennylane/pull/2254)

`WireCut` operations that do not lead to a disconnection are now being removed.
[(#2260)](https://github.com/PennyLaneAI/pennylane/pull/2260)

<h3>Improvements</h3>

Expand Down
12 changes: 11 additions & 1 deletion pennylane/transforms/qcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ def tape_to_graph(tape: QuantumTape) -> MultiDiGraph:
return graph


# pylint: disable=too-many-branches
def fragment_graph(graph: MultiDiGraph) -> Tuple[Tuple[MultiDiGraph], MultiDiGraph]:
"""
Fragments a graph into a collection of subgraphs as well as returning
Expand Down Expand Up @@ -305,7 +306,16 @@ def fragment_graph(graph: MultiDiGraph) -> Tuple[Tuple[MultiDiGraph], MultiDiGra
if subgraph.has_node(node2):
end_fragment = i

communication_graph.add_edge(start_fragment, end_fragment, pair=(node1, node2))
if start_fragment != end_fragment:
communication_graph.add_edge(start_fragment, end_fragment, pair=(node1, node2))
else:
# The MeasureNode and PrepareNode pair live in the same fragment and did not result
# in a disconnection. We can therefore remove these nodes. Note that we do not need
# to worry about adding back an edge between the predecessor to node1 and the successor
# to node2 because our next step is to convert the fragment circuit graphs to tapes,
# a process that does not depend on edge connections in the subgraph.
subgraphs[start_fragment].remove_node(node1)
subgraphs[end_fragment].remove_node(node2)

terminal_indices = [i for i, s in enumerate(subgraphs) for n in measure_nodes if s.has_node(n)]

Expand Down
21 changes: 19 additions & 2 deletions tests/transforms/test_qcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from itertools import product

import pytest
from networkx import MultiDiGraph
from networkx import MultiDiGraph, number_of_selfloops
from scipy.stats import unitary_group

import pennylane as qml
Expand Down Expand Up @@ -900,6 +900,23 @@ def test_communication_graph_persistence(self):
assert communication_graph_0.nodes == communication_graph_1.nodes
assert communication_graph_0.edges == communication_graph_1.edges

def test_contained_cut(self):
"""Tests that fragmentation ignores `MeasureNode` and `PrepareNode` pairs that do not
result in a disconnection"""
with qml.tape.QuantumTape() as tape:
qml.RX(0.4, wires=0)
qml.CNOT(wires=[0, 1])
qml.WireCut(wires=0)
qml.CNOT(wires=[0, 1])
qml.RX(0.4, wires=0)
qml.expval(qml.PauliZ(0))

g = qcut.tape_to_graph(tape)
qcut.replace_wire_cut_nodes(g)
fragments, communication_graph = qcut.fragment_graph(g)
assert len(fragments) == 1
assert number_of_selfloops(communication_graph) == 0


class TestGraphToTape:
"""Tests that directed multigraphs are correctly converted to tapes"""
Expand Down Expand Up @@ -2095,7 +2112,7 @@ def circuit(x):
res = circuit(x)
assert np.allclose(res, np.cos(x))
assert len(spy.call_args[0][0]) == 1 # there should be 2 tensors for wire 0
assert spy.call_args[0][0][0].shape == (4, 4)
assert spy.call_args[0][0][0].shape == ()
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did this have to change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The circuit in this test actually has a fully contained cut. Beforehand, we were going over all measurement and preparation configurations even though the cut didn't result in a disconnection. So we'd have a (4, 4) tensor with contraction equation a,a



class TestCutCircuitTransformValidation:
Expand Down