diff --git a/qiskit/transpiler/passes/optimization/cx_cancellation.py b/qiskit/transpiler/passes/optimization/cx_cancellation.py index df1ffc8ebe2..4b8f8572f89 100644 --- a/qiskit/transpiler/passes/optimization/cx_cancellation.py +++ b/qiskit/transpiler/passes/optimization/cx_cancellation.py @@ -14,11 +14,21 @@ from qiskit.transpiler.basepasses import TransformationPass from qiskit.transpiler.passes.utils import control_flow +from qiskit.utils.deprecation import deprecate_func class CXCancellation(TransformationPass): """Cancel back-to-back ``cx`` gates in dag.""" + @deprecate_func( + additional_msg=( + "Instead, use :class:`~.InverseCancellation`, which is a more generic pass." + ), + since="1.1.0", + ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + @control_flow.trivial_recurse def run(self, dag): """Run the CXCancellation pass on `dag`. diff --git a/releasenotes/notes/fixes_11212-d6de3c007ce6d697.yaml b/releasenotes/notes/fixes_11212-d6de3c007ce6d697.yaml new file mode 100644 index 00000000000..32314b50692 --- /dev/null +++ b/releasenotes/notes/fixes_11212-d6de3c007ce6d697.yaml @@ -0,0 +1,6 @@ +--- +deprecations_transpiler: + - | + The pass ``qiskit.transpiler.passes.CXCancellation`` was deprecated in favor of + class:`.InverseCancellation`, which is more generic. + ``CXCancellation`` is fully semantically equivalent to ``InverseCancellation([CXGate()])``. diff --git a/test/benchmarks/passes.py b/test/benchmarks/passes.py index 19fb4f265c0..b79419fc2d9 100644 --- a/test/benchmarks/passes.py +++ b/test/benchmarks/passes.py @@ -18,6 +18,7 @@ from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as SEL from qiskit.transpiler.passes import * from qiskit.converters import circuit_to_dag +from qiskit.circuit.library import CXGate from .utils import random_circuit @@ -128,7 +129,7 @@ def time_resource_optimization(self, _, __): ResourceEstimation().run(self.dag) def time_cx_cancellation(self, _, __): - CXCancellation().run(self.dag) + InverseCancellation([CXGate()]).run(self.dag) def time_dag_longest_path(self, _, __): DAGLongestPath().run(self.dag) diff --git a/test/python/circuit/test_unitary.py b/test/python/circuit/test_unitary.py index 3c6cd22567a..23aec666cbd 100644 --- a/test/python/circuit/test_unitary.py +++ b/test/python/circuit/test_unitary.py @@ -17,13 +17,13 @@ from numpy.testing import assert_allclose import qiskit -from qiskit.circuit.library import UnitaryGate +from qiskit.circuit.library import UnitaryGate, CXGate from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.transpiler import PassManager from qiskit.converters import circuit_to_dag, dag_to_circuit from qiskit.quantum_info.random import random_unitary from qiskit.quantum_info.operators import Operator -from qiskit.transpiler.passes import CXCancellation +from qiskit.transpiler.passes import InverseCancellation from qiskit.qasm2 import dumps from test import QiskitTestCase # pylint: disable=wrong-import-order @@ -103,7 +103,7 @@ def test_2q_unitary(self): uni2q = UnitaryGate(matrix) qc.append(uni2q, [qr[0], qr[1]]) passman = PassManager() - passman.append(CXCancellation()) + passman.append(InverseCancellation([CXGate()])) qc2 = passman.run(qc) # test of qasm output self.log.info(dumps(qc2)) diff --git a/test/python/transpiler/test_cx_cancellation.py b/test/python/transpiler/test_cx_cancellation.py index 0a40953c17b..1ed4b7b9bdb 100644 --- a/test/python/transpiler/test_cx_cancellation.py +++ b/test/python/transpiler/test_cx_cancellation.py @@ -39,7 +39,8 @@ def test_pass_cx_cancellation(self): circuit.cx(qr[1], qr[0]) pass_manager = PassManager() - pass_manager.append(CXCancellation()) + with self.assertWarns(DeprecationWarning): + pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) expected = QuantumCircuit(qr) @@ -60,7 +61,8 @@ def test_pass_cx_cancellation_intermixed_ops(self): circuit.cx(qr[2], qr[3]) pass_manager = PassManager() - pass_manager.append(CXCancellation()) + with self.assertWarns(DeprecationWarning): + pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) expected = QuantumCircuit(qr) @@ -92,7 +94,8 @@ def test_pass_cx_cancellation_chained_cx(self): circuit.cx(qr[2], qr[3]) pass_manager = PassManager() - pass_manager.append(CXCancellation()) + with self.assertWarns(DeprecationWarning): + pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) # ┌───┐ @@ -121,7 +124,8 @@ def test_swapped_cx(self): circuit.cx(qr[1], qr[0]) pass_manager = PassManager() - pass_manager.append(CXCancellation()) + with self.assertWarns(DeprecationWarning): + pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) self.assertEqual(out_circuit, circuit) @@ -134,13 +138,15 @@ def test_inverted_cx(self): circuit.cx(qr[0], qr[1]) pass_manager = PassManager() - pass_manager.append(CXCancellation()) + with self.assertWarns(DeprecationWarning): + pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) self.assertEqual(out_circuit, circuit) def test_if_else(self): """Test that the pass recurses in a simple if-else.""" - pass_ = CXCancellation() + with self.assertWarns(DeprecationWarning): + pass_ = CXCancellation() inner_test = QuantumCircuit(4, 1) inner_test.cx(0, 1) @@ -164,7 +170,8 @@ def test_if_else(self): def test_nested_control_flow(self): """Test that collection recurses into nested control flow.""" - pass_ = CXCancellation() + with self.assertWarns(DeprecationWarning): + pass_ = CXCancellation() qubits = [Qubit() for _ in [None] * 4] clbit = Clbit() diff --git a/test/python/transpiler/test_swap_strategy_router.py b/test/python/transpiler/test_swap_strategy_router.py index e35256ec44c..4a46efd57b2 100644 --- a/test/python/transpiler/test_swap_strategy_router.py +++ b/test/python/transpiler/test_swap_strategy_router.py @@ -16,7 +16,7 @@ from qiskit.circuit import QuantumCircuit, Qubit, QuantumRegister from qiskit.transpiler import PassManager, CouplingMap, Layout, TranspilerError -from qiskit.circuit.library import PauliEvolutionGate +from qiskit.circuit.library import PauliEvolutionGate, CXGate from qiskit.circuit.library.n_local import QAOAAnsatz from qiskit.converters import circuit_to_dag from qiskit.exceptions import QiskitError @@ -25,7 +25,7 @@ from qiskit.transpiler.passes import EnlargeWithAncilla from qiskit.transpiler.passes import ApplyLayout from qiskit.transpiler.passes import SetLayout -from qiskit.transpiler.passes import CXCancellation +from qiskit.transpiler.passes import InverseCancellation from qiskit.transpiler.passes import Decompose from qiskit.transpiler.passes.routing.commuting_2q_gate_routing.commuting_2q_block import ( Commuting2qBlock, @@ -524,7 +524,7 @@ def test_edge_coloring(self, edge_coloring): Commuting2qGateRouter(swap_strat, edge_coloring=edge_coloring), Decompose(), # double decompose gets to CX Decompose(), - CXCancellation(), + InverseCancellation([CXGate()]), ] )