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 MCX synthesis plugins #12961

Merged
merged 42 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d3e882c
moving high-level-synthesis plugins to a separate file
alexanderivrii Aug 12, 2024
a64597a
Adding the remaining MCX synthesis functions and exposting all of the…
alexanderivrii Aug 12, 2024
e548257
adding entry points for MCX plugins
alexanderivrii Aug 12, 2024
dccd30f
adding documentation section for MCX plugins
alexanderivrii Aug 13, 2024
d5458ce
renaming file
alexanderivrii Aug 13, 2024
014b8a2
Adding pending deprecation warnings
alexanderivrii Aug 13, 2024
cab6cb5
placeholder for MCX plugin tests
alexanderivrii Aug 13, 2024
a79e2f9
adding flag pending=True to deprecate
alexanderivrii Aug 13, 2024
364cf75
changing checks from isinstance to name-based: a CCCX gate is called …
alexanderivrii Aug 13, 2024
bc4238c
merging main
alexanderivrii Aug 14, 2024
fa94424
futher exposing C3X and C4X synthesis
alexanderivrii Aug 14, 2024
306361f
updating MCX synthesis functions to avoid returning C3X and C4X gates
alexanderivrii Aug 15, 2024
e54706b
fix compose to append
alexanderivrii Aug 15, 2024
c3c1927
renaming synthesized circuits for c3x and for c4x back to 'mcx' to av…
alexanderivrii Aug 15, 2024
b21f3ea
test qasm fixes
alexanderivrii Aug 15, 2024
f0f3de9
randomly spotted typo
alexanderivrii Aug 15, 2024
01d76b2
fixing how QuantumCircuit.decompose works in the presence of gates_to…
alexanderivrii Aug 15, 2024
d739065
updating MCX plugins to check isinstance
alexanderivrii Aug 15, 2024
d856c88
fixing test
alexanderivrii Aug 15, 2024
08051f3
pylint fixes
alexanderivrii Aug 15, 2024
d73d941
properly fixing test
alexanderivrii Aug 15, 2024
73d4502
additional tests
alexanderivrii Aug 16, 2024
4135344
adding new synthesis functions to synthesis docs
alexanderivrii Aug 16, 2024
efb55c2
release notes
alexanderivrii Aug 16, 2024
b6702c5
docstrings improvements followin review
alexanderivrii Aug 16, 2024
247d414
Adding refernce to Vale et al paper for the MCXPhase gate implementation
alexanderivrii Aug 18, 2024
458c10d
fixes to deprecation warnings and adding deprecation for get_num_anci…
alexanderivrii Aug 18, 2024
055e365
docstring fixes
alexanderivrii Aug 18, 2024
6bb46d5
renaming mcphase to v24
alexanderivrii Aug 20, 2024
e5cd0b8
removing unncessary checks
alexanderivrii Aug 20, 2024
d6226b9
addressing the rest of review comments
alexanderivrii Aug 20, 2024
9278d26
and of course updating qasm checking after we've slightly changed the…
alexanderivrii Aug 20, 2024
3879cdd
yet another renaming
alexanderivrii Aug 20, 2024
1c05061
Update qiskit/circuit/library/standard_gates/x.py
alexanderivrii Aug 20, 2024
40228f0
Update qiskit/circuit/library/standard_gates/x.py
alexanderivrii Aug 20, 2024
0649bc9
Update releasenotes/notes/add-mcx-plugins-85e5b248692a36db.yaml
alexanderivrii Aug 20, 2024
5a8ba64
release notes
alexanderivrii Aug 20, 2024
5422990
formatting
alexanderivrii Aug 20, 2024
e0765ec
fixing docs
alexanderivrii Aug 21, 2024
5f14493
Merge branch 'main' into mcx-plugins
alexanderivrii Aug 21, 2024
82586cb
removing references from the first sentence of plugin descriptions
alexanderivrii Aug 22, 2024
c0746ec
Merge branch 'mcx-plugins' of github.com:alexanderivrii/qiskit-terra …
alexanderivrii Aug 22, 2024
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
Prev Previous commit
Next Next commit
yet another renaming
  • Loading branch information
