Skip to content

Commit

Permalink
Fix qft-plugins for custom 'qft' gates (Qiskit#13181)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderivrii authored Sep 19, 2024
1 parent 4c64a64 commit 2245a4f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
22 changes: 16 additions & 6 deletions qiskit/transpiler/passes/synthesis/hls_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,10 @@ class QFTSynthesisFull(HighLevelSynthesisPlugin):
This plugin name is :``qft.full`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Note that the plugin mechanism is not applied if the gate is called ``qft`` but
is not an instance of ``QFTGate``. This allows users to create custom gates with
name ``qft``.
The plugin supports the following additional options:
* reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
Expand Down Expand Up @@ -532,10 +536,11 @@ class QFTSynthesisFull(HighLevelSynthesisPlugin):

def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
"""Run synthesis for the given QFTGate."""

# Even though the gate is called "qft", it's not a QFTGate,
# and we should not synthesize it using the plugin.
if not isinstance(high_level_object, QFTGate):
raise TranspilerError(
"The synthesis plugin 'qft.full` only applies to objects of type QFTGate."
)
return None

reverse_qubits = options.get("reverse_qubits", False)
approximation_degree = options.get("approximation_degree", 0)
Expand All @@ -560,6 +565,10 @@ class QFTSynthesisLine(HighLevelSynthesisPlugin):
This plugin name is :``qft.line`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Note that the plugin mechanism is not applied if the gate is called ``qft`` but
is not an instance of ``QFTGate``. This allows users to create custom gates with
name ``qft``.
The plugin supports the following additional options:
* reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
Expand All @@ -584,10 +593,11 @@ class QFTSynthesisLine(HighLevelSynthesisPlugin):

def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
"""Run synthesis for the given QFTGate."""

# Even though the gate is called "qft", it's not a QFTGate,
# and we should not synthesize it using the plugin.
if not isinstance(high_level_object, QFTGate):
raise TranspilerError(
"The synthesis plugin 'qft.line` only applies to objects of type QFTGate."
)
return None

reverse_qubits = options.get("reverse_qubits", False)
approximation_degree = options.get("approximation_degree", 0)
Expand Down
9 changes: 9 additions & 0 deletions releasenotes/notes/fix-qft-plugins-7106029d33c44b96.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
The ``HighLevelSynthesis`` transpiler pass no longer raises an exception when
encountering a custom gate that is called "qft" but is not an instance of
:class:`~qiskit.circuit.library.QFTGate`. Instead, the synthesis plugins for
QFT gates ignore such a gate, and the gate's definition is used (if provided).
16 changes: 16 additions & 0 deletions test/python/transpiler/test_high_level_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -2309,6 +2309,22 @@ def test_qft_line_plugin_annotated_qft(self, qft_plugin_name):
qct = hls_pass(qc)
self.assertEqual(Operator(qc), Operator(qct))

@data("line", "full")
def test_skip_non_qft(self, qft_plugin_name):
"""Test that synthesis plugins are not applied on gates that are called `qft`, yet
that are not of type `QFTGate`.
"""
qc = QuantumCircuit(1)
qc2 = QuantumCircuit(1, name="qft")
qc2.s(0)
qc.append(qc2.to_instruction(), qc.qregs[0])
hls_config = HLSConfig(qft=[qft_plugin_name])
hls_pass = HighLevelSynthesis(hls_config=hls_config)
qct = hls_pass(qc)
# HighLevelSynthesis should replace the custom gate called "qft"
# by the user-provided definition.
self.assertEqual(Operator(qc2), Operator(qct))


@ddt
class TestMCXSynthesisPlugins(QiskitTestCase):
Expand Down

0 comments on commit 2245a4f

Please sign in to comment.