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

Add display of expressions to circuit drawers #10869

Merged
merged 45 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e9f5af3
Fix override bug and testing
enavarro51 Aug 5, 2023
bf3dfde
Preliminary changes
enavarro51 Aug 7, 2023
b54ac68
Merge branch 'main' into add_expr_to_drawers
enavarro51 Aug 10, 2023
131c899
Merge main
enavarro51 Aug 15, 2023
f77c0e3
First attempts
enavarro51 Aug 15, 2023
aaeea24
Work on x_index
enavarro51 Aug 15, 2023
9f0aba0
Merge branch 'main' into add_expr_to_drawers
enavarro51 Aug 22, 2023
38502e0
Early testing
enavarro51 Aug 25, 2023
1bc3e9a
Merge branch 'main' into add_expr_to_drawers
enavarro51 Aug 28, 2023
2e43bcf
Cleanup getattr
enavarro51 Aug 28, 2023
0fd86e2
Complete adding exprs
enavarro51 Aug 30, 2023
b4b65eb
Add exprs to mpl
enavarro51 Sep 1, 2023
3713099
Merge branch 'main' into add_expr_to_mpl
enavarro51 Sep 3, 2023
31d6c4b
Work on spacing
enavarro51 Sep 4, 2023
5c495b8
Merge branch 'main' into add_expr_to_mpl
enavarro51 Sep 15, 2023
fc57f7f
Spacing changes
enavarro51 Sep 16, 2023
dad54e6
Finish initial mpl expressions
enavarro51 Sep 17, 2023
5a9a05f
Exprs fully implemented mpl, pre-test
enavarro51 Sep 18, 2023
8b5a06e
Add exprs to text drawer
enavarro51 Sep 18, 2023
d23b7fe
Minor text fixes and update tests for cregbundle False
enavarro51 Sep 20, 2023
3dcb1da
Add tests
enavarro51 Sep 20, 2023
d44bed9
Lint
enavarro51 Sep 20, 2023
149c30e
Merge branch 'main' into add_expr_to_mpl
enavarro51 Sep 20, 2023
de056fc
Merge branch 'main' into add_expr_to_mpl
enavarro51 Sep 20, 2023
82177a9
Fix test
enavarro51 Sep 20, 2023
c3e8f97
Merge branch 'add_expr_to_mpl' of github.com:enavarro51/qiskit-terra …
enavarro51 Sep 20, 2023
79d9a71
Adjust switch test
enavarro51 Sep 20, 2023
7781a35
Lint again
enavarro51 Sep 20, 2023
d25f175
Add expr_len kwarg and minor fixes
enavarro51 Sep 22, 2023
1341954
Update for 10842 changes
enavarro51 Sep 23, 2023
9542c2a
Lint
enavarro51 Sep 23, 2023
b69da5b
Merge branch 'main' into add_expr_to_mpl
enavarro51 Sep 28, 2023
3c06bed
Fix merge conflicts
enavarro51 Sep 29, 2023
302720d
Update refs for minor switch spacing
enavarro51 Sep 29, 2023
225b9d6
Minor cleanup
enavarro51 Sep 29, 2023
94b465e
Only call QASM3Builder once
enavarro51 Oct 4, 2023
92948c5
Remove spurious print
enavarro51 Oct 4, 2023
02da794
Minor documentation tweaks
jakelishman Oct 17, 2023
339bd1f
Merge branch 'main' into add_expr_to_mpl
enavarro51 Oct 17, 2023
123ef47
Merge branch 'add_expr_to_mpl' of github.com:enavarro51/qiskit-terra …
enavarro51 Oct 17, 2023
fa038ca
For mpl, adjust switch/expr spacing, fix 1 qarg flow ops, fix top lev…
enavarro51 Oct 17, 2023
74fd1ee
Add tests for 1 qarg, nested expr, and for range
enavarro51 Oct 17, 2023
e62ec80
Lint
enavarro51 Oct 17, 2023
a3d6aec
Fold on text test
enavarro51 Oct 17, 2023
7890a11
Remove wire_map from get_layered
enavarro51 Oct 17, 2023
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
5 changes: 5 additions & 0 deletions qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1673,6 +1673,7 @@ def draw(
initial_state: bool = False,
cregbundle: bool = None,
wire_order: list = None,
expr_len: int = 30,
):
"""Draw the quantum circuit. Use the output parameter to choose the drawing format:

Expand Down Expand Up @@ -1766,6 +1767,9 @@ def draw(
wire_order (list): Optional. A list of integers used to reorder the display
of the bits. The list must have an entry for every bit with the bits
in the range 0 to (``num_qubits`` + ``num_clbits``).
expr_len (int): Optional. The number of characters to display if an :class:`~.expr.Expr`
is used for the condition in a :class:`.ControlFlowOp`. If this number is exceeded,
the string will be truncated at that number and '...' added to the end.

Returns:
:class:`.TextDrawing` or :class:`matplotlib.figure` or :class:`PIL.Image` or
Expand Down Expand Up @@ -1818,6 +1822,7 @@ def draw(
initial_state=initial_state,
cregbundle=cregbundle,
wire_order=wire_order,
expr_len=expr_len,
)

def size(
Expand Down
17 changes: 8 additions & 9 deletions qiskit/visualization/circuit/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ def _get_layered_instructions(
for node in dag.topological_op_nodes():
nodes.append([node])
else:
nodes = _LayerSpooler(dag, justify, measure_map, wire_map)
nodes = _LayerSpooler(dag, justify, measure_map)

# Optionally remove all idle wires and instructions that are on them and
# on them only.
Expand All @@ -454,7 +454,7 @@ def _sorted_nodes(dag_layer):
return nodes


def _get_gate_span(qubits, node, wire_map):
def _get_gate_span(qubits, node):
"""Get the list of qubits drawing this gate would cover
qiskit-terra #2802
"""
Expand All @@ -470,7 +470,7 @@ def _get_gate_span(qubits, node, wire_map):

# Because of wrapping boxes for mpl control flow ops, this
# type of op must be the only op in the layer
if wire_map is not None and isinstance(node.op, ControlFlowOp):
if isinstance(node.op, ControlFlowOp):
span = qubits
elif node.cargs or getattr(node.op, "condition", None):
span = qubits[min_index : len(qubits)]
Expand All @@ -480,28 +480,27 @@ def _get_gate_span(qubits, node, wire_map):
return span


def _any_crossover(qubits, node, nodes, wire_map):
def _any_crossover(qubits, node, nodes):
"""Return True .IFF. 'node' crosses over any 'nodes'."""
gate_span = _get_gate_span(qubits, node, wire_map)
gate_span = _get_gate_span(qubits, node)
all_indices = []
for check_node in nodes:
if check_node != node:
all_indices += _get_gate_span(qubits, check_node, wire_map)
all_indices += _get_gate_span(qubits, check_node)
return any(i in gate_span for i in all_indices)


class _LayerSpooler(list):
"""Manipulate list of layer dicts for _get_layered_instructions."""

def __init__(self, dag, justification, measure_map, wire_map):
def __init__(self, dag, justification, measure_map):
"""Create spool"""
super().__init__()
self.dag = dag
self.qubits = dag.qubits
self.clbits = dag.clbits
self.justification = justification
self.measure_map = measure_map
self.wire_map = wire_map
self.cregs = [self.dag.cregs[reg] for reg in self.dag.cregs]

if self.justification == "left":
Expand Down Expand Up @@ -534,7 +533,7 @@ def is_found_in(self, node, nodes):

def insertable(self, node, nodes):
"""True .IFF. we can add 'node' to layer 'nodes'"""
return not _any_crossover(self.qubits, node, nodes, self.wire_map)
return not _any_crossover(self.qubits, node, nodes)

def slide_from_left(self, node, index):
"""Insert node into first layer where there is no conflict going l > r"""
Expand Down
17 changes: 17 additions & 0 deletions qiskit/visualization/circuit/circuit_visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def circuit_drawer(
initial_state=False,
cregbundle=None,
wire_order=None,
expr_len=30,
):
"""Draw the quantum circuit. Use the output parameter to choose the drawing format:

