From 3b97b3745e958f12d25eb7f3ec7a1e80836f8ba8 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Mon, 16 Oct 2023 14:39:14 +0100 Subject: [PATCH] Fix deprecation warning of unscheduled circuits in timeline drawer (#10851) The warning was previously emitted with a `stacklevel` that blamed the caller of `warnings.warn`, which would not be shown to users with the default warning filters. This moves the stack level up to blame the caller of `timeline_drawer`. --- .../passes/scheduling/dynamical_decoupling.py | 18 +++++++++++++-- qiskit/visualization/timeline/core.py | 1 + ...-unscheduled-warning-873f7a24c6b51e2c.yaml | 22 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/fix-timeline-draw-unscheduled-warning-873f7a24c6b51e2c.yaml diff --git a/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py index bc606a0f7161..87bbdbff919c 100644 --- a/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +++ b/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py @@ -53,6 +53,20 @@ class DynamicalDecoupling(TransformationPass): from qiskit.transpiler import PassManager, InstructionDurations from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling from qiskit.visualization import timeline_drawer + + # Because the legacy passes do not propagate the scheduling information correctly, it is + # necessary to run a no-op "re-schedule" before the output circuits can be drawn. + def draw(circuit): + from qiskit import transpile + + scheduled = transpile( + circuit, + optimization_level=0, + instruction_durations=InstructionDurations(), + scheduling_method="alap", + ) + return timeline_drawer(scheduled) + circ = QuantumCircuit(4) circ.h(0) circ.cx(0, 1) @@ -69,7 +83,7 @@ class DynamicalDecoupling(TransformationPass): pm = PassManager([ALAPSchedule(durations), DynamicalDecoupling(durations, dd_sequence)]) circ_dd = pm.run(circ) - timeline_drawer(circ_dd) + draw(circ_dd) # Uhrig sequence on qubit 0 n = 8 @@ -87,7 +101,7 @@ def uhrig_pulse_location(k): ] ) circ_dd = pm.run(circ) - timeline_drawer(circ_dd) + draw(circ_dd) """ @deprecate_func( diff --git a/qiskit/visualization/timeline/core.py b/qiskit/visualization/timeline/core.py index 35841fe16512..d98527937ff9 100644 --- a/qiskit/visualization/timeline/core.py +++ b/qiskit/visualization/timeline/core.py @@ -159,6 +159,7 @@ def load_program(self, program: circuit.QuantumCircuit): "This circuit should be transpiled with scheduler though it consists of " "instructions with explicit durations.", DeprecationWarning, + stacklevel=3, ) try: diff --git a/releasenotes/notes/fix-timeline-draw-unscheduled-warning-873f7a24c6b51e2c.yaml b/releasenotes/notes/fix-timeline-draw-unscheduled-warning-873f7a24c6b51e2c.yaml new file mode 100644 index 000000000000..e93e62c963a3 --- /dev/null +++ b/releasenotes/notes/fix-timeline-draw-unscheduled-warning-873f7a24c6b51e2c.yaml @@ -0,0 +1,22 @@ +--- +deprecations: + - | + Passing a circuit to :func:`qiskit.visualization.timeline_drawer` that does not have scheduled + node start-time information is deprecated. Only circuits that have gone through one of the + scheduling analysis passes (for example :class:`.ALAPScheduleAnalysis` or + :class:`.ASAPScheduleAnalysis`) can be visualised. If you have used one of the old-style + scheduling passes (for example :class:`.ALAPSchedule` or :class:`.ASAPSchedule`), you can + propagate the scheduling information by running:: + + from qiskit import transpile + from qiskit.transpiler import InstructionDurations + + scheduled = transpile( + my_old_style_circuit, + optimization_level=0, + scheduling_method="alap", + instruction_durations=InstructionDurations(), + ) + + This behaviour was previously intended to be deprecated in Qiskit 0.37, but due to a bug in the + warning, it was not displayed to users until now. The behaviour will be removed in Qiskit 1.0.