alexanderivrii committed Aug 20, 2024
commit 3879cdd6fed85083b8f6b73a7529438c63a0fb56
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ sk = "qiskit.transpiler.passes.synthesis.solovay_kitaev_synthesis:SolovayKitaevS
"mcx.n_clean_m15" = "qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisNCleanM15"
"mcx.1_clean_b95" = "qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesis1CleanB95"
"mcx.gray_code" = "qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisGrayCode"
"mcx.v24" = "qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisV24"
"mcx.noaux_v24" = "qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisNoAuxV24"
"mcx.default" = "qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisDefault"
"permutation.default" = "qiskit.transpiler.passes.synthesis.hls_plugins:BasicSynthesisPermutation"
"permutation.kms" = "qiskit.transpiler.passes.synthesis.hls_plugins:KMSSynthesisPermutation"
Expand Down
4 changes: 2 additions & 2 deletions qiskit/circuit/library/standard_gates/x.py
Original file line number Diff line number Diff line change
Expand Up @@ -1199,9 +1199,9 @@ def get_num_ancilla_qubits(num_ctrl_qubits: int, mode: str = "noancilla") -> int
def _define(self):
"""This definition is based on MCPhaseGate implementation."""
# pylint: disable=cyclic-import
from qiskit.synthesis.multi_controlled import synth_mcx_v24
from qiskit.synthesis.multi_controlled import synth_mcx_noaux_v24

qc = synth_mcx_v24(self.num_ctrl_qubits)
qc = synth_mcx_noaux_v24(self.num_ctrl_qubits)
self.definition = qc

@property
Expand Down
4 changes: 2 additions & 2 deletions qiskit/synthesis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
.. autofunction:: synth_mcx_n_dirty_i15
.. autofunction:: synth_mcx_n_clean_m15
.. autofunction:: synth_mcx_1_clean_b95
.. autofunction:: synth_mcx_v24
.. autofunction:: synth_mcx_noaux_v24
.. autofunction:: synth_mcx_gray_code
.. autofunction:: synth_c3x
.. autofunction:: synth_c4x
Expand Down Expand Up @@ -188,7 +188,7 @@
synth_mcx_n_dirty_i15,
synth_mcx_n_clean_m15,
synth_mcx_1_clean_b95,
synth_mcx_v24,
synth_mcx_noaux_v24,
synth_mcx_gray_code,
synth_c3x,
synth_c4x,
alexanderivrii marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
2 changes: 1 addition & 1 deletion qiskit/synthesis/multi_controlled/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
synth_mcx_n_clean_m15,
synth_mcx_1_clean_b95,
synth_mcx_gray_code,
synth_mcx_v24,
synth_mcx_noaux_v24,
synth_c3x,
synth_c4x,
)
2 changes: 1 addition & 1 deletion qiskit/synthesis/multi_controlled/mcx_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def synth_mcx_gray_code(num_ctrl_qubits: int) -> QuantumCircuit:
return qc


def synth_mcx_v24(num_ctrl_qubits: int) -> QuantumCircuit:
def synth_mcx_noaux_v24(num_ctrl_qubits: int) -> QuantumCircuit:
r"""
Synthesize a multi-controlled X gate with :math:`k` controls based on
the implementation for MCPhaseGate.
Expand Down
16 changes: 8 additions & 8 deletions qiskit/transpiler/passes/synthesis/hls_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@
- `0`
- `0`
- exponentially many CX gates; use only for small values of `k`
* - ``"v24"``
- :class:`~.MCXSynthesisV24`
* - ``"noaux_v24"``
- :class:`~.MCXSynthesisNoAuxV24`
- `0`
- `0`
- quadratic number of CX gates; use instead of ``"gray_code"`` for large values of `k`
Expand Down Expand Up @@ -209,7 +209,7 @@
:toctree: ../stubs/

MCXSynthesisGrayCode
MCXSynthesisV24
MCXSynthesisNoAuxV24
MCXSynthesisNCleanM15
MCXSynthesisNDirtyI15
MCXSynthesis1CleanB95
Expand Down Expand Up @@ -252,7 +252,7 @@
synth_mcx_n_clean_m15,
synth_mcx_1_clean_b95,
synth_mcx_gray_code,
synth_mcx_v24,
synth_mcx_noaux_v24,
)
from qiskit.transpiler.passes.routing.algorithms import ApproximateTokenSwapper
from .plugin import HighLevelSynthesisPlugin
Expand Down Expand Up @@ -839,11 +839,11 @@ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **
return decomposition


class MCXSynthesisV24(HighLevelSynthesisPlugin):
class MCXSynthesisNoAuxV24(HighLevelSynthesisPlugin):
r"""Synthesis plugin for a multi-controlled X gate based on the
implementation for MCPhaseGate, which is in turn based on [1].

This plugin name is :``mcx.v24`` which can be used as the key on
This plugin name is :``mcx.noaux_v24`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k` control qubits this synthesis
Expand All @@ -867,7 +867,7 @@ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **
return None