Expand Down Expand Up @@ -156,6 +157,9 @@ def circuit_drawer(
wire_order (list): Optional. A list of integers used to reorder the display
of the bits. The list must have an entry for every bit with the bits
in the range 0 to (num_qubits + num_clbits).
expr_len (int): Optional. The number of characters to display if an :class:`~.expr.Expr`
is used for the condition in a :class:`.ControlFlowOp`. If this number is exceeded,
the string will be truncated at that number and '...' added to the end.

Returns:
:class:`TextDrawing` or :class:`matplotlib.figure` or :class:`PIL.Image` or
Expand Down Expand Up @@ -188,6 +192,7 @@ def circuit_drawer(
circuit_drawer(qc, output='mpl', style={'backgroundcolor': '#EEEEEE'})
"""
image = None
expr_len = max(expr_len, 0)
config = user_config.get_config()
# Get default from config file else use text
default_output = "text"
Expand Down Expand Up @@ -257,6 +262,7 @@ def circuit_drawer(
initial_state=initial_state,
cregbundle=cregbundle,
wire_order=complete_wire_order,
expr_len=expr_len,
)
elif output == "latex":
image = _latex_circuit_drawer(
Expand Down Expand Up @@ -304,6 +310,7 @@ def circuit_drawer(
initial_state=initial_state,
cregbundle=cregbundle,
wire_order=complete_wire_order,
expr_len=expr_len,
)
else:
raise VisualizationError(
Expand Down Expand Up @@ -334,6 +341,7 @@ def _text_circuit_drawer(
cregbundle=None,
encoding=None,
wire_order=None,
expr_len=30,
):
"""Draws a circuit using ascii art.

Expand Down Expand Up @@ -363,6 +371,9 @@ def _text_circuit_drawer(
wire_order (list): Optional. A list of integers used to reorder the display
of the bits. The list must have an entry for every bit with the bits
in the range 0 to (num_qubits + num_clbits).
expr_len (int): Optional. The number of characters to display if an :class:`~.expr.Expr`
is used for the condition in a :class:`.ControlFlowOp`. If this number is exceeded,
the string will be truncated at that number and '...' added to the end.

Returns:
TextDrawing: An instance that, when printed, draws the circuit in ascii art.
Expand All @@ -387,6 +398,7 @@ def _text_circuit_drawer(
cregbundle=cregbundle,
encoding=encoding,
with_layout=with_layout,
expr_len=expr_len,
)
text_drawing.plotbarriers = plot_barriers
text_drawing.line_length = fold
Expand Down Expand Up @@ -612,6 +624,7 @@ def _matplotlib_circuit_drawer(
initial_state=False,
cregbundle=None,
wire_order=None,
expr_len=30,
):
"""Draw a quantum circuit based on matplotlib.
If `%matplotlib inline` is invoked in a Jupyter notebook, it visualizes a circuit inline.
Expand Down Expand Up @@ -643,6 +656,9 @@ def _matplotlib_circuit_drawer(
wire_order (list): Optional. A list of integers used to reorder the display
of the bits. The list must have an entry for every bit with the bits
in the range 0 to (num_qubits + num_clbits).
expr_len (int): Optional. The number of characters to display if an :class:`~.expr.Expr`
is used for the condition in a :class:`.ControlFlowOp`. If this number is exceeded,
the string will be truncated at that number and '...' added to the end.

Returns:
matplotlib.figure: a matplotlib figure object for the circuit diagram
Expand Down Expand Up @@ -673,5 +689,6 @@ def _matplotlib_circuit_drawer(
initial_state=initial_state,
cregbundle=cregbundle,
with_layout=with_layout,
expr_len=expr_len,
)
return qcd.draw(filename)
Loading