Skip to content

Commit

Permalink
Reduce number of decomposers used during UnitarySynthesis default plu…
Browse files Browse the repository at this point in the history
…gin (Qiskit#12151)

* Reduce number of decomposers used during UnitarySynthesis default plugin

This commit reduces the number of decomposers we run in the default
synthesis plugin when we're in known targets. Previously the unitary
synthesis plugin was trying to product of all 1q basis and 2q basis for
every 2q pair that is being synthesized. This would result in duplicated
work for several 1q bases where there were potential subsets available
as two different target euler bases, mainly U321 and U3 or ZSX and ZSXX
if the basis gates for a qubit where U3, U2, U1 or Rz, SX, and X
respectively. This reuses the logic from Optimize1qGatesDecomposition to
make the euler basis selection which does the deduplication. Similarly,
in the presence of known 2q gates we can skip the XXDecomposer checks (or
potentially running the XXDecomposer) which should speed up both the
selection of decomposers and also reduce the number of decomposers we
run.

* Update qiskit/transpiler/passes/synthesis/unitary_synthesis.py

---------

Co-authored-by: John Lapeyre <[email protected]>
  • Loading branch information
mtreinish and jlapeyre authored Apr 10, 2024
1 parent a7cc166 commit e48b4c4
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions qiskit/transpiler/passes/synthesis/unitary_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from qiskit.transpiler.exceptions import TranspilerError
from qiskit.dagcircuit.dagcircuit import DAGCircuit
from qiskit.synthesis.one_qubit import one_qubit_decompose
from qiskit.transpiler.passes.optimization.optimize_1q_decomposition import _possible_decomposers
from qiskit.synthesis.two_qubit.xx_decompose import XXDecomposer, XXEmbodiments
from qiskit.synthesis.two_qubit.two_qubit_decompose import (
TwoQubitBasisDecomposer,
Expand Down Expand Up @@ -84,23 +85,16 @@ def _choose_kak_gate(basis_gates):
def _choose_euler_basis(basis_gates):
"""Choose the first available 1q basis to use in the Euler decomposition."""
basis_set = set(basis_gates or [])

for basis, gates in one_qubit_decompose.ONE_QUBIT_EULER_BASIS_GATES.items():

if set(gates).issubset(basis_set):
return basis

decomposers = _possible_decomposers(basis_set)
if decomposers:
return decomposers[0]
return "U"


def _find_matching_euler_bases(target, qubit):
"""Find matching available 1q basis to use in the Euler decomposition."""
euler_basis_gates = []
basis_set = target.operation_names_for_qargs((qubit,))
for basis, gates in one_qubit_decompose.ONE_QUBIT_EULER_BASIS_GATES.items():
if set(gates).issubset(basis_set):
euler_basis_gates.append(basis)
return euler_basis_gates
return _possible_decomposers(basis_set)


def _choose_bases(basis_gates, basis_dict=None):
Expand Down Expand Up @@ -777,6 +771,13 @@ def is_controlled(gate):
)
decomposers.append(decomposer)

# If our 2q basis gates are a subset of cx, ecr, or cz then we know TwoQubitBasisDecomposer
# is an ideal decomposition and there is no need to bother calculating the XX embodiments
# or try the XX decomposer
if {"cx", "cz", "ecr"}.issuperset(available_2q_basis):
self._decomposer_cache[qubits_tuple] = decomposers
return decomposers

# possible controlled decomposers (i.e. XXDecomposer)
controlled_basis = {k: v for k, v in available_2q_basis.items() if is_controlled(v)}
basis_2q_fidelity = {}
Expand Down

0 comments on commit e48b4c4

Please sign in to comment.