From 33704ea61f6a3fa60612cbe4463894d2859fe9ec Mon Sep 17 00:00:00 2001 From: Diego Emilio Serrano <65074936+diemilio@users.noreply.github.com> Date: Wed, 19 Apr 2023 20:48:44 -0400 Subject: [PATCH] Fix circuit drawer for instructions with circuit parameters (#9942) * fix: modify get_param_str to prevent circuit drawer from displaying params of type QuantumCircuit * fix lint errors * test: add circuit drawer test for instructions with parameters of type QuantumCircuit * test: add circuit drawer tests for no parameters and params of type ndarray * fix lint errors * remove variable to fix lint error * add reno * update releasenotes/notes/fix-circuit-drawer-for-qc-params --- qiskit/visualization/circuit/_utils.py | 12 ++--- ...drawer-for-qc-params-e78c67310ae43ccf.yaml | 5 ++ .../visualization/test_circuit_text_drawer.py | 50 ++++++++++++++++++- 3 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/fix-circuit-drawer-for-qc-params-e78c67310ae43ccf.yaml diff --git a/qiskit/visualization/circuit/_utils.py b/qiskit/visualization/circuit/_utils.py index 5242e0c48d46..4117b0e76177 100644 --- a/qiskit/visualization/circuit/_utils.py +++ b/qiskit/visualization/circuit/_utils.py @@ -25,10 +25,9 @@ Gate, Instruction, Measure, - ControlFlowOp, ) from qiskit.circuit.library import PauliEvolutionGate -from qiskit.circuit import ClassicalRegister +from qiskit.circuit import ClassicalRegister, QuantumCircuit from qiskit.circuit.tools import pi_check from qiskit.converters import circuit_to_dag from qiskit.utils import optionals as _optionals @@ -119,10 +118,11 @@ def get_gate_ctrl_text(op, drawer, style=None, calibrations=None): def get_param_str(op, drawer, ndigits=3): """Get the params as a string to add to the gate text display""" - if not hasattr(op, "params") or any(isinstance(param, np.ndarray) for param in op.params): - return "" - - if isinstance(op, ControlFlowOp): + if ( + not hasattr(op, "params") + or any(isinstance(param, np.ndarray) for param in op.params) + or any(isinstance(param, QuantumCircuit) for param in op.params) + ): return "" if isinstance(op, Delay): diff --git a/releasenotes/notes/fix-circuit-drawer-for-qc-params-e78c67310ae43ccf.yaml b/releasenotes/notes/fix-circuit-drawer-for-qc-params-e78c67310ae43ccf.yaml new file mode 100644 index 000000000000..778c42041643 --- /dev/null +++ b/releasenotes/notes/fix-circuit-drawer-for-qc-params-e78c67310ae43ccf.yaml @@ -0,0 +1,5 @@ +fixes: + - | + Fixes the circuit drawer from displaying parameters when they are of type :class:`.QuantumCircuit` + since this resulted in an illegible drawing. + \ No newline at end of file diff --git a/test/python/visualization/test_circuit_text_drawer.py b/test/python/visualization/test_circuit_text_drawer.py index 9a44a7ed2cd6..e5d4f543734e 100644 --- a/test/python/visualization/test_circuit_text_drawer.py +++ b/test/python/visualization/test_circuit_text_drawer.py @@ -22,7 +22,7 @@ import numpy from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, transpile -from qiskit.circuit import Gate, Parameter, Qubit, Clbit +from qiskit.circuit import Gate, Parameter, Qubit, Clbit, Instruction from qiskit.quantum_info.operators import SuperOp from qiskit.quantum_info.random import random_unitary from qiskit.test import QiskitTestCase @@ -1839,6 +1839,21 @@ def test_control_gate_label_with_cond_2_low_cregbundle(self): class TestTextDrawerParams(QiskitTestCase): """Test drawing parameters.""" + def test_text_no_parameters(self): + """Test drawing with no parameters""" + expected = "\n".join( + [ + " ┌───┐", + "q: |0>┤ X ├", + " └───┘", + ] + ) + + qr = QuantumRegister(1, "q") + circuit = QuantumCircuit(qr) + circuit.x(0) + self.assertEqual(str(_text_circuit_drawer(circuit)), expected) + def test_text_parameters_mix(self): """cu3 drawing with parameters""" expected = "\n".join( @@ -1904,6 +1919,39 @@ def test_text_utf8(self): circuit.u(0, phi, lam, 0) self.assertEqual(circuit.draw(output="text").single_string(), expected) + def test_text_ndarray_parameters(self): + """Test that if params are type ndarray, params are not displayed.""" + # fmt: off + expected = "\n".join([" ┌─────────┐", + "q: |0>┤ Unitary ├", + " └─────────┘"]) + # fmt: on + qr = QuantumRegister(1, "q") + circuit = QuantumCircuit(qr) + circuit.unitary(numpy.array([[0, 1], [1, 0]]), 0) + self.assertEqual(str(_text_circuit_drawer(circuit)), expected) + + def test_text_qc_parameters(self): + """Test that if params are type QuantumCircuit, params are not displayed.""" + expected = "\n".join( + [ + " ┌───────┐", + "q_0: |0>┤0 ├", + " │ name │", + "q_1: |0>┤1 ├", + " └───────┘", + ] + ) + + my_qc_param = QuantumCircuit(2) + my_qc_param.h(0) + my_qc_param.cx(0, 1) + inst = Instruction("name", 2, 0, [my_qc_param]) + qr = QuantumRegister(2, "q") + circuit = QuantumCircuit(qr) + circuit.append(inst, [0, 1]) + self.assertEqual(str(_text_circuit_drawer(circuit)), expected) + class TestTextDrawerVerticalCompressionLow(QiskitTestCase): """Test vertical_compression='low'"""