num_ctrl_qubits = high_level_object.num_ctrl_qubits
decomposition = synth_mcx_v24(num_ctrl_qubits)
decomposition = synth_mcx_noaux_v24(num_ctrl_qubits)
return decomposition


Expand Down Expand Up @@ -911,4 +911,4 @@ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **
) is not None:
return decomposition

return MCXSynthesisV24().run(high_level_object, coupling_map, target, qubits, **options)
return MCXSynthesisNoAuxV24().run(high_level_object, coupling_map, target, qubits, **options)
4 changes: 2 additions & 2 deletions releasenotes/notes/add-mcx-plugins-85e5b248692a36db.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
features_synthesis:
- |
Added synthesis functions :func:`.synth_mcx_gray_code` and :func:`.synth_mcx_v24`
Added synthesis functions :func:`.synth_mcx_gray_code` and :func:`.synth_mcx_noaux_v24`
that synthesize multi-controlled X gates. These functions do not require additional
ancilla qubits.
- |
Expand All @@ -14,7 +14,7 @@ features_transpiler:
* :class:`.MCXSynthesisNCleanM15`, based on :func:`.synth_mcx_n_clean_m15`.
* :class:`.MCXSynthesisNDirtyI15`, based on :func:`.synth_mcx_n_dirty_i15`.
* :class:`.MCXSynthesis1CleanB95`, based on :func:`.synth_mcx_1_clean_b95`.
* :class:`.MCXSynthesisV24`, based on :func:`.synth_mcx_v24`.
* :class:`.MCXSynthesisNoAuxV24`, based on :func:`.synth_mcx_noaux_v24`.
* :class:`.MCXSynthesisGrayCode`, based on :func:`.synth_mcx_gray_code`.

As well:
Expand Down
14 changes: 7 additions & 7 deletions test/python/transpiler/test_high_level_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
MCXSynthesisNDirtyI15,
MCXSynthesisGrayCode,
MCXSynthesisDefault,
MCXSynthesisV24,
MCXSynthesisNoAuxV24,
)
from qiskit.circuit.annotated_operation import (
AnnotatedOperation,
Expand Down Expand Up @@ -2372,14 +2372,14 @@ def test_mcx_plugins_applicability(self):
)
self.assertIsNone(decomposition)

with self.subTest(method="v24", num_clean_ancillas=1, num_dirty_ancillas=1):
with self.subTest(method="noaux_v24", num_clean_ancillas=1, num_dirty_ancillas=1):
# should have a decomposition
decomposition = MCXSynthesisV24().run(gate, num_clean_ancillas=1, num_dirty_ancillas=1)
decomposition = MCXSynthesisNoAuxV24().run(gate, num_clean_ancillas=1, num_dirty_ancillas=1)
self.assertIsNotNone(decomposition)

with self.subTest(method="v24", num_clean_ancillas=0, num_dirty_ancillas=0):
with self.subTest(method="noaux_v24", num_clean_ancillas=0, num_dirty_ancillas=0):
# should have a decomposition
decomposition = MCXSynthesisV24().run(gate, num_clean_ancillas=0, num_dirty_ancillas=0)
decomposition = MCXSynthesisNoAuxV24().run(gate, num_clean_ancillas=0, num_dirty_ancillas=0)
self.assertIsNotNone(decomposition)

with self.subTest(method="gray_code", num_clean_ancillas=1, num_dirty_ancillas=1):
Expand Down Expand Up @@ -2410,7 +2410,7 @@ def test_mcx_plugins_applicability(self):
)
self.assertIsNotNone(decomposition)

@data("n_clean_m15", "n_dirty_i15", "1_clean_b95", "v24", "gray_code", "default")
@data("n_clean_m15", "n_dirty_i15", "1_clean_b95", "noaux_v24", "gray_code", "default")
def test_mcx_plugins_correctness_from_arbitrary(self, mcx_plugin_name):
"""Test that all plugins return a correct Operator when qubits are not
initially zero."""
Expand All @@ -2425,7 +2425,7 @@ def test_mcx_plugins_correctness_from_arbitrary(self, mcx_plugin_name):
qct = hls_pass(qc)
self.assertEqual(Operator(qc), Operator(qct))

@data("n_clean_m15", "n_dirty_i15", "1_clean_b95", "v24", "gray_code", "default")
@data("n_clean_m15", "n_dirty_i15", "1_clean_b95", "noaux_v24", "gray_code", "default")
def test_mcx_plugins_correctness_from_zero(self, mcx_plugin_name):
"""Test that all plugins return a correct Statevector when qubits are
initially zero."""
Expand Down
Loading