Skip to content

Commit b9d5c9c

Browse files
HLS fix to not synthesize instructions already supported (Qiskit#13417)
* HLS fix to not synthesize instructions already supported * reno * fix for control-flow-operations The control-flow operations such as 'for-loop` are considered to be a part of 'basis_gates`, yet they need to be recursively synthesized. * using faster is_control_flow check * Update test/python/transpiler/test_high_level_synthesis.py Co-authored-by: Julien Gacon <[email protected]> --------- Co-authored-by: Julien Gacon <[email protected]>
1 parent 74b32c9 commit b9d5c9c

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

qiskit/transpiler/passes/synthesis/high_level_synthesis.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ def _definitely_skip_node(
814814
dag._has_calibration_for(node)
815815
or len(node.qargs) < self._min_qubits
816816
or node.is_directive()
817+
or (self._instruction_supported(node.name, qubits) and not node.is_control_flow())
817818
):
818819
return True
819820

@@ -831,15 +832,12 @@ def _definitely_skip_node(
831832
# If all the above constraints hold, and it's already supported or the basis translator
832833
# can handle it, we'll leave it be.
833834
and (
834-
self._instruction_supported(node.name, qubits)
835835
# This uses unfortunately private details of `EquivalenceLibrary`, but so does the
836836
# `BasisTranslator`, and this is supposed to just be temporary til this is moved
837837
# into Rust space.
838-
or (
839-
self._equiv_lib is not None
840-
and equivalence.Key(name=node.name, num_qubits=node.num_qubits)
841-
in self._equiv_lib.keys()
842-
)
838+
self._equiv_lib is not None
839+
and equivalence.Key(name=node.name, num_qubits=node.num_qubits)
840+
in self._equiv_lib.keys()
843841
)
844842
)
845843

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
fixes:
3+
- |
4+
Previously the :class:`.HighLevelSynthesis` transpiler pass synthesized an
5+
instruction for which a synthesis plugin is available, regardless of
6+
whether the instruction is already supported by the target or a part of
7+
the explicitly passed ``basis_gates``. This behavior is now fixed, so that
8+
such already supported instructions are no longer synthesized.

test/python/transpiler/test_high_level_synthesis.py

+13
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
IGate,
4747
MCXGate,
4848
SGate,
49+
QAOAAnsatz,
4950
)
5051
from qiskit.circuit.library import LinearFunction, PauliEvolutionGate
5152
from qiskit.quantum_info import Clifford, Operator, Statevector, SparsePauliOp
@@ -664,6 +665,18 @@ def test_synth_fails_definition_exists(self):
664665
out = hls(circuit)
665666
self.assertEqual(out.count_ops(), {"u": 1})
666667

668+
def test_both_basis_gates_and_plugin_specified(self):
669+
"""Test that a gate is not synthesized when it belongs to basis_gates,
670+
regardless of whether there is a plugin method available.
671+
672+
See: https://github.com/Qiskit/qiskit/issues/13412 for more
673+
details.
674+
"""
675+
qc = QAOAAnsatz(SparsePauliOp("Z"), initial_state=QuantumCircuit(1))
676+
pm = PassManager([HighLevelSynthesis(basis_gates=["PauliEvolution"])])
677+
qct = pm.run(qc)
678+
self.assertEqual(qct.count_ops()["PauliEvolution"], 2)
679+
667680

668681
class TestPMHSynthesisLinearFunctionPlugin(QiskitTestCase):
669682
"""Tests for the PMHSynthesisLinearFunction plugin for synthesizing linear functions."""

0 commit comments

Comments
 (0)