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

Generate all configurations for a fragment tape #2169

Merged
merged 123 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from 121 commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
3274339
add WireCut operator, add qcut package, update docs
anthayes92 Jan 17, 2022
df01372
add unit test
anthayes92 Jan 17, 2022
bef8586
update changelog
anthayes92 Jan 18, 2022
7e3f493
updates
anthayes92 Jan 18, 2022
f441f10
add tape to graph conversion and unit test
anthayes92 Jan 18, 2022
d32b030
add unit tests
anthayes92 Jan 18, 2022
5c7dccd
add obs to node tests
anthayes92 Jan 19, 2022
56d0b4b
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 20, 2022
1c747cd
restructure qcut module
anthayes92 Jan 20, 2022
2542b74
Merge branch 'sc-13390-a-user-can-convert-a-tape-to-an-accurate' of g…
anthayes92 Jan 20, 2022
c1c5dc5
add tests for observable and measurement conversion to nodes, update …
anthayes92 Jan 21, 2022
b886815
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 21, 2022
24b6765
fix pylint
anthayes92 Jan 21, 2022
d054a6b
Merge branch 'sc-13390-a-user-can-convert-a-tape-to-an-accurate' of g…
anthayes92 Jan 21, 2022
4a1ab6e
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 21, 2022
3b13808
add method to replace Wirecut ops with Measure and Prepare ops
anthayes92 Jan 25, 2022
24af86e
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 25, 2022
58cabdf
add unit tests
anthayes92 Jan 25, 2022
701b9d1
add unit tests, update changelog
anthayes92 Jan 27, 2022
f66bceb
format
anthayes92 Jan 27, 2022
f78d462
set measure and prepare node order to be equal (remove 0.5)
anthayes92 Jan 27, 2022
1364568
Apply suggestions from code review
anthayes92 Jan 27, 2022
a78e07a
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 27, 2022
ecf0d57
add code review suggestions
anthayes92 Jan 27, 2022
8df6d3f
add unit tests
anthayes92 Jan 27, 2022
b61d975
format
anthayes92 Jan 27, 2022
557eaa4
Merge branch 'sc-13390-a-user-can-convert-a-tape-to-an-accurate' into…
anthayes92 Jan 27, 2022
5b6e47e
format
anthayes92 Jan 27, 2022
b51dff1
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 28, 2022
5591931
Apply suggestions from code review
anthayes92 Jan 31, 2022
699f639
add review suggestions
anthayes92 Jan 31, 2022
c3c6df6
Update pennylane/transforms/qcut.py
anthayes92 Jan 31, 2022
43d04a8
Merge branch 'master' into sc-13390-a-user-can-convert-a-tape-to-an-a…
anthayes92 Jan 31, 2022
831d3b3
Apply suggestions from code review
anthayes92 Jan 31, 2022
514e5ba
Merge branch 'sc-13390-a-user-can-convert-a-tape-to-an-accurate' into…
anthayes92 Jan 31, 2022
22a8ff5
Merge branch 'master' into sc-13391-wirecut-nodes-can-be-replaced-wit…
anthayes92 Jan 31, 2022
7cd2af7
add review suggestions
anthayes92 Jan 31, 2022
6861e9e
add unit test
anthayes92 Jan 31, 2022
b1b8573
Merge branch 'master' into sc-13391-wirecut-nodes-can-be-replaced-wit…
anthayes92 Jan 31, 2022
fd7c53a
Merge branch 'master' into sc-13391-wirecut-nodes-can-be-replaced-wit…
anthayes92 Feb 1, 2022
844acb5
update changelog
anthayes92 Feb 1, 2022
616022a
update changelog-0.21.0
anthayes92 Feb 1, 2022
dc06d6a
Apply suggestions from code review
anthayes92 Feb 1, 2022
76befee
apply review suggestions
anthayes92 Feb 1, 2022
755663e
add fragment method and test
anthayes92 Feb 2, 2022
4eda405
Merge branch 'master' into sc-14127-a-user-can-fragment-a-circuit-gra…
trbromley Feb 2, 2022
0489867
Fix merge
trbromley Feb 2, 2022
a130fde
add communication graph test
anthayes92 Feb 2, 2022
b511c18
Merge branch 'sc-14127-a-user-can-fragment-a-circuit-graph-into' of g…
anthayes92 Feb 2, 2022
b5d5ba6
update docs
anthayes92 Feb 2, 2022
535e5e0
format
anthayes92 Feb 2, 2022
036dea8
add edge case test
anthayes92 Feb 2, 2022
8495fff
update changelog
anthayes92 Feb 3, 2022
cecc6fc
Merge branch 'master' into sc-14127-a-user-can-fragment-a-circuit-gra…
anthayes92 Feb 3, 2022
ed15a26
add graph to tape, add test
anthayes92 Feb 3, 2022
3bc3ae9
fix docstring
anthayes92 Feb 3, 2022
0dd34f1
Merge branch 'sc-14127-a-user-can-fragment-a-circuit-graph-into' of g…
anthayes92 Feb 3, 2022
44fed02
update changelog
anthayes92 Feb 3, 2022
a7c0496
fix docstring
anthayes92 Feb 3, 2022
b5ace5f
update docs
anthayes92 Feb 3, 2022
3036c58
update docstring
anthayes92 Feb 3, 2022
39679e8
Apply suggestions from code review
anthayes92 Feb 4, 2022
69c2891
add fragment configurations method, add test, update docs
anthayes92 Feb 4, 2022
0996e08
fix measurements
anthayes92 Feb 4, 2022
7cc03b2
add suggestions from code review
anthayes92 Feb 4, 2022
817afda
Merge branch 'sc-14127-a-user-can-fragment-a-circuit-graph-into' into…
anthayes92 Feb 4, 2022
ff7509e
format
anthayes92 Feb 4, 2022
1de8674
Merge branch 'master' into sc-13394-a-user-can-convert-a-multigraph-t…
anthayes92 Feb 8, 2022
e1154bc
Apply suggestions from code review
anthayes92 Feb 8, 2022
501c429
add code review suggestions
anthayes92 Feb 8, 2022
fd09982
update unit test
anthayes92 Feb 8, 2022
7492d39
add unit test
anthayes92 Feb 9, 2022
5bcddbe
format
anthayes92 Feb 9, 2022
c6232ab
Merge branch 'master' into sc-13394-a-user-can-convert-a-multigraph-t…
anthayes92 Feb 9, 2022
25bdfe3
format
anthayes92 Feb 9, 2022
74ff942
Merge branch 'master' into sc-13394-a-user-can-convert-a-multigraph-t…
anthayes92 Feb 9, 2022
c190f19
add mid circuit measurements unit test
anthayes92 Feb 10, 2022
694cd51
Merge branch 'sc-13394-a-user-can-convert-a-multigraph-to-a-quantum' …
anthayes92 Feb 10, 2022
0b47303
fix import
anthayes92 Feb 10, 2022
b4ea9a8
add edge cases unit test
anthayes92 Feb 10, 2022
8ae0ae2
Merge branch 'master' into sc-13394-a-user-can-convert-a-multigraph-t…
anthayes92 Feb 10, 2022
2c39ca9
attempt to add partition_pauli_group function
anthayes92 Feb 11, 2022
5efa006
Apply suggestions from code review
anthayes92 Feb 11, 2022
0bd46e2
Merge branch 'master' into sc-13394-a-user-can-convert-a-multigraph-t…
anthayes92 Feb 11, 2022
b717706
remove subscript wire label logic
anthayes92 Feb 11, 2022
8f83a56
add unit test
anthayes92 Feb 12, 2022
922bf6f
add unit test
anthayes92 Feb 14, 2022
6b5e073
prevent original tape from being modified, add unit test
anthayes92 Feb 14, 2022
92808e5
format
anthayes92 Feb 14, 2022
81eb088
Merge branch 'master' into sc-13394-a-user-can-convert-a-multigraph-t…
anthayes92 Feb 14, 2022
2e7ca12
update docs
anthayes92 Feb 14, 2022
50a0785
add logic and test n_qubit=1 case
anthayes92 Feb 14, 2022
11d7440
Merge branch 'sc-13394-a-user-can-convert-a-multigraph-to-a-quantum' …
anthayes92 Feb 15, 2022
453b807
fix pauli grouping and test for n_qubits=1
anthayes92 Feb 16, 2022
8fbea30
tidy code
anthayes92 Feb 16, 2022
aa40cda
add multiqubit measurements unit test
anthayes92 Feb 16, 2022
e571609
Merge branch 'master' into sc-13396-a-user-can-generate-all-configura…
trbromley Feb 16, 2022
c335fea
Tidy merge
trbromley Feb 16, 2022
e48dc3f
Remove unused import
trbromley Feb 16, 2022
6fb65ac
Add to changelog
trbromley Feb 16, 2022
1921452
Add note
trbromley Feb 16, 2022
915f6c6
Typo
trbromley Feb 16, 2022
9e9551a
Remove casting to list
trbromley Feb 16, 2022
66f9d98
Rename
trbromley Feb 16, 2022
2af6282
Remove unused list
trbromley Feb 17, 2022
9819c62
Begin factor out
trbromley Feb 17, 2022
270d32d
Merge branch 'master' into sc-13396-a-user-can-generate-all-configura…
trbromley Feb 17, 2022
6fcdc17
Add measurement processing fn
trbromley Feb 17, 2022
180daf0
Add
trbromley Feb 17, 2022
593e4d7
Merge branch 'master' into sc-13396-a-user-can-generate-all-configura…
trbromley Feb 17, 2022
7907b8f
Fix CI
trbromley Feb 17, 2022
80361c5
add multiqubit state preparation test
anthayes92 Feb 17, 2022
bea35f3
Merge branch 'sc-13396-a-user-can-generate-all-configurations-of' of …
anthayes92 Feb 17, 2022
9b38be5
add compare_measurements() again
anthayes92 Feb 17, 2022
52cfc45
format
anthayes92 Feb 17, 2022
308631e
address codefactor issues, fix typo
anthayes92 Feb 17, 2022
2def3d2
Add test
trbromley Feb 17, 2022
70c88e8
Merge branch 'sc-13396-a-user-can-generate-all-configurations-of' of …
trbromley Feb 17, 2022
cf7c435
Run isort
trbromley Feb 17, 2022
c96a251
Update pennylane/transforms/qcut.py
anthayes92 Feb 17, 2022
efaa052
update docstring
anthayes92 Feb 17, 2022
be99aef
Apply suggestions from code review
anthayes92 Feb 18, 2022
cff1237
add code review suggestions
anthayes92 Feb 18, 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
4 changes: 4 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@
A differentiable tensor contraction function `contract_tensors` has been
added.
[(#2158)](https://github.com/PennyLaneAI/pennylane/pull/2158)

A method has been added that expands a quantum tape over `MeasureNode` and `PrepareNode`
configurations.
[(#2169)](https://github.com/PennyLaneAI/pennylane/pull/2169)

<h3>Improvements</h3>

Expand Down
2 changes: 2 additions & 0 deletions pennylane/transforms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
~transforms.replace_wire_cut_nodes
~transforms.fragment_graph
~transforms.graph_to_tape
~transforms.expand_fragment_tapes
~transforms.contract_tensors

Transforms that act on tapes
Expand Down Expand Up @@ -174,5 +175,6 @@
replace_wire_cut_nodes,
fragment_graph,
graph_to_tape,
expand_fragment_tapes,
contract_tensors,
)
179 changes: 174 additions & 5 deletions pennylane/transforms/qcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@

import copy
import string
from typing import Sequence, Tuple

from networkx import MultiDiGraph, weakly_connected_components
from itertools import product
from typing import List, Sequence, Tuple

import pennylane as qml
from pennylane import apply
from networkx import MultiDiGraph, weakly_connected_components
from pennylane import Hadamard, Identity, PauliX, S, apply, expval
from pennylane.grouping import string_to_pauli_word
from pennylane.measure import MeasurementProcess
from pennylane.operation import Operation, Operator, Tensor
from pennylane.operation import Expectation, Operation, Operator, Tensor
from pennylane.ops.qubit.non_parametric_ops import WireCut
from pennylane.tape import QuantumTape
from pennylane.wires import Wires
Expand Down Expand Up @@ -364,6 +365,174 @@ def graph_to_tape(graph: MultiDiGraph) -> QuantumTape:
return tape


def _get_measurements(
group: Sequence[Operator], measurements: Sequence[MeasurementProcess]
) -> List[MeasurementProcess]:
"""Pairs each observable in ``group`` with the fixed circuit ``measurements``.

Only a single fixed measurement of an expectation value is currently supported.
Copy link
Contributor Author

@anthayes92 anthayes92 Feb 17, 2022

Choose a reason for hiding this comment

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

What is a "fixed" circuit measurement, fixed as opposed to... ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed as in the measurements of the original circuit, rather than the product of Pauli terms

anthayes92 marked this conversation as resolved.
Show resolved Hide resolved

Args:
group (Sequence[Operator]): a collection of qubit-wise commuting observables
anthayes92 marked this conversation as resolved.
Show resolved Hide resolved
measurements (Sequence[MeasurementProcess]): fixed circuit measurements
anthayes92 marked this conversation as resolved.
Show resolved Hide resolved

Returns:
List[MeasurementProcess]: the expectation values of ``g @ obs``, where ``g`` is iterated
over ``group`` and ``obs`` is the observable composing the single fixed circuit measurement
anthayes92 marked this conversation as resolved.
Show resolved Hide resolved
in ``measurements``
"""
n_measurements = len(measurements)
if n_measurements > 1:
raise ValueError(
"The circuit cutting workflow only supports circuits with a single output "
"measurement"
)
if n_measurements == 0:
return [expval(g) for g in group]

measurement = measurements[0]

if measurement.return_type is not Expectation:
raise ValueError(
"The circuit cutting workflow only supports circuits with expectation "
"value measurements"
)

obs = measurement.obs

return [expval(obs @ g) for g in group]
Comment on lines +385 to +404
Copy link
Contributor

Choose a reason for hiding this comment

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

@anthayes92 - this is a simplified version of what we had before. I recall some of the complexity of the prototype implementation came from a potential bug in PennyLane where the order of observables composing a tensor product resulted in different results. I propose that, for now, we keep the simple version above and see if the potential bug surfaces as we add some integration tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the addition and the explanation! This sounds like a sensible approach to me. Is this bug known and was there an issue raised for the bug?

The above seems to work well with the current unit tests 👌

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this bug known and was there an issue raised for the bug?

Trying to remember back - I wasn't sure exactly what was going on, and it could have been a bug in PL or in the prototype implementation. But yes I wouldn't say it's a well defined bug at this stage, and there isn't an issue. I'm sure we'll find it though when we get to the integration tests.



def _prep_zero_state(wire):
Identity(wire)


def _prep_one_state(wire):
PauliX(wire)


def _prep_plus_state(wire):
Hadamard(wire)


def _prep_iplus_state(wire):
Hadamard(wire)
S(wires=wire)


PREPARE_SETTINGS = [_prep_zero_state, _prep_one_state, _prep_plus_state, _prep_iplus_state]


def expand_fragment_tapes(
tape: QuantumTape,
) -> Tuple[List[QuantumTape], List[PrepareNode], List[MeasureNode]]:
"""
Expands a fragment tape into a collection of tapes for each configuration of
anthayes92 marked this conversation as resolved.
Show resolved Hide resolved
:class:`MeasureNode` and :class:`PrepareNode` operations.

.. note::

This function is designed for use as part of the circuit cutting workflow. Check out the
:doc:`transforms </code/qml_transforms>` page for more details.

Args:
tape (QuantumTape): the fragment tape to be expanded.

Returns:
Tuple[List[QuantumTape], List[PrepareNode], List[MeasureNode]]: the
tapes corresponding to each configuration, the preparation nodes and
the measurement nodes.

**Example**

Consider the following circuit, which contains a :class:`~.MeasureNode` and :class:`~.PrepareNode`
operation:

.. code-block:: python

from pennylane.transforms import qcut

with qml.tape.QuantumTape() as tape:
qcut.PrepareNode(wires=0)
qml.RX(0.5, wires=0)
qcut.MeasureNode(wires=0)

We can expand over the measurement and preparation nodes using:

.. code-block:: python

>>> tapes, prep, meas = qml.transforms.expand_fragment_tapes(tape)
>>> for t in tapes:
... print(t.draw())
0: ──I──RX(0.5)──┤ ⟨I⟩ ┤ ⟨Z⟩

0: ──I──RX(0.5)──┤ ⟨X⟩

0: ──I──RX(0.5)──┤ ⟨Y⟩

0: ──X──RX(0.5)──┤ ⟨I⟩ ┤ ⟨Z⟩

0: ──X──RX(0.5)──┤ ⟨X⟩

0: ──X──RX(0.5)──┤ ⟨Y⟩

0: ──H──RX(0.5)──┤ ⟨I⟩ ┤ ⟨Z⟩

0: ──H──RX(0.5)──┤ ⟨X⟩

0: ──H──RX(0.5)──┤ ⟨Y⟩

0: ──H──S──RX(0.5)──┤ ⟨I⟩ ┤ ⟨Z⟩

0: ──H──S──RX(0.5)──┤ ⟨X⟩

0: ──H──S──RX(0.5)──┤ ⟨Y⟩
"""
prepare_nodes = [o for o in tape.operations if isinstance(o, PrepareNode)]
measure_nodes = [o for o in tape.operations if isinstance(o, MeasureNode)]

wire_map = {mn.wires[0]: i for i, mn in enumerate(measure_nodes)}

n_meas = len(measure_nodes)
if n_meas >= 1:
measure_combinations = qml.grouping.partition_pauli_group(len(measure_nodes))
else:
measure_combinations = [[""]]
Comment on lines +497 to +501
Copy link
Contributor

Choose a reason for hiding this comment

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

We should update this when we merge in #2192


tapes = []

for prepare_settings in product(range(len(PREPARE_SETTINGS)), repeat=len(prepare_nodes)):
for measure_group in measure_combinations:
if n_meas >= 1:
group = [
string_to_pauli_word(paulis, wire_map=wire_map) for paulis in measure_group
]
else:
group = []

prepare_mapping = {
n: PREPARE_SETTINGS[s] for n, s in zip(prepare_nodes, prepare_settings)
}

with QuantumTape() as tape_:
for op in tape.operations:
if isinstance(op, PrepareNode):
w = op.wires[0]
prepare_mapping[op](w)
elif not isinstance(op, MeasureNode):
apply(op)

with qml.tape.stop_recording():
measurements = _get_measurements(group, tape.measurements)

for meas in measurements:
apply(meas)

tapes.append(tape_)

return tapes, prepare_nodes, measure_nodes


def _get_symbol(i):
"""Finds the i-th ASCII symbol. Works for lowercase and uppercase letters, allowing i up to
51."""
Expand Down
Loading