Skip to content

Commit

Permalink
pull
Browse files Browse the repository at this point in the history
  • Loading branch information
mudit2812 committed Nov 10, 2023
1 parent 4cddf70 commit e6e4c03
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 15 deletions.
13 changes: 1 addition & 12 deletions pennylane/drawer/drawable_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"""

from pennylane.measurements import MidMeasureMP
from pennylane.tape import QuantumScript
from .utils import default_wire_map


Expand Down Expand Up @@ -135,7 +134,7 @@ def drawable_layers(ops, wire_map=None):

# loop over operations
for op in ops:
is_mid_measure = is_conditional = False
is_mid_measure = False

if isinstance(op, MidMeasureMP):
if len(op.wires) > 1:
Expand All @@ -144,19 +143,9 @@ def drawable_layers(ops, wire_map=None):
is_mid_measure = True
measured_wires[op.id] = wire_map[op.wires[0]]

elif op.__class__.__name__ == "Conditional":
is_conditional = True

op_occupied_wires = _get_op_occupied_wires(op, wire_map, cond_measurements)
op_layer = _recursive_find_layer(max_layer, op_occupied_wires, occupied_wires_per_layer)

if is_conditional:
m_layers = [measured_layers[m.id] for m in op.meas_val.measurements]
max_control_layer = max(m_layers)

if op_layer == max_control_layer:
op_layer += 1

# see if need to add new layer
if op_layer > max_layer:
max_layer += 1
Expand Down
7 changes: 5 additions & 2 deletions pennylane/drawer/tape_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import pennylane as qml
from pennylane.measurements import Expectation, Probability, Sample, Variance, State, MidMeasureMP
from pennylane.tape import QuantumScript

from .drawable_layers import drawable_layers
from .utils import convert_wire_order, unwrap_controls
Expand Down Expand Up @@ -58,7 +57,11 @@ def _add_cond_grouping_symbols(op, layer_str, wire_map, bit_map):
layer_str[w] = "─║"

for b in range(n_wires, max_b):
layer_str[b] = "═║" if b - n_wires not in mapped_bits else "═╣"
if b - n_wires in mapped_bits:
layer_str[b] = "═╣"
else:
filler = " " if layer_str[b][-1] == " " else "═"
layer_str[b] = filler + "║"

return layer_str

Expand Down
156 changes: 155 additions & 1 deletion tests/drawer/test_tape_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,39 @@
import pennylane as qml
from pennylane import numpy as np
from pennylane.drawer import tape_text
from pennylane.drawer.tape_text import _add_grouping_symbols, _add_measurement, _add_op
from pennylane.drawer.tape_text import (
_add_grouping_symbols,
_add_cond_grouping_symbols,
_add_mid_measure_grouping_symbols,
_add_measurement,
_add_op,
)
from pennylane.tape import QuantumScript, QuantumTape

default_wire_map = {0: 0, 1: 1, 2: 2, 3: 3}
default_bit_map = {}

default_mid_measure_1 = qml.measurements.MidMeasureMP(0, id="foo")
default_mid_measure_2 = qml.measurements.MidMeasureMP(0, id="bar")
default_measurement_value_1 = qml.measurements.MeasurementValue(
[default_mid_measure_1], lambda v: v
)
default_measurement_value_2 = qml.measurements.MeasurementValue(
[default_mid_measure_2], lambda v: v
)
cond_bit_map_1 = {default_mid_measure_1: 0}
cond_bit_map_2 = {default_mid_measure_1: 0, default_mid_measure_2: 1}


def get_conditional_op(mv, true_fn, *args, **kwargs):
"""Helper to get conditional operator."""

with qml.queuing.AnnotatedQueue() as q:
qml.cond(mv, true_fn)(*args, **kwargs)

return q.queue[0]


with qml.queuing.AnnotatedQueue() as q_tape:
qml.RX(1.23456, wires=0)
qml.RY(2.3456, wires="a")
Expand All @@ -51,6 +78,72 @@ def test_add_grouping_symbols(self, op, out):
"""Test private _add_grouping_symbols function renders as expected."""
assert out == _add_grouping_symbols(op, ["", "", "", ""], default_wire_map, default_bit_map)

@pytest.mark.parametrize(
"op, bit_map, layer_str, out",
[
(default_mid_measure_1, default_bit_map, ["", "", "", ""], ["", "", "", ""]),
(
default_mid_measure_1,
cond_bit_map_1,
["", "", "", "", ""],
["", "─║", "─║", "─║", " ╚"],
),
(
default_mid_measure_2,
cond_bit_map_2,
["─", "─", "─", "─", " ", " "],
["─", "──║", "──║", "──║", " ║", " ╚"],
),
],
)
def test_add_mid_measure_grouping_symbols(self, op, layer_str, bit_map, out):
"""Test private _add_grouping_symbols function renders as expected for MidMeasureMPs."""
assert out == _add_mid_measure_grouping_symbols(op, layer_str, default_wire_map, bit_map)

@pytest.mark.parametrize(
"cond_op, args, kwargs, out, bit_map, mv",
[
(
qml.PauliX,
[],
{"wires": 0},
["─", "─║", "─║", "─║", "═╝"],
cond_bit_map_1,
default_measurement_value_1,
),
(
qml.MultiRZ,
[0.5],
{"wires": [0, 1]},
["─", "─", "─║", "─║", "═╝"],
cond_bit_map_1,
default_measurement_value_1,
),
(
qml.Toffoli,
[],
{"wires": [0, 1, 2]},
["─", "─", "─", "─║", " ║", "═╝"],
cond_bit_map_2,
default_measurement_value_2,
),
(
qml.Toffoli,
[],
{"wires": [0, 1, 2]},
["─", "─", "─", "─║", "═╣", "═╝"],
cond_bit_map_2,
default_measurement_value_1 & default_measurement_value_2,
),
],
)
def test_add_cond_grouping_symbols(self, cond_op, bit_map, mv, args, kwargs, out):
"""Test private _add_grouping_symbols function renders as expected for Conditionals."""
op = get_conditional_op(mv, cond_op, *args, **kwargs)
layer_str = ["─", "─", "─", ""] + [" "] * len(bit_map)

assert out == _add_cond_grouping_symbols(op, layer_str, default_wire_map, bit_map)

@pytest.mark.parametrize(
"op, out",
[
Expand All @@ -59,6 +152,9 @@ def test_add_grouping_symbols(self, op, out):
(qml.var(qml.PauliX(1)), ["", "Var[X]", "", ""]),
(qml.state(), ["State", "State", "State", "State"]),
(qml.sample(), ["Sample", "Sample", "Sample", "Sample"]),
(qml.purity(0), ["purity", "", "", ""]),
(qml.vn_entropy([2, 1]), ["", "╭vnentropy", "╰vnentropy", ""]),
(qml.mutual_info(3, 1), ["", "╭mutualinfo", "│", "╰mutualinfo"]),
],
)
def test_add_measurements(self, op, out):
Expand Down Expand Up @@ -99,6 +195,64 @@ def test_add_op(self, op, out):
"""Test adding the first operation to array of strings"""
assert out == _add_op(op, ["─"] * 4, default_wire_map, default_bit_map, None, None)

@pytest.mark.parametrize(
"op, bit_map, layer_str, out",
[
(default_mid_measure_1, default_bit_map, ["─", "─", "─", "─"], ["─┤↗├", "─", "─", "─"]),
(
default_mid_measure_1,
cond_bit_map_1,
["─", "─", "─", "─", " "],
["─┤↗├", "──║", "──║", "──║", " ╚"],
),
(
default_mid_measure_2,
cond_bit_map_2,
["─", "─", "─", "─", " ", " "],
["─┤↗├", "──║", "──║", "──║", " ║", " ╚"],
),
],
)
def test_add_mid_measure_op(self, op, layer_str, bit_map, out):
"""Test adding the first MidMeasureMP to array of strings"""
assert out == _add_op(op, layer_str, default_wire_map, bit_map, None, None)

@pytest.mark.parametrize(
"cond_op, args, kwargs, out, bit_map, mv",
[
(
qml.MultiRZ,
[0.5],
{"wires": [0, 1]},
["╭MultiRZ", "╰MultiRZ", "─║", "─║", "═╝"],
cond_bit_map_1,
default_measurement_value_1,
),
(
qml.Toffoli,
[],
{"wires": [0, 1, 2]},
["╭●", "├●", "╰X", "─║", "═╝"],
cond_bit_map_1,
default_measurement_value_1,
),
(
qml.PauliX,
[],
{"wires": 1},
["─", "─X", "─║", "─║", " ║", "═╝"],
cond_bit_map_2,
default_measurement_value_2,
),
],
)
def test_add_cond_op(self, cond_op, bit_map, mv, args, kwargs, out):
"""Test adding the first Conditional to array of strings"""
op = get_conditional_op(mv, cond_op, *args, **kwargs)
layer_str = ["─", "─", "─", ""] + [" "] * len(bit_map)

assert out == _add_op(op, layer_str, default_wire_map, bit_map, None, None)

@pytest.mark.parametrize(
"op, out",
[
Expand Down

0 comments on commit e6e4c03

Please sign in to comment.