mirror of https://github.com/Qiskit/qiskit.git
Fix handling of 1q gates in UnitarySynthesis with target (#8847)
This commit fixes a bug in the UnitarySynthesis pass with 1q gates and a Target set. Previously the pass unconditionally expected that it would only ever encounter 2 or more qubits when it was running on a node if the target was set. This would cause a failure if it ever encountered a 1q node in the dag. This commit fixes the handling so the pass will synthesize 1 qubit unitaries it encounters too. Fixes #8845 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
7bc3cb62bd
commit
3bb60b4c1e
|
@ -529,27 +529,30 @@ class DefaultUnitarySynthesis(plugin.UnitarySynthesisPlugin):
|
|||
qubits = options["coupling_map"][1]
|
||||
target = options["target"]
|
||||
|
||||
euler_basis = _choose_euler_basis(basis_gates)
|
||||
if euler_basis is not None:
|
||||
decomposer1q = one_qubit_decompose.OneQubitEulerDecomposer(euler_basis)
|
||||
else:
|
||||
decomposer1q = None
|
||||
|
||||
preferred_direction = None
|
||||
if target is not None:
|
||||
decomposer2q, preferred_direction = self._find_decomposer_2q_from_target(
|
||||
target, qubits, pulse_optimize
|
||||
)
|
||||
else:
|
||||
decomposer2q = _basis_gates_to_decomposer_2q(basis_gates, pulse_optimize=pulse_optimize)
|
||||
|
||||
synth_dag = None
|
||||
wires = None
|
||||
if unitary.shape == (2, 2):
|
||||
if target is not None:
|
||||
euler_basis = _choose_euler_basis(target.operation_names_for_qargs(tuple(qubits)))
|
||||
else:
|
||||
euler_basis = _choose_euler_basis(basis_gates)
|
||||
if euler_basis is not None:
|
||||
decomposer1q = one_qubit_decompose.OneQubitEulerDecomposer(euler_basis)
|
||||
else:
|
||||
decomposer1q = None
|
||||
if decomposer1q is None:
|
||||
return None
|
||||
synth_dag = circuit_to_dag(decomposer1q._decompose(unitary))
|
||||
elif unitary.shape == (4, 4):
|
||||
preferred_direction = None
|
||||
if target is not None:
|
||||
decomposer2q, preferred_direction = self._find_decomposer_2q_from_target(
|
||||
target, qubits, pulse_optimize
|
||||
)
|
||||
else:
|
||||
decomposer2q = _basis_gates_to_decomposer_2q(
|
||||
basis_gates, pulse_optimize=pulse_optimize
|
||||
)
|
||||
if not decomposer2q:
|
||||
return None
|
||||
synth_dag, wires = self._synth_natural_direction(
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed an issue with the :class:`~.UnitarySynthesis` pass where a circuit
|
||||
with 1 qubit gates and a :class:`~.Target` input would sometimes fail
|
||||
instead of processing the circuit as expected.
|
|
@ -24,7 +24,7 @@ from ddt import ddt, data
|
|||
|
||||
from qiskit import transpile
|
||||
from qiskit.test import QiskitTestCase
|
||||
from qiskit.providers.fake_provider import FakeVigo, FakeMumbaiFractionalCX
|
||||
from qiskit.providers.fake_provider import FakeVigo, FakeMumbaiFractionalCX, FakeBelemV2
|
||||
from qiskit.providers.fake_provider.fake_backend_v2 import FakeBackendV2, FakeBackend5QV2
|
||||
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
||||
from qiskit.circuit.library import QuantumVolume
|
||||
|
@ -51,7 +51,7 @@ from qiskit.transpiler.passes import (
|
|||
SabreSwap,
|
||||
TrivialLayout,
|
||||
)
|
||||
from qiskit.circuit.library import CXGate, ECRGate, UGate
|
||||
from qiskit.circuit.library import CXGate, ECRGate, UGate, ZGate
|
||||
from qiskit.circuit import Parameter
|
||||
|
||||
|
||||
|
@ -766,6 +766,26 @@ class TestUnitarySynthesis(QiskitTestCase):
|
|||
self.assertEqual(cbody.count_ops().keys(), {"u", "cx"})
|
||||
self.assertEqual(qc_uni1_mat, Operator(cbody))
|
||||
|
||||
def test_single_qubit_with_target(self):
|
||||
"""Test input circuit with only 1q works with target."""
|
||||
qc = QuantumCircuit(1)
|
||||
qc.append(ZGate(), [qc.qubits[0]])
|
||||
dag = circuit_to_dag(qc)
|
||||
unitary_synth_pass = UnitarySynthesis(target=FakeBelemV2().target)
|
||||
result_dag = unitary_synth_pass.run(dag)
|
||||
result_qc = dag_to_circuit(result_dag)
|
||||
self.assertEqual(qc, result_qc)
|
||||
|
||||
def test_single_qubit_identity_with_target(self):
|
||||
"""Test input single qubit identity works with target."""
|
||||
qc = QuantumCircuit(1)
|
||||
qc.unitary([[1.0, 0.0], [0.0, 1.0]], 0)
|
||||
dag = circuit_to_dag(qc)
|
||||
unitary_synth_pass = UnitarySynthesis(target=FakeBelemV2().target)
|
||||
result_dag = unitary_synth_pass.run(dag)
|
||||
result_qc = dag_to_circuit(result_dag)
|
||||
self.assertEqual(result_qc, QuantumCircuit(1))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue