Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding HLS plugins for linear functions and cliffords #9399

Merged
merged 7 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 86 additions & 7 deletions qiskit/transpiler/passes/synthesis/high_level_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@


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_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


Expand Down Expand Up @@ -156,16 +167,75 @@ def run(self, dag: DAGCircuit) -> DAGCircuit:


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.
"""

def run(self, high_level_object, **options):
"""Run synthesis for the given Clifford."""
decomposition = synth_clifford_full(high_level_object)
return decomposition


class DefaultSynthesisLinearFunction(HighLevelSynthesisPlugin):
"""The default linear function synthesis plugin."""
class AGSynthesisClifford(HighLevelSynthesisPlugin):
"""Clifford synthesis plugin based on the Aaronson-Gottesman method."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to say explicitly in the docstring here (and for the other plugin classes) that the name of this plugin is "ag" so that users know how to specify the plugin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in a91f5d2.


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 method only works on Cliffords with at most 3 qubits, for which it
constructs the optimal CX cost decomposition.
"""

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."""

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."""

def run(self, high_level_object, **options):
"""Run synthesis for the given Clifford."""
decomposition = synth_clifford_layers(high_level_object)
return decomposition


class KMSSynthesisLinearFunction(HighLevelSynthesisPlugin):
"""Linear function synthesis plugin based on the Kutin-Moulton-Smithline method."""

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."""

def run(self, high_level_object, **options):
"""Run synthesis for the given LinearFunction."""
Expand All @@ -182,6 +252,15 @@ def run(self, high_level_object, **options):
return decomposition


class DefaultSynthesisLinearFunction(HighLevelSynthesisPlugin):
"""The default linear function synthesis plugin."""

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 BasicSynthesisPermutation(HighLevelSynthesisPlugin):
"""The permutation synthesis plugin based on sorting."""

Expand Down
14 changes: 14 additions & 0 deletions releasenotes/notes/add-hls-plugins-038388970ad43c55.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
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 newly available plugins are
:class:`.PMHSynthesisLinearFunction` and :class:`.KMSSynthesisLinearFunction`.
For :class:`qiskit.quantum_info.Clifford` the newly available plugins are
:class:`.AGSynthesisClifford`, :class:`.BMSynthesisClifford`,
:class:`.GreedySynthesisClifford` and :class:`.LayerSynthesisClifford`.
Please refer to :mod:`qiskit.synthesis` documentation for more information
about each individual method.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a table or something that maps the plugin names to the methods? I think that'll be good for users so they know what the plugin names are going to be. Also having an example of how to use it with transpile would go a long way too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 0dbcf31.

6 changes: 6 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,13 @@
],
"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.layer = qiskit.transpiler.passes.synthesis.high_level_synthesis:LayerSynthesisClifford",
"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",
Expand Down