Skip to content

Commit

Permalink
Fix InverseCancellation pass to handle gates of different names. (#7383
Browse files Browse the repository at this point in the history
…) (#7384)

As reported in GH-7378, the InverseCancellation optimization pass
previously assumed that inverse gate pairs would always share a
common name, but this is not universally true. This commit updates
the pass to search for runs containing any of the gate names in the
gates_to_cancel list, instead of only the first.

Co-authored-by: Bruno Schmitt <bruno.schmitt@epfl.ch>

Co-authored-by: Bruno Schmitt <bruno.schmitt@epfl.ch>
(cherry picked from commit d9ab98f)

Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com>
  • Loading branch information
mergify[bot] and kdk authored Dec 9, 2021
1 parent 73024df commit bd7791e
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def _run_on_inverse_pairs(self, dag: DAGCircuit, inverse_gate_pairs: List[Tuple[
DAGCircuit: Transformed DAG.
"""
for pair in inverse_gate_pairs:
gate_cancel_runs = dag.collect_runs([pair[0].name])
gate_cancel_runs = dag.collect_runs([pair[0].name, pair[1].name])
for dag_nodes in gate_cancel_runs:
for i in range(len(dag_nodes) - 1):
if dag_nodes[i].op == pair[0] and dag_nodes[i + 1].op == pair[1]:
Expand Down
14 changes: 13 additions & 1 deletion test/python/transpiler/test_inverse_cancellation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from qiskit.transpiler.passes import InverseCancellation
from qiskit.transpiler import PassManager
from qiskit.test import QiskitTestCase
from qiskit.circuit.library import RXGate, HGate, CXGate, PhaseGate, XGate
from qiskit.circuit.library import RXGate, HGate, CXGate, PhaseGate, XGate, TGate, TdgGate


class TestInverseCancellation(QiskitTestCase):
Expand Down Expand Up @@ -164,3 +164,15 @@ def test_consecutive_self_inverse_h_x_gate(self):
gates_after = new_circ.count_ops()
self.assertNotIn("x", gates_after)
self.assertEqual(gates_after["h"], 2)

def test_inverse_with_different_names(self):
"""Test that inverse gates that have different names."""
qc = QuantumCircuit(2, 2)
qc.t(0)
qc.tdg(0)
pass_ = InverseCancellation([(TGate(), TdgGate())])
pm = PassManager(pass_)
new_circ = pm.run(qc)
gates_after = new_circ.count_ops()
self.assertNotIn("t", gates_after)
self.assertNotIn("tdg", gates_after)

0 comments on commit bd7791e

Please sign in to comment.