Skip to content

Commit

Permalink
HLS fix to not synthesize instructions already supported (#13417)
Browse files Browse the repository at this point in the history
* 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 <gaconju@gmail.com>

---------

Co-authored-by: Julien Gacon <gaconju@gmail.com>
  • Loading branch information
alexanderivrii and Cryoris authored Nov 14, 2024
1 parent 74b32c9 commit b9d5c9c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
10 changes: 4 additions & 6 deletions qiskit/transpiler/passes/synthesis/high_level_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ def _definitely_skip_node(
dag._has_calibration_for(node)
or len(node.qargs) < self._min_qubits
or node.is_directive()
or (self._instruction_supported(node.name, qubits) and not node.is_control_flow())
):
return True

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
fixes:
- |
Previously the :class:`.HighLevelSynthesis` transpiler pass synthesized an
instruction for which a synthesis plugin is available, regardless of
whether the instruction is already supported by the target or a part of
the explicitly passed ``basis_gates``. This behavior is now fixed, so that
such already supported instructions are no longer synthesized.
13 changes: 13 additions & 0 deletions test/python/transpiler/test_high_level_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
IGate,
MCXGate,
SGate,
QAOAAnsatz,
)
from qiskit.circuit.library import LinearFunction, PauliEvolutionGate
from qiskit.quantum_info import Clifford, Operator, Statevector, SparsePauliOp
Expand Down Expand Up @@ -664,6 +665,18 @@ def test_synth_fails_definition_exists(self):
out = hls(circuit)
self.assertEqual(out.count_ops(), {"u": 1})

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


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

0 comments on commit b9d5c9c

Please sign in to comment.