From 22522ab59f0ecf30d1e6c5d9dee8dd723fcaee6c Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 17 Oct 2024 13:51:51 +0200 Subject: [PATCH 01/12] Deprecate instruction_durations, timing_constraints and backend_properties --- qiskit/compiler/transpiler.py | 80 +++++++++++++------ .../generate_preset_pass_manager.py | 27 +++++++ test/python/compiler/test_transpiler.py | 18 +++-- 3 files changed, 93 insertions(+), 32 deletions(-) diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index 5e2dcf8a1560..1af3389c4800 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -32,12 +32,39 @@ from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit.transpiler.target import Target +from qiskit.utils import deprecate_arg logger = logging.getLogger(__name__) _CircuitT = TypeVar("_CircuitT", bound=Union[QuantumCircuit, List[QuantumCircuit]]) +@deprecate_arg( + name="instruction_durations", + since="1.3", + package_name="Qiskit", + removal_timeline="in Qiskit 2.0", + additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " + "with defined instruction duration with " + "`Target.from_configuration(..., instruction_durations=...)`", +) +@deprecate_arg( + name="timing_constraints", + since="1.3", + package_name="Qiskit", + removal_timeline="in Qiskit 2.0", + additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " + "with defined timing constraints with " + "`Target.from_configuration(..., timing_constraints=...)`", +) +@deprecate_arg( + name="backend_properties", + since="1.3", + package_name="Qiskit", + removal_timeline="in Qiskit 2.0", + additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " + "with defined properties with Target.from_configuration(..., backend_properties=...)", +) def transpile( # pylint: disable=too-many-return-statements circuits: _CircuitT, backend: Optional[Backend] = None, @@ -365,31 +392,34 @@ def callback_func(**kwargs): # Edge cases require using the old model (loose constraints) instead of building a target, # but we don't populate the passmanager config with loose constraints unless it's one of # the known edge cases to control the execution path. - pm = generate_preset_pass_manager( - optimization_level, - target=target, - backend=backend, - basis_gates=basis_gates, - coupling_map=coupling_map, - instruction_durations=instruction_durations, - backend_properties=backend_properties, - timing_constraints=timing_constraints, - inst_map=inst_map, - initial_layout=initial_layout, - layout_method=layout_method, - routing_method=routing_method, - translation_method=translation_method, - scheduling_method=scheduling_method, - approximation_degree=approximation_degree, - seed_transpiler=seed_transpiler, - unitary_synthesis_method=unitary_synthesis_method, - unitary_synthesis_plugin_config=unitary_synthesis_plugin_config, - hls_config=hls_config, - init_method=init_method, - optimization_method=optimization_method, - dt=dt, - qubits_initially_zero=qubits_initially_zero, - ) + with warnings.catch_warnings(): + warnings.simplefilter(action="ignore", category=DeprecationWarning) + # Filter instruction_durations, timing_constraints and backend_properties deprecation + pm = generate_preset_pass_manager( + optimization_level, + target=target, + backend=backend, + basis_gates=basis_gates, + coupling_map=coupling_map, + instruction_durations=instruction_durations, + backend_properties=backend_properties, + timing_constraints=timing_constraints, + inst_map=inst_map, + initial_layout=initial_layout, + layout_method=layout_method, + routing_method=routing_method, + translation_method=translation_method, + scheduling_method=scheduling_method, + approximation_degree=approximation_degree, + seed_transpiler=seed_transpiler, + unitary_synthesis_method=unitary_synthesis_method, + unitary_synthesis_plugin_config=unitary_synthesis_plugin_config, + hls_config=hls_config, + init_method=init_method, + optimization_method=optimization_method, + dt=dt, + qubits_initially_zero=qubits_initially_zero, + ) out_circuits = pm.run(circuits, callback=callback, num_processes=num_processes) diff --git a/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py b/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py index 830618845352..87f66811098d 100644 --- a/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +++ b/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py @@ -29,6 +29,7 @@ from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.target import Target, target_to_backend_properties from qiskit.transpiler.timing_constraints import TimingConstraints +from qiskit.utils import deprecate_arg from .level0 import level_0_pass_manager from .level1 import level_1_pass_manager @@ -36,6 +37,32 @@ from .level3 import level_3_pass_manager +@deprecate_arg( + name="instruction_durations", + since="1.3", + package_name="Qiskit", + removal_timeline="in Qiskit 2.0", + additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " + "with defined instruction duration with " + "`Target.from_configuration(..., instruction_durations=...)`", +) +@deprecate_arg( + name="timing_constraints", + since="1.3", + package_name="Qiskit", + removal_timeline="in Qiskit 2.0", + additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " + "with defined timing constraints with " + "`Target.from_configuration(..., timing_constraints=...)`", +) +@deprecate_arg( + name="backend_properties", + since="1.3", + package_name="Qiskit", + removal_timeline="in Qiskit 2.0", + additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " + "with defined properties with Target.from_configuration(..., backend_properties=...)", +) def generate_preset_pass_manager( optimization_level=2, backend=None, diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index a90c2bfee7d2..f798866ae974 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -1715,13 +1715,17 @@ def test_backend_props_constraints(self): ) self.assertEqual(result._layout.initial_layout._p2v, vf2_layout) - result = transpile( - qc, - backend=backend_v2, - backend_properties=custom_backend_properties, - optimization_level=2, - seed_transpiler=42, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + result = transpile( + qc, + backend=backend_v2, + backend_properties=custom_backend_properties, + optimization_level=2, + seed_transpiler=42, + ) self.assertEqual(result._layout.initial_layout._p2v, vf2_layout) From 6e8f506167ddb3d818f7abc6eb86739c4f6a1e45 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Fri, 18 Oct 2024 10:04:45 +0200 Subject: [PATCH 02/12] test_scheduling_instruction_constraints --- test/python/compiler/test_transpiler.py | 37 ++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index f798866ae974..a6d3e9519c73 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -1592,7 +1592,7 @@ def test_scheduling_timing_constraints(self): timing_constraints=timing_constraints, ) - def test_scheduling_instruction_constraints(self): + def test_scheduling_instruction_constraints_backend(self): """Test that scheduling-related loose transpile constraints work with both BackendV1 and BackendV2.""" @@ -1620,14 +1620,43 @@ def test_scheduling_instruction_constraints(self): ) self.assertEqual(scheduled.duration, 1500) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + scheduled = transpile( + qc, + backend=backend_v2, + scheduling_method="alap", + instruction_durations=durations, + layout_method="trivial", + ) + self.assertEqual(scheduled.duration, 1500) + + def test_scheduling_instruction_constraints(self): + """Test that scheduling-related loose transpile constraints work with target.""" + target = GenericBackendV2( + 2, + calibrate_instructions=True, + coupling_map=[[0, 1]], + basis_gates=["cx", "h"], + seed=42, + ).target + qc = QuantumCircuit(2) + qc.h(0) + qc.delay(0.000001, 1, "s") + qc.cx(0, 1) + + # update cx to 2 seconds + target.update_instruction_properties("cx", (0, 1), InstructionProperties(0.000001)) + scheduled = transpile( qc, - backend=backend_v2, + target=target, scheduling_method="alap", - instruction_durations=durations, layout_method="trivial", ) - self.assertEqual(scheduled.duration, 1500) + self.assertEqual(scheduled.duration, 9010) def test_scheduling_dt_constraints(self): """Test that scheduling-related loose transpile constraints From 78ae60df86fbe3fa5e6f36841c0eeb037019887b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= Date: Fri, 18 Oct 2024 14:53:00 +0200 Subject: [PATCH 03/12] Fix test/python/transpiler/test_preset_passmanagers.py --- .../transpiler/test_preset_passmanagers.py | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py index b762d84032bb..8f84bad9efa4 100644 --- a/test/python/transpiler/test_preset_passmanagers.py +++ b/test/python/transpiler/test_preset_passmanagers.py @@ -1316,15 +1316,19 @@ def test_default_optimization_level_target_first_pos_arg(self): def test_with_no_backend(self, optimization_level): """Test a passmanager is constructed with no backend and optimization level.""" target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) - pm = generate_preset_pass_manager( - optimization_level, - coupling_map=target.coupling_map, - basis_gates=target.operation_names, - inst_map=target.instruction_schedule_map, - instruction_durations=target.instruction_durations, - timing_constraints=target.target.timing_constraints(), - target=target.target, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + pm = generate_preset_pass_manager( + optimization_level, + coupling_map=target.coupling_map, + basis_gates=target.operation_names, + inst_map=target.instruction_schedule_map, + instruction_durations=target.instruction_durations, + timing_constraints=target.target.timing_constraints(), + target=target.target, + ) self.assertIsInstance(pm, PassManager) @data(0, 1, 2, 3) From 42ad6d422f7112d27daab67bfbf411b9b40769c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= Date: Fri, 18 Oct 2024 14:57:05 +0200 Subject: [PATCH 04/12] Fix test/python/visualization/timeline/test_core.py --- .../visualization/timeline/test_core.py | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/test/python/visualization/timeline/test_core.py b/test/python/visualization/timeline/test_core.py index 16a5457e8d42..895aa48d954e 100644 --- a/test/python/visualization/timeline/test_core.py +++ b/test/python/visualization/timeline/test_core.py @@ -30,13 +30,17 @@ def setUp(self): circ.cx(0, 2) circ.cx(1, 3) - self.circ = transpile( - circ, - scheduling_method="alap", - basis_gates=["h", "cx"], - instruction_durations=[("h", 0, 200), ("cx", [0, 2], 1000), ("cx", [1, 3], 1000)], - optimization_level=0, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + self.circ = transpile( + circ, + scheduling_method="alap", + basis_gates=["h", "cx"], + instruction_durations=[("h", 0, 200), ("cx", [0, 2], 1000), ("cx", [1, 3], 1000)], + optimization_level=0, + ) def test_time_range(self): """Test calculating time range.""" @@ -153,13 +157,17 @@ def test_multi_measurement_with_clbit_not_shown(self): circ.measure(0, 0) circ.measure(1, 1) - circ = transpile( - circ, - scheduling_method="alap", - basis_gates=[], - instruction_durations=[("measure", 0, 2000), ("measure", 1, 2000)], - optimization_level=0, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + circ = transpile( + circ, + scheduling_method="alap", + basis_gates=[], + instruction_durations=[("measure", 0, 2000), ("measure", 1, 2000)], + optimization_level=0, + ) canvas = core.DrawerCanvas(stylesheet=self.style) canvas.formatter.update({"control.show_clbits": False}) @@ -184,13 +192,17 @@ def test_multi_measurement_with_clbit_shown(self): circ.measure(0, 0) circ.measure(1, 1) - circ = transpile( - circ, - scheduling_method="alap", - basis_gates=[], - instruction_durations=[("measure", 0, 2000), ("measure", 1, 2000)], - optimization_level=0, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + circ = transpile( + circ, + scheduling_method="alap", + basis_gates=[], + instruction_durations=[("measure", 0, 2000), ("measure", 1, 2000)], + optimization_level=0, + ) canvas = core.DrawerCanvas(stylesheet=self.style) canvas.formatter.update({"control.show_clbits": True}) From a5a07fa7e1a09492d4dba179b417433d8d9106c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= Date: Fri, 18 Oct 2024 15:10:52 +0200 Subject: [PATCH 05/12] Fix test/python/compiler/test_transpiler.py --- test/python/compiler/test_transpiler.py | 56 ++++++++++++++----------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index a6d3e9519c73..3d66370ff275 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -1508,14 +1508,18 @@ def test_circuit_with_delay(self, optimization_level): qc.delay(500, 1) qc.cx(0, 1) - out = transpile( - qc, - scheduling_method="alap", - basis_gates=["h", "cx"], - instruction_durations=[("h", 0, 200), ("cx", [0, 1], 700)], - optimization_level=optimization_level, - seed_transpiler=42, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + out = transpile( + qc, + scheduling_method="alap", + basis_gates=["h", "cx"], + instruction_durations=[("h", 0, 200), ("cx", [0, 1], 700)], + optimization_level=optimization_level, + seed_transpiler=42, + ) self.assertEqual(out.duration, 1200) @@ -3747,14 +3751,19 @@ def test_triple_circuit_invalid_layout(self, routing_method): qc.cy(20, 28) qc.cy(20, 29) qc.measure_all() + with self.assertRaises(TranspilerError): - transpile( - qc, - self.backend, - layout_method="trivial", - routing_method=routing_method, - seed_transpiler=42, - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + transpile( + qc, + self.backend, + layout_method="trivial", + routing_method=routing_method, + seed_transpiler=42, + ) @data("stochastic") def test_triple_circuit_invalid_layout_stochastic(self, routing_method): @@ -3792,15 +3801,14 @@ def test_triple_circuit_invalid_layout_stochastic(self, routing_method): qc.cy(20, 28) qc.cy(20, 29) qc.measure_all() - with self.assertWarns(DeprecationWarning): - with self.assertRaises(TranspilerError): - transpile( - qc, - self.backend, - layout_method="trivial", - routing_method=routing_method, - seed_transpiler=42, - ) + with self.assertRaises(TranspilerError): + transpile( + qc, + self.backend, + layout_method="trivial", + routing_method=routing_method, + seed_transpiler=42, + ) # Lookahead swap skipped for performance reasons, stochastic moved to new test due to deprecation @data("sabre", "basic") From bd4965070ffa78296d064d24b1dc2beebf831c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= Date: Fri, 18 Oct 2024 15:14:35 +0200 Subject: [PATCH 06/12] Fix test/python/circuit/test_scheduled_circuit.py --- test/python/circuit/test_scheduled_circuit.py | 62 ++++++++++++------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/test/python/circuit/test_scheduled_circuit.py b/test/python/circuit/test_scheduled_circuit.py index ce5cd8213105..65a4e1e88323 100644 --- a/test/python/circuit/test_scheduled_circuit.py +++ b/test/python/circuit/test_scheduled_circuit.py @@ -193,12 +193,16 @@ def test_transpile_delay_circuit_without_backend(self): qc.h(0) qc.delay(500, 1) qc.cx(0, 1) - scheduled = transpile( - qc, - scheduling_method="alap", - basis_gates=["h", "cx"], - instruction_durations=[("h", 0, 200), ("cx", [0, 1], 700)], - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + scheduled = transpile( + qc, + scheduling_method="alap", + basis_gates=["h", "cx"], + instruction_durations=[("h", 0, 200), ("cx", [0, 1], 700)], + ) self.assertEqual(scheduled.duration, 1200) def test_transpile_circuit_with_custom_instruction(self): @@ -209,9 +213,13 @@ def test_transpile_circuit_with_custom_instruction(self): qc = QuantumCircuit(2) qc.delay(500, 1) qc.append(bell.to_instruction(), [0, 1]) - scheduled = transpile( - qc, scheduling_method="alap", instruction_durations=[("bell", [0, 1], 1000)] - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + scheduled = transpile( + qc, scheduling_method="alap", instruction_durations=[("bell", [0, 1], 1000)] + ) self.assertEqual(scheduled.duration, 1500) def test_transpile_delay_circuit_with_dt_but_without_scheduling_method(self): @@ -262,21 +270,29 @@ def test_default_units_for_my_own_duration_users(self): qc.h(0) qc.delay(500, 1) qc.cx(0, 1) - # accept None for qubits - scheduled = transpile( - qc, - basis_gates=["h", "cx", "delay"], - scheduling_method="alap", - instruction_durations=[("h", 0, 200), ("cx", None, 900)], - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + # accept None for qubits + scheduled = transpile( + qc, + basis_gates=["h", "cx", "delay"], + scheduling_method="alap", + instruction_durations=[("h", 0, 200), ("cx", None, 900)], + ) self.assertEqual(scheduled.duration, 1400) - # prioritize specified qubits over None - scheduled = transpile( - qc, - basis_gates=["h", "cx", "delay"], - scheduling_method="alap", - instruction_durations=[("h", 0, 200), ("cx", None, 900), ("cx", [0, 1], 800)], - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + # prioritize specified qubits over None + scheduled = transpile( + qc, + basis_gates=["h", "cx", "delay"], + scheduling_method="alap", + instruction_durations=[("h", 0, 200), ("cx", None, 900), ("cx", [0, 1], 800)], + ) self.assertEqual(scheduled.duration, 1300) def test_unit_seconds_when_using_backend_durations(self): From d721dc606ecc4951eeab8fe139729c3692abe60c Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 21 Oct 2024 10:22:36 +0200 Subject: [PATCH 07/12] single line --- test/python/compiler/test_transpiler.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index a6d3e9519c73..accc6d3a8db7 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -1686,8 +1686,7 @@ def test_scheduling_dt_constraints(self): self.assertEqual(scheduled.duration, original_duration * 2) def test_backend_props_constraints(self): - """Test that loose transpile constraints - work with both BackendV1 and BackendV2.""" + """Test that loose transpile constraints work with both BackendV1 and BackendV2.""" with self.assertWarns(DeprecationWarning): backend_v1 = Fake20QV1() From 3e4011edea3a20f4f6d690d93a8827e12fa7723d Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 21 Oct 2024 10:50:32 +0200 Subject: [PATCH 08/12] test.python.circuit.test_scheduled_circuit.TestScheduledCircuit --- test/python/circuit/test_scheduled_circuit.py | 89 ++++++++++++++++--- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/test/python/circuit/test_scheduled_circuit.py b/test/python/circuit/test_scheduled_circuit.py index 65a4e1e88323..af0f2ce7a5d5 100644 --- a/test/python/circuit/test_scheduled_circuit.py +++ b/test/python/circuit/test_scheduled_circuit.py @@ -22,6 +22,7 @@ from qiskit.providers.fake_provider import Fake27QPulseV1, GenericBackendV2 from qiskit.providers.basic_provider import BasicSimulator from qiskit.scheduler import ScheduleConfig +from qiskit.transpiler import InstructionProperties from qiskit.transpiler.exceptions import TranspilerError from qiskit.transpiler.instruction_durations import InstructionDurations from test import QiskitTestCase # pylint: disable=wrong-import-order @@ -328,19 +329,23 @@ def test_unit_seconds_when_using_backend_durations(self): ) self.assertEqual(scheduled.duration, 1500) - def test_per_qubit_durations(self): - """See: https://github.com/Qiskit/qiskit-terra/issues/5109""" + def test_per_qubit_durations_loose_constrain(self): + """See Qiskit/5109 and Qiskit/13306""" qc = QuantumCircuit(3) qc.h(0) qc.delay(500, 1) qc.cx(0, 1) qc.h(1) - sc = transpile( - qc, - scheduling_method="alap", - basis_gates=["h", "cx"], - instruction_durations=[("h", None, 200), ("cx", [0, 1], 700)], - ) + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + sc = transpile( + qc, + scheduling_method="alap", + basis_gates=["h", "cx"], + instruction_durations=[("h", None, 200), ("cx", [0, 1], 700)], + ) self.assertEqual(sc.qubit_start_time(0), 300) self.assertEqual(sc.qubit_stop_time(0), 1200) self.assertEqual(sc.qubit_start_time(1), 500) @@ -351,12 +356,21 @@ def test_per_qubit_durations(self): self.assertEqual(sc.qubit_stop_time(0, 1), 1400) qc.measure_all() - sc = transpile( - qc, - scheduling_method="alap", - basis_gates=["h", "cx", "measure"], - instruction_durations=[("h", None, 200), ("cx", [0, 1], 700), ("measure", None, 1000)], - ) + + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="The `target` parameter should be used instead", + ): + sc = transpile( + qc, + scheduling_method="alap", + basis_gates=["h", "cx", "measure"], + instruction_durations=[ + ("h", None, 200), + ("cx", [0, 1], 700), + ("measure", None, 1000), + ], + ) q = sc.qubits self.assertEqual(sc.qubit_start_time(q[0]), 300) self.assertEqual(sc.qubit_stop_time(q[0]), 2400) @@ -367,6 +381,53 @@ def test_per_qubit_durations(self): self.assertEqual(sc.qubit_start_time(*q), 300) self.assertEqual(sc.qubit_stop_time(*q), 2400) + def test_per_qubit_durations(self): + """Test target with custom instruction_durations""" + target = GenericBackendV2( + 3, + calibrate_instructions=True, + coupling_map=[[0, 1], [1, 2]], + basis_gates=["cx", "h"], + seed=42, + ).target + target.update_instruction_properties("cx", (0, 1), InstructionProperties(0.00001)) + target.update_instruction_properties("cx", (1, 2), InstructionProperties(0.00001)) + target.update_instruction_properties("h", (0,), InstructionProperties(0.000002)) + target.update_instruction_properties("h", (1,), InstructionProperties(0.000002)) + target.update_instruction_properties("h", (2,), InstructionProperties(0.000002)) + + qc = QuantumCircuit(3) + qc.h(0) + qc.delay(500, 1) + qc.cx(0, 1) + qc.h(1) + + sc = transpile(qc, scheduling_method="alap", target=target) + self.assertEqual(sc.qubit_start_time(0), 500) + self.assertEqual(sc.qubit_stop_time(0), 54554) + self.assertEqual(sc.qubit_start_time(1), 9509) + self.assertEqual(sc.qubit_stop_time(1), 63563) + self.assertEqual(sc.qubit_start_time(2), 0) + self.assertEqual(sc.qubit_stop_time(2), 0) + self.assertEqual(sc.qubit_start_time(0, 1), 500) + self.assertEqual(sc.qubit_stop_time(0, 1), 63563) + + qc.measure_all() + + target.update_instruction_properties("measure", (0,), InstructionProperties(0.0001)) + target.update_instruction_properties("measure", (1,), InstructionProperties(0.0001)) + + sc = transpile(qc, scheduling_method="alap", target=target) + q = sc.qubits + self.assertEqual(sc.qubit_start_time(q[0]), 500) + self.assertEqual(sc.qubit_stop_time(q[0]), 514013) + self.assertEqual(sc.qubit_start_time(q[1]), 9509) + self.assertEqual(sc.qubit_stop_time(q[1]), 514013) + self.assertEqual(sc.qubit_start_time(q[2]), 63563) + self.assertEqual(sc.qubit_stop_time(q[2]), 514013) + self.assertEqual(sc.qubit_start_time(*q), 500) + self.assertEqual(sc.qubit_stop_time(*q), 514013) + def test_convert_duration_to_dt(self): """Test that circuit duration unit conversion is applied only when necessary. Tests fix for bug reported in PR #11782.""" From 0f362089309ede9da2496ce708ca1e25796ac25d Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 21 Oct 2024 15:33:09 +0200 Subject: [PATCH 09/12] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- qiskit/compiler/transpiler.py | 2 +- .../preset_passmanagers/generate_preset_pass_manager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index 1af3389c4800..2a3e6b88ee0c 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -45,7 +45,7 @@ package_name="Qiskit", removal_timeline="in Qiskit 2.0", additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " - "with defined instruction duration with " + "with defined instruction durations with " "`Target.from_configuration(..., instruction_durations=...)`", ) @deprecate_arg( diff --git a/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py b/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py index 87f66811098d..3f5933396e91 100644 --- a/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +++ b/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py @@ -43,7 +43,7 @@ package_name="Qiskit", removal_timeline="in Qiskit 2.0", additional_msg="The `target` parameter should be used instead. You can build a `Target` instance " - "with defined instruction duration with " + "with defined instruction durations with " "`Target.from_configuration(..., instruction_durations=...)`", ) @deprecate_arg( From df08ca2f4def0e6fe3deecffb7701173ce1c2c58 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Wed, 23 Oct 2024 14:26:22 +0200 Subject: [PATCH 10/12] reno --- .../notes/fixes_13306-f9883a733491a72f.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 releasenotes/notes/fixes_13306-f9883a733491a72f.yaml diff --git a/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml b/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml new file mode 100644 index 000000000000..d9e3fadceb08 --- /dev/null +++ b/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml @@ -0,0 +1,13 @@ +--- +deprecations_transpiler: + - | + The following :func:`.transpile` and :func:`.generate_preset_pass_manager` arguments are deprecated in favor of + defining a custom :class:`.Target`: ``instruction_durations``, ``timing_constraints``, and ``backend_properties``. + These arguments can be used to build a target with :meth:`.Target.from_configuration`:: + Target.from_configuration( + ... + backend_properties = backend_properties, + instruction_durations = instruction_durations, + timing_constraints = timing_constraints + ) + From a27577e3954fe13fd111b71fe4dd190c85f76bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= <57907331+ElePT@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:07:15 +0100 Subject: [PATCH 11/12] Update reno example --- releasenotes/notes/fixes_13306-f9883a733491a72f.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml b/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml index d9e3fadceb08..e46b971b6462 100644 --- a/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml +++ b/releasenotes/notes/fixes_13306-f9883a733491a72f.yaml @@ -4,6 +4,7 @@ deprecations_transpiler: The following :func:`.transpile` and :func:`.generate_preset_pass_manager` arguments are deprecated in favor of defining a custom :class:`.Target`: ``instruction_durations``, ``timing_constraints``, and ``backend_properties``. These arguments can be used to build a target with :meth:`.Target.from_configuration`:: + Target.from_configuration( ... backend_properties = backend_properties, From d565922f2d38a4fb95211d860bef0db81d1717ab Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Wed, 30 Oct 2024 14:06:40 +0100 Subject: [PATCH 12/12] tests --- test/python/circuit/test_scheduled_circuit.py | 18 +++++++++++------- test/python/compiler/test_transpiler.py | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/test/python/circuit/test_scheduled_circuit.py b/test/python/circuit/test_scheduled_circuit.py index 98d6cb7c713f..7ebed694a8db 100644 --- a/test/python/circuit/test_scheduled_circuit.py +++ b/test/python/circuit/test_scheduled_circuit.py @@ -384,13 +384,17 @@ def test_per_qubit_durations_loose_constrain(self): def test_per_qubit_durations(self): """Test target with custom instruction_durations""" - target = GenericBackendV2( - 3, - calibrate_instructions=True, - coupling_map=[[0, 1], [1, 2]], - basis_gates=["cx", "h"], - seed=42, - ).target + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="argument ``calibrate_instructions`` is deprecated", + ): + target = GenericBackendV2( + 3, + calibrate_instructions=True, + coupling_map=[[0, 1], [1, 2]], + basis_gates=["cx", "h"], + seed=42, + ).target target.update_instruction_properties("cx", (0, 1), InstructionProperties(0.00001)) target.update_instruction_properties("cx", (1, 2), InstructionProperties(0.00001)) target.update_instruction_properties("h", (0,), InstructionProperties(0.000002)) diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index b74dd7350584..17239d338a2d 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -1657,13 +1657,17 @@ def test_scheduling_instruction_constraints_backend(self): def test_scheduling_instruction_constraints(self): """Test that scheduling-related loose transpile constraints work with target.""" - target = GenericBackendV2( - 2, - calibrate_instructions=True, - coupling_map=[[0, 1]], - basis_gates=["cx", "h"], - seed=42, - ).target + with self.assertWarnsRegex( + DeprecationWarning, + expected_regex="argument ``calibrate_instructions`` is deprecated", + ): + target = GenericBackendV2( + 2, + calibrate_instructions=True, + coupling_map=[[0, 1]], + basis_gates=["cx", "h"], + seed=42, + ).target qc = QuantumCircuit(2) qc.h(0) qc.delay(0.000001, 1, "s")