Skip to content

Commit

Permalink
Remove lone identity gates in Optimize 1q decomposition pass (#5292) (#…
Browse files Browse the repository at this point in the history
…5385)

* Remove lone identity gates in Optimize 1q decomposition pass

When running the optimize 1q decomposition pass for basis sets other
than u1, u2, u3 there was an edge case where it wouldn't remove lone
identity gates. This was because normally the pass skips runs of length
1 because the Euler decomposer will normally not do better than that.
But, in the case of identity gates we know that they can just be
removed, and the simplify=True flag on the decomposer will normally do
this for us. But, since we don't run the decomposer this commit fixes
this edge case by explicitly checking the single gate for an identity
and removing it if it is.

Fixes #5287

* Use append instead of deprecated u3 method in test

* Compare to identity matrix instead of checking all parameters are 0

(cherry picked from commit 1578fb4)

Co-authored-by: Matthew Treinish <[email protected]>
  • Loading branch information
mergify[bot] and mtreinish authored Nov 12, 2020
1 parent 230c07b commit 1a009ca
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from itertools import groupby
import logging

import numpy as np

from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.quantum_info import Operator
from qiskit.transpiler.basepasses import TransformationPass
Expand Down Expand Up @@ -71,8 +73,14 @@ def run(self, dag):
runs = dag.collect_runs(self.euler_basis_names[self.basis])
runs = _split_runs_on_parameters(runs)
for run in runs:
# Don't try to optimize a single 1q gate
if len(run) <= 1:
params = run[0].op.params
# Remove single identity gates
if run[0].op.name in self.euler_basis_names[self.basis] and len(
params) > 0 and np.array_equal(run[0].op.to_matrix(),
np.eye(2)):
dag.remove_op_node(run[0])
# Don't try to optimize a single 1q gate
continue
q = QuantumRegister(1, "q")
qc = QuantumCircuit(1)
Expand Down
81 changes: 81 additions & 0 deletions test/python/transpiler/test_optimize_1q_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import numpy as np

from qiskit.circuit import QuantumRegister, QuantumCircuit, ClassicalRegister
from qiskit.circuit.library.standard_gates import U3Gate
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import Optimize1qGatesDecomposition
from qiskit.transpiler.passes import BasisTranslator
Expand Down Expand Up @@ -235,6 +236,86 @@ def test_parameterized_expressions_in_circuits(self, basis):
Operator(qc.bind_parameters({theta: 3.14, phi: 10})).equiv(
Operator(result.bind_parameters({theta: 3.14, phi: 10}))))

def test_identity_xyx(self):
"""Test lone identity gates in rx ry basis are removed."""
circuit = QuantumCircuit(2)
circuit.rx(0, 1)
circuit.ry(0, 0)
basis = ['rxx', 'rx', 'ry']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)

def test_identity_zxz(self):
"""Test lone identity gates in rx rz basis are removed."""
circuit = QuantumCircuit(2)
circuit.rx(0, 1)
circuit.rz(0, 0)
basis = ['cz', 'rx', 'rz']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)

def test_identity_psx(self):
"""Test lone identity gates in p sx basis are removed."""
circuit = QuantumCircuit(1)
circuit.p(0, 0)
basis = ['cx', 'p', 'sx']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)

def test_identity_u(self):
"""Test lone identity gates in u basis are removed."""
circuit = QuantumCircuit(1)
circuit.u(0, 0, 0, 0)
basis = ['cx', 'u']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)

def test_identity_u3(self):
"""Test lone identity gates in u3 basis are removed."""
circuit = QuantumCircuit(1)
circuit.append(U3Gate(0, 0, 0), [0])
basis = ['cx', 'u3']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)

def test_identity_r(self):
"""Test lone identity gates in r basis are removed."""
circuit = QuantumCircuit(1)
circuit.r(0, 0, 0)
basis = ['r']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)

def test_identity_u1x(self):
"""Test lone identity gates in u1 rx basis are removed."""
circuit = QuantumCircuit(2)
circuit.u1(0, 0)
circuit.rx(0, 1)
basis = ['cx', 'u1', 'rx']
passmanager = PassManager()
passmanager.append(BasisTranslator(sel, basis))
passmanager.append(Optimize1qGatesDecomposition(basis))
result = passmanager.run(circuit)
self.assertEqual([], result.data)


if __name__ == '__main__':
unittest.main()

0 comments on commit 1a009ca

Please sign in to comment.