mirror of https://github.com/Qiskit/qiskit.git
Reduce number of decomposers used during UnitarySynthesis default plugin (#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 <jlapeyre@users.noreply.github.com>
This commit is contained in:
parent
a7cc16624a
commit
e48b4c47de
|
@ -35,6 +35,7 @@ from qiskit.transpiler.basepasses import TransformationPass
|
||||||
from qiskit.transpiler.exceptions import TranspilerError
|
from qiskit.transpiler.exceptions import TranspilerError
|
||||||
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
||||||
from qiskit.synthesis.one_qubit import one_qubit_decompose
|
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.xx_decompose import XXDecomposer, XXEmbodiments
|
||||||
from qiskit.synthesis.two_qubit.two_qubit_decompose import (
|
from qiskit.synthesis.two_qubit.two_qubit_decompose import (
|
||||||
TwoQubitBasisDecomposer,
|
TwoQubitBasisDecomposer,
|
||||||
|
@ -84,23 +85,16 @@ def _choose_kak_gate(basis_gates):
|
||||||
def _choose_euler_basis(basis_gates):
|
def _choose_euler_basis(basis_gates):
|
||||||
"""Choose the first available 1q basis to use in the Euler decomposition."""
|
"""Choose the first available 1q basis to use in the Euler decomposition."""
|
||||||
basis_set = set(basis_gates or [])
|
basis_set = set(basis_gates or [])
|
||||||
|
decomposers = _possible_decomposers(basis_set)
|
||||||
for basis, gates in one_qubit_decompose.ONE_QUBIT_EULER_BASIS_GATES.items():
|
if decomposers:
|
||||||
|
return decomposers[0]
|
||||||
if set(gates).issubset(basis_set):
|
|
||||||
return basis
|
|
||||||
|
|
||||||
return "U"
|
return "U"
|
||||||
|
|
||||||
|
|
||||||
def _find_matching_euler_bases(target, qubit):
|
def _find_matching_euler_bases(target, qubit):
|
||||||
"""Find matching available 1q basis to use in the Euler decomposition."""
|
"""Find matching available 1q basis to use in the Euler decomposition."""
|
||||||
euler_basis_gates = []
|
|
||||||
basis_set = target.operation_names_for_qargs((qubit,))
|
basis_set = target.operation_names_for_qargs((qubit,))
|
||||||
for basis, gates in one_qubit_decompose.ONE_QUBIT_EULER_BASIS_GATES.items():
|
return _possible_decomposers(basis_set)
|
||||||
if set(gates).issubset(basis_set):
|
|
||||||
euler_basis_gates.append(basis)
|
|
||||||
return euler_basis_gates
|
|
||||||
|
|
||||||
|
|
||||||
def _choose_bases(basis_gates, basis_dict=None):
|
def _choose_bases(basis_gates, basis_dict=None):
|
||||||
|
@ -777,6 +771,13 @@ class DefaultUnitarySynthesis(plugin.UnitarySynthesisPlugin):
|
||||||
)
|
)
|
||||||
decomposers.append(decomposer)
|
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)
|
# possible controlled decomposers (i.e. XXDecomposer)
|
||||||
controlled_basis = {k: v for k, v in available_2q_basis.items() if is_controlled(v)}
|
controlled_basis = {k: v for k, v in available_2q_basis.items() if is_controlled(v)}
|
||||||
basis_2q_fidelity = {}
|
basis_2q_fidelity = {}
|
||||||
|
|
Loading…
Reference in New Issue