mirror of https://github.com/Qiskit/qiskit.git
Adding HLS plugins for linear functions and cliffords (#9399)
* Adding barebone HLS plugins for linear functions and cliffods * adding clifford.lnn method and improving docstrings * improving release notes with table and example * docstring improvements following review
This commit is contained in:
parent
5bd188b1c9
commit
625f3fc783
|
@ -15,13 +15,25 @@
|
|||
|
||||
|
||||
from qiskit.converters import circuit_to_dag
|
||||
from qiskit.synthesis import synth_permutation_basic, synth_permutation_acg
|
||||
from qiskit.transpiler.basepasses import TransformationPass
|
||||
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
||||
from qiskit.transpiler.exceptions import TranspilerError
|
||||
from qiskit.synthesis import synth_clifford_full
|
||||
from qiskit.synthesis.linear import synth_cnot_count_full_pmh
|
||||
from qiskit.synthesis.permutation import synth_permutation_depth_lnn_kms
|
||||
|
||||
from qiskit.synthesis.clifford import (
|
||||
synth_clifford_full,
|
||||
synth_clifford_layers,
|
||||
synth_clifford_depth_lnn,
|
||||
synth_clifford_greedy,
|
||||
synth_clifford_ag,
|
||||
synth_clifford_bm,
|
||||
)
|
||||
from qiskit.synthesis.linear import synth_cnot_count_full_pmh, synth_cnot_depth_line_kms
|
||||
from qiskit.synthesis.permutation import (
|
||||
synth_permutation_basic,
|
||||
synth_permutation_acg,
|
||||
synth_permutation_depth_lnn_kms,
|
||||
)
|
||||
|
||||
from .plugin import HighLevelSynthesisPluginManager, HighLevelSynthesisPlugin
|
||||
|
||||
|
||||
|
@ -189,7 +201,15 @@ class HighLevelSynthesis(TransformationPass):
|
|||
|
||||
|
||||
class DefaultSynthesisClifford(HighLevelSynthesisPlugin):
|
||||
"""The default clifford synthesis plugin."""
|
||||
"""The default clifford synthesis plugin.
|
||||
|
||||
For N <= 3 qubits this is the optimal CX cost decomposition by Bravyi, Maslov.
|
||||
For N > 3 qubits this is done using the general non-optimal greedy compilation
|
||||
routine from reference by Bravyi, Hu, Maslov, Shaydulin.
|
||||
|
||||
This plugin name is :``clifford.default`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Clifford."""
|
||||
|
@ -197,8 +217,114 @@ class DefaultSynthesisClifford(HighLevelSynthesisPlugin):
|
|||
return decomposition
|
||||
|
||||
|
||||
class AGSynthesisClifford(HighLevelSynthesisPlugin):
|
||||
"""Clifford synthesis plugin based on the Aaronson-Gottesman method.
|
||||
|
||||
This plugin name is :``clifford.ag`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Clifford."""
|
||||
decomposition = synth_clifford_ag(high_level_object)
|
||||
return decomposition
|
||||
|
||||
|
||||
class BMSynthesisClifford(HighLevelSynthesisPlugin):
|
||||
"""Clifford synthesis plugin based on the Bravyi-Maslov method.
|
||||
The plugin is named
|
||||
|
||||
The method only works on Cliffords with at most 3 qubits, for which it
|
||||
constructs the optimal CX cost decomposition.
|
||||
|
||||
This plugin name is :``clifford.bm`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Clifford."""
|
||||
if high_level_object.num_qubits <= 3:
|
||||
decomposition = synth_clifford_bm(high_level_object)
|
||||
else:
|
||||
decomposition = None
|
||||
return decomposition
|
||||
|
||||
|
||||
class GreedySynthesisClifford(HighLevelSynthesisPlugin):
|
||||
"""Clifford synthesis plugin based on the greedy synthesis
|
||||
Bravyi-Hu-Maslov-Shaydulin method.
|
||||
|
||||
This plugin name is :``clifford.greedy`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Clifford."""
|
||||
decomposition = synth_clifford_greedy(high_level_object)
|
||||
return decomposition
|
||||
|
||||
|
||||
class LayerSynthesisClifford(HighLevelSynthesisPlugin):
|
||||
"""Clifford synthesis plugin based on the Bravyi-Maslov method
|
||||
to synthesize Cliffords into layers.
|
||||
|
||||
This plugin name is :``clifford.layers`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Clifford."""
|
||||
decomposition = synth_clifford_layers(high_level_object)
|
||||
return decomposition
|
||||
|
||||
|
||||
class LayerLnnSynthesisClifford(HighLevelSynthesisPlugin):
|
||||
"""Clifford synthesis plugin based on the Bravyi-Maslov method
|
||||
to synthesize Cliffords into layers, with each layer synthesized
|
||||
adhering to LNN connectivity.
|
||||
|
||||
This plugin name is :``clifford.lnn`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Clifford."""
|
||||
decomposition = synth_clifford_depth_lnn(high_level_object)
|
||||
return decomposition
|
||||
|
||||
|
||||
class DefaultSynthesisLinearFunction(HighLevelSynthesisPlugin):
|
||||
"""The default linear function synthesis plugin."""
|
||||
"""The default linear function synthesis plugin.
|
||||
|
||||
This plugin name is :``linear_function.default`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given LinearFunction."""
|
||||
decomposition = synth_cnot_count_full_pmh(high_level_object.linear)
|
||||
return decomposition
|
||||
|
||||
|
||||
class KMSSynthesisLinearFunction(HighLevelSynthesisPlugin):
|
||||
"""Linear function synthesis plugin based on the Kutin-Moulton-Smithline method.
|
||||
|
||||
This plugin name is :``linear_function.kms`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given LinearFunction."""
|
||||
decomposition = synth_cnot_depth_line_kms(high_level_object.linear)
|
||||
return decomposition
|
||||
|
||||
|
||||
class PMHSynthesisLinearFunction(HighLevelSynthesisPlugin):
|
||||
"""Linear function synthesis plugin based on the Patel-Markov-Hayes method.
|
||||
|
||||
This plugin name is :``linear_function.pmh`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given LinearFunction."""
|
||||
|
@ -207,7 +333,11 @@ class DefaultSynthesisLinearFunction(HighLevelSynthesisPlugin):
|
|||
|
||||
|
||||
class KMSSynthesisPermutation(HighLevelSynthesisPlugin):
|
||||
"""The permutation synthesis plugin based on the Kutin, Moulton, Smithline method."""
|
||||
"""The permutation synthesis plugin based on the Kutin, Moulton, Smithline method.
|
||||
|
||||
This plugin name is :``permutation.kms`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Permutation."""
|
||||
|
@ -216,7 +346,11 @@ class KMSSynthesisPermutation(HighLevelSynthesisPlugin):
|
|||
|
||||
|
||||
class BasicSynthesisPermutation(HighLevelSynthesisPlugin):
|
||||
"""The permutation synthesis plugin based on sorting."""
|
||||
"""The permutation synthesis plugin based on sorting.
|
||||
|
||||
This plugin name is :``permutation.basic`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Permutation."""
|
||||
|
@ -225,7 +359,11 @@ class BasicSynthesisPermutation(HighLevelSynthesisPlugin):
|
|||
|
||||
|
||||
class ACGSynthesisPermutation(HighLevelSynthesisPlugin):
|
||||
"""The permutation synthesis plugin based on the Alon, Chung, Graham method."""
|
||||
"""The permutation synthesis plugin based on the Alon, Chung, Graham method.
|
||||
|
||||
This plugin name is :``permutation.acg`` which can be used as the key on
|
||||
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
||||
"""
|
||||
|
||||
def run(self, high_level_object, **options):
|
||||
"""Run synthesis for the given Permutation."""
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Added high-level-synthesis plugins for :class:`.LinearFunction` and for
|
||||
:class:`qiskit.quantum_info.Clifford`, extending the set of synthesis
|
||||
methods that can be called from :class:`~qiskit.transpiler.passes.HighLevelSynthesis`
|
||||
transpiler pass.
|
||||
|
||||
For :class:`.LinearFunction` the available plugins are listed below:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Plugin name
|
||||
- High-level synthesis plugin
|
||||
* - ``default``
|
||||
- :class:`.DefaultSynthesisLinearFunction`
|
||||
* - ``kms``
|
||||
- :class:`.KMSSynthesisLinearFunction`
|
||||
* - ``pmh``
|
||||
- :class:`.PMHSynthesisLinearFunction`
|
||||
|
||||
For :class:`qiskit.quantum_info.Clifford` the available plugins are listed below:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Plugin name
|
||||
- High-level synthesis plugin
|
||||
* - ``default``
|
||||
- :class:`.DefaultSynthesisClifford`
|
||||
* - ``ag``
|
||||
- :class:`.AGSynthesisClifford`
|
||||
* - ``bm``
|
||||
- :class:`.BMSynthesisClifford`
|
||||
* - ``greedy``
|
||||
- :class:`.GreedySynthesisClifford`
|
||||
* - ``layers``
|
||||
- :class:`.LayerSynthesisClifford`
|
||||
* - ``lnn``
|
||||
- :class:`.LayerLnnSynthesisClifford`
|
||||
|
||||
Please refer to :mod:`qiskit.synthesis` documentation for more information
|
||||
about each individual method.
|
||||
|
||||
The following example illustrates some of the new plugins::
|
||||
|
||||
from qiskit.circuit import QuantumCircuit
|
||||
from qiskit.circuit.library import LinearFunction
|
||||
from qiskit.quantum_info import Clifford
|
||||
from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig, HighLevelSynthesis
|
||||
|
||||
# Create a quantum circuit with one linear function and one clifford
|
||||
qc1 = QuantumCircuit(3)
|
||||
qc1.cx(0, 1)
|
||||
qc1.swap(0, 2)
|
||||
lin_fun = LinearFunction(qc1)
|
||||
|
||||
qc2 = QuantumCircuit(3)
|
||||
qc2.h(0)
|
||||
qc2.cx(0, 2)
|
||||
cliff = Clifford(qc2)
|
||||
|
||||
qc = QuantumCircuit(4)
|
||||
qc.append(lin_fun, [0, 1, 2])
|
||||
qc.append(cliff, [1, 2, 3])
|
||||
|
||||
# Choose synthesis methods that adhere to linear-nearest-neighbour connectivity
|
||||
hls_config = HLSConfig(linear_function=["kms"], clifford=["lnn"])
|
||||
|
||||
# Synthesize
|
||||
qct = HighLevelSynthesis(hls_config)(qc)
|
||||
print(qct.decompose())
|
||||
|
||||
|
7
setup.py
7
setup.py
|
@ -117,7 +117,14 @@ setup(
|
|||
],
|
||||
"qiskit.synthesis": [
|
||||
"clifford.default = qiskit.transpiler.passes.synthesis.high_level_synthesis:DefaultSynthesisClifford",
|
||||
"clifford.ag = qiskit.transpiler.passes.synthesis.high_level_synthesis:AGSynthesisClifford",
|
||||
"clifford.bm = qiskit.transpiler.passes.synthesis.high_level_synthesis:BMSynthesisClifford",
|
||||
"clifford.greedy = qiskit.transpiler.passes.synthesis.high_level_synthesis:GreedySynthesisClifford",
|
||||
"clifford.layers = qiskit.transpiler.passes.synthesis.high_level_synthesis:LayerSynthesisClifford",
|
||||
"clifford.lnn = qiskit.transpiler.passes.synthesis.high_level_synthesis:LayerLnnSynthesisClifford",
|
||||
"linear_function.default = qiskit.transpiler.passes.synthesis.high_level_synthesis:DefaultSynthesisLinearFunction",
|
||||
"linear_function.kms = qiskit.transpiler.passes.synthesis.high_level_synthesis:KMSSynthesisLinearFunction",
|
||||
"linear_function.pmh = qiskit.transpiler.passes.synthesis.high_level_synthesis:PMHSynthesisLinearFunction",
|
||||
"permutation.default = qiskit.transpiler.passes.synthesis.high_level_synthesis:BasicSynthesisPermutation",
|
||||
"permutation.kms = qiskit.transpiler.passes.synthesis.high_level_synthesis:KMSSynthesisPermutation",
|
||||
"permutation.basic = qiskit.transpiler.passes.synthesis.high_level_synthesis:BasicSynthesisPermutation",
|
||||
|
|
Loading…
Reference in New Issue