diff --git a/qiskit/transpiler/passes/routing/algorithms/bip_model.py b/qiskit/transpiler/passes/routing/algorithms/bip_model.py index f0b7d576d4c3..7a37ff6a949b 100644 --- a/qiskit/transpiler/passes/routing/algorithms/bip_model.py +++ b/qiskit/transpiler/passes/routing/algorithms/bip_model.py @@ -26,6 +26,7 @@ trace_to_fid, ) from qiskit.utils import optionals as _optionals +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) @@ -41,6 +42,12 @@ class BIPMappingModel: the solution will be stored in :attr:`solution`). None if it's not yet set. """ + @deprecate_func( + since="0.24.0", + additional_msg="This has been replaced by a new transpiler plugin package: " + "qiskit-bip-mapper. More details can be found here: " + "https://github.com/qiskit-community/qiskit-bip-mapper", + ) # pylint: disable=bad-docstring-quotes def __init__(self, dag, coupling_map, qubit_subset, dummy_timesteps=None): """ Args: diff --git a/qiskit/transpiler/passes/routing/bip_mapping.py b/qiskit/transpiler/passes/routing/bip_mapping.py index 9f6fc177eece..58b040a9821c 100644 --- a/qiskit/transpiler/passes/routing/bip_mapping.py +++ b/qiskit/transpiler/passes/routing/bip_mapping.py @@ -23,6 +23,7 @@ from qiskit.transpiler.exceptions import TranspilerError from qiskit.transpiler.passes.routing.algorithms.bip_model import BIPMappingModel from qiskit.transpiler.target import target_to_backend_properties, Target +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) @@ -63,6 +64,12 @@ class BIPMapping(TransformationPass): `arXiv:2106.06446 `_ """ + @deprecate_func( + since="0.24.0", + additional_msg="This has been replaced by a new transpiler plugin package: " + "qiskit-bip-mapper. More details can be found here: " + "https://github.com/qiskit-community/qiskit-bip-mapper", + ) # pylint: disable=bad-docstring-quotes def __init__( self, coupling_map, diff --git a/releasenotes/notes/deprecate-bip-mapping-f0025c4c724e1ec8.yaml b/releasenotes/notes/deprecate-bip-mapping-f0025c4c724e1ec8.yaml new file mode 100644 index 000000000000..93a0523397bd --- /dev/null +++ b/releasenotes/notes/deprecate-bip-mapping-f0025c4c724e1ec8.yaml @@ -0,0 +1,14 @@ +--- +deprecations: + - | + The transpiler routing pass, :class:`~.BIPMapping` has been deprecated + and will be removed in a future release. It has been replaced by an external + plugin package: ``qiskit-bip-mapper``. Details for this new package can + be found at the package's github repository: + + https://github.com/qiskit-community/qiskit-bip-mapper + + The pass was made into a separate plugin package for two reasons, first + the dependency on CPLEX makes it harder to use and secondly the plugin + packge more cleanly integrates with :func:`~.transpile`. + diff --git a/test/python/transpiler/test_bip_mapping.py b/test/python/transpiler/test_bip_mapping.py index 60283abec750..a95ca727f79a 100644 --- a/test/python/transpiler/test_bip_mapping.py +++ b/test/python/transpiler/test_bip_mapping.py @@ -36,7 +36,8 @@ def test_empty(self): """Returns the original circuit if the circuit is empty.""" coupling = CouplingMap([[0, 1]]) circuit = QuantumCircuit(2) - actual = BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit) self.assertEqual(circuit, actual) def test_no_two_qubit_gates(self): @@ -49,8 +50,8 @@ def test_no_two_qubit_gates(self): circuit = QuantumCircuit(2) circuit.h(0) - - actual = BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit) self.assertEqual(circuit, actual) @@ -70,7 +71,8 @@ def test_trivial_case(self): circuit.h(0) circuit.cx(2, 0) - actual = BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit) self.assertEqual(3, len(actual)) for inst, _, _ in actual.data: # there are no swaps self.assertFalse(isinstance(inst, SwapGate)) @@ -82,7 +84,8 @@ def test_no_swap(self): circuit = QuantumCircuit(3) circuit.cx(1, 2) - actual = BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit) q = QuantumRegister(3, name="q") expected = QuantumCircuit(q) @@ -98,7 +101,8 @@ def test_ignore_initial_layout(self): circuit.cx(1, 2) property_set = {"layout": Layout.generate_trivial_layout(*circuit.qubits)} - actual = BIPMapping(coupling)(circuit, property_set) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit, property_set) q = QuantumRegister(3, name="q") expected = QuantumCircuit(q) @@ -117,7 +121,8 @@ def test_can_map_measurements_correctly(self): circuit.measure(qr[1], cr[0]) circuit.measure(qr[2], cr[1]) - actual = BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit) q = QuantumRegister(3, "q") expected = QuantumCircuit(q, cr) @@ -139,7 +144,8 @@ def test_can_map_measurements_correctly_with_target(self): circuit.measure(qr[1], cr[0]) circuit.measure(qr[2], cr[1]) - actual = BIPMapping(target)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(target)(circuit) q = QuantumRegister(3, "q") expected = QuantumCircuit(q, cr) @@ -162,8 +168,9 @@ def test_never_modify_mapped_circuit(self): circuit.measure(2, 1) dag = circuit_to_dag(circuit) - mapped_dag = BIPMapping(coupling).run(dag) - remapped_dag = BIPMapping(coupling).run(mapped_dag) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + mapped_dag = BIPMapping(coupling).run(dag) + remapped_dag = BIPMapping(coupling).run(mapped_dag) self.assertEqual(mapped_dag, remapped_dag) @@ -177,7 +184,8 @@ def test_no_swap_multi_layer(self): circuit.cx(qr[0], qr[3]) property_set = {} - actual = BIPMapping(coupling, objective="depth")(circuit, property_set) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling, objective="depth")(circuit, property_set) self.assertEqual(2, actual.depth()) CheckMap(coupling)(actual, property_set) @@ -194,7 +202,8 @@ def test_unmappable_cnots_in_a_layer(self): circuit.measure(qr, cr) coupling = CouplingMap([[0, 1], [1, 2], [1, 3]]) # {0: [1], 1: [2, 3]} - actual = BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling)(circuit) # Fails to map and returns the original circuit self.assertEqual(circuit, actual) @@ -233,7 +242,8 @@ def test_multi_cregs(self): coupling = CouplingMap([[0, 1], [0, 2], [2, 3]]) # linear [1, 0, 2, 3] property_set = {} - actual = BIPMapping(coupling, objective="depth")(circuit, property_set) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling, objective="depth")(circuit, property_set) self.assertEqual(5, actual.depth()) CheckMap(coupling)(actual, property_set) @@ -264,7 +274,8 @@ def test_swaps_in_dummy_steps(self): coupling = CouplingMap.from_line(4) property_set = {} - actual = BIPMapping(coupling, objective="depth")(circuit, property_set) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling, objective="depth")(circuit, property_set) self.assertEqual(7, actual.depth()) CheckMap(coupling)(actual, property_set) @@ -295,7 +306,8 @@ def test_different_number_of_virtual_and_physical_qubits(self): coupling = CouplingMap.from_line(5) with self.assertRaises(TranspilerError): - BIPMapping(coupling)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + BIPMapping(coupling)(circuit) def test_qubit_subset(self): """Test if `qubit_subset` option works as expected.""" @@ -306,7 +318,8 @@ def test_qubit_subset(self): coupling = CouplingMap([(0, 1), (1, 3), (3, 2)]) qubit_subset = [0, 1, 3] - actual = BIPMapping(coupling, qubit_subset=qubit_subset)(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + actual = BIPMapping(coupling, qubit_subset=qubit_subset)(circuit) # all used qubits are in qubit_subset bit_indices = {bit: index for index, bit in enumerate(actual.qubits)} for _, qargs, _ in actual.data: @@ -323,7 +336,8 @@ def test_unconnected_qubit_subset(self): coupling = CouplingMap([(0, 1), (1, 3), (3, 2)]) with self.assertRaises(TranspilerError): - BIPMapping(coupling, qubit_subset=[0, 1, 2])(circuit) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + BIPMapping(coupling, qubit_subset=[0, 1, 2])(circuit) def test_objective_function(self): """Test if ``objective`` functions prioritize metrics correctly.""" @@ -345,13 +359,15 @@ def test_objective_function(self): qc.dcx(0, 1) qc.cx(2, 3) coupling = CouplingMap(FakeLima().configuration().coupling_map) - dep_opt = BIPMapping(coupling, objective="depth", qubit_subset=[0, 1, 3, 4])(qc) - err_opt = BIPMapping( - coupling, - objective="gate_error", - qubit_subset=[0, 1, 3, 4], - backend_prop=FakeLima().properties(), - )(qc) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + dep_opt = BIPMapping(coupling, objective="depth", qubit_subset=[0, 1, 3, 4])(qc) + with self.assertWarnsRegex(DeprecationWarning, r"^The class.*is deprecated"): + err_opt = BIPMapping( + coupling, + objective="gate_error", + qubit_subset=[0, 1, 3, 4], + backend_prop=FakeLima().properties(), + )(qc) # depth = number of su4 layers (mirrored gates have to be consolidated as single su4 gates) pm_ = PassManager([Collect2qBlocks(), ConsolidateBlocks(basis_gates=["cx", "u"])]) dep_opt = pm_.run(dep_opt)