Skip to content

Commit

Permalink
Fix an unchecked condition in InverseCancellation (#11834) (#11867)
Browse files Browse the repository at this point in the history
* fix an unchecked condition in self_inverse inversecancellation

* add release note for the bug in inversecancellation

* reformat reverse_cancellation.py to follow the standards

* update fix-inverse-cancellation release note

* add a test for InverseCancellation with self-inverse

* fix a typo in test_inverse_cancellation.py

Co-authored-by: Matthew Treinish <[email protected]>

* Update qiskit/transpiler/passes/optimization/inverse_cancellation.py

* Update releasenotes/notes/fix-inverse-cancellation-self-inverse-e09a5553331e1b0b.yaml

* Revert "Update qiskit/transpiler/passes/optimization/inverse_cancellation.py"

This had a logical error in it and doesn't work.

This reverts commit 0048e8e.

---------

Co-authored-by: Matthew Treinish <[email protected]>
(cherry picked from commit 8509d94)

Co-authored-by: Seyed Sajad Kahani <[email protected]>
  • Loading branch information
mergify[bot] and sesajad authored Feb 22, 2024
1 parent 150c534 commit 77e08e1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
7 changes: 3 additions & 4 deletions qiskit/transpiler/passes/optimization/inverse_cancellation.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,18 @@ def _run_on_self_inverse(self, dag: DAGCircuit):
for gate_cancel_run in gate_runs:
partitions = []
chunk = []
for i in range(len(gate_cancel_run) - 1):
max_index = len(gate_cancel_run) - 1
for i in range(len(gate_cancel_run)):
if gate_cancel_run[i].op == gate:
chunk.append(gate_cancel_run[i])
else:
if chunk:
partitions.append(chunk)
chunk = []
continue
if gate_cancel_run[i].qargs != gate_cancel_run[i + 1].qargs:
if i == max_index or gate_cancel_run[i].qargs != gate_cancel_run[i + 1].qargs:
partitions.append(chunk)
chunk = []
chunk.append(gate_cancel_run[-1])
partitions.append(chunk)
# Remove an even number of gates from each chunk
for chunk in partitions:
if len(chunk) % 2 == 0:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

fixes:
- |
Fixed an issue in the :class:`.InverseCancellation` transpiler pass where in some cases it
would incorrectly cancel a self-inverse parameterized gate even if the parameter value
didn't match.
Fixed `#11815 <https://github.com/Qiskit/qiskit/issues/11815>`__
16 changes: 14 additions & 2 deletions test/python/transpiler/test_inverse_cancellation.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,10 @@ def test_parameterized_self_inverse(self):
new_circ = inverse_pass(qc)
self.assertEqual(new_circ, QuantumCircuit(1))

def test_parameterized_self_inverse_not_equal_parameter(self):
"""Test that a parameterized self inverse gate doesn't cancel incorrectly."""
def test_parameterized_self_inverse_not_equal_parameter_1(self):
"""Test that a parameterized self inverse gate doesn't cancel incorrectly.
This test, checks three gates with the same name but the middle one has a
different parameter."""
qc = QuantumCircuit(1)
qc.rz(0, 0)
qc.rz(3.14159, 0)
Expand All @@ -368,6 +370,16 @@ def test_parameterized_self_inverse_not_equal_parameter(self):
new_circ = inverse_pass(qc)
self.assertEqual(new_circ, qc)

def test_parameterized_self_inverse_not_equal_parameter_2(self):
"""Test that a parameterized self inverse gate doesn't cancel incorrectly.
This test, checks two gates with the same name but different parameters."""
qc = QuantumCircuit(1)
qc.rz(0, 0)
qc.rz(3.14159, 0)
inverse_pass = InverseCancellation([RZGate(0)])
new_circ = inverse_pass(qc)
self.assertEqual(qc, new_circ)

def test_controlled_gate_open_control_does_not_cancel(self):
"""Test that a controlled gate with an open control doesn't cancel."""
qc = QuantumCircuit(2)
Expand Down

0 comments on commit 77e08e1

Please sign in to comment.