Skip to content

Commit

Permalink
Add back qiskit.transpiler.passes.synthesis.graysynth module (#9445) (#…
Browse files Browse the repository at this point in the history
…9446)

* Add back qiskit.transpiler.passes.synthesis.graysynth module

This commit reverts a breaking change made in #8568, in that PR the
graysynth module was moved to the qiskit.synthesis package and the
cnot_synth function was also renamed as part of the move. However, this
change would break any existing users of the module without any warning.
To fix this for the 0.23.0 release this commit adds back the graysynth
module and just exports the contents of the module in its new location.
Additionally, a small wrapper function is added so that the legacy
cnot_synth function name can continue to be used for the time being. In
the 0.24.0 cycle we can deprecate the old module and remove them after
we've giving users a warning about the change.

* Restore root qiskit.transpiler.synthesis exports

* Fix import issues

(cherry picked from commit bf8d6fa)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
  • Loading branch information
mergify[bot] and mtreinish authored Jan 25, 2023
1 parent abb8ce4 commit 9b1dad5
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 4 deletions.
12 changes: 12 additions & 0 deletions qiskit/transpiler/synthesis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,16 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

# pylint: disable=undefined-all-variable

"""Module containing transpiler synthesize."""

import importlib

__all__ = ["graysynth", "cnot_synth"]


def __getattr__(name):
if name in __all__:
return getattr(importlib.import_module(".graysynth", __name__), name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
54 changes: 54 additions & 0 deletions qiskit/transpiler/synthesis/graysynth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

# pylint: disable=unused-wildcard-import, wildcard-import

"""
Implementation of the GraySynth algorithm for synthesizing CNOT-Phase
circuits with efficient CNOT cost, and the Patel-Hayes-Markov algorithm
for optimal synthesis of linear (CNOT-only) reversible circuits.
"""


# Redirect getattrs to modules new location
# TODO: Deprecate in 0.24.0 and remove in 0.26.0
from qiskit.synthesis.linear.graysynth import *


def cnot_synth(state, section_size=2):
"""
Synthesize linear reversible circuits for all-to-all architecture
using Patel, Markov and Hayes method.
This function is an implementation of the Patel, Markov and Hayes algorithm from [1]
for optimal synthesis of linear reversible circuits for all-to-all architecture,
as specified by an n x n matrix.
Args:
state (list[list] or ndarray): n x n boolean invertible matrix, describing the state
of the input circuit
section_size (int): the size of each section, used in the
Patel–Markov–Hayes algorithm [1]. section_size must be a factor of num_qubits.
Returns:
QuantumCircuit: a CX-only circuit implementing the linear transformation.
Raises:
QiskitError: when variable "state" isn't of type numpy.ndarray
References:
1. Patel, Ketan N., Igor L. Markov, and John P. Hayes,
*Optimal synthesis of linear reversible circuits*,
Quantum Information & Computation 8.3 (2008): 282-294.
`arXiv:quant-ph/0302002 [quant-ph] <https://arxiv.org/abs/quant-ph/0302002>`_
"""
return synth_cnot_count_full_pmh(state, section_size=section_size)
16 changes: 12 additions & 4 deletions test/python/synthesis/test_gray_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@

import unittest

import ddt

from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.quantum_info.operators import Operator
from qiskit.extensions.unitary import UnitaryGate
from qiskit.synthesis.linear import graysynth, synth_cnot_count_full_pmh
from qiskit.transpiler.synthesis import cnot_synth # pylint: disable=no-name-in-module
from qiskit.transpiler.synthesis.graysynth import graysynth as legacy_graysynth
from qiskit.test import QiskitTestCase


@ddt.ddt
class TestGraySynth(QiskitTestCase):
"""Test the Gray-Synth algorithm."""

def test_gray_synth(self):
@ddt.data(graysynth, legacy_graysynth)
def test_gray_synth(self, synth_func):
"""Test synthesis of a small parity network via gray_synth.
The algorithm should take the following matrix as an input:
Expand Down Expand Up @@ -66,7 +72,7 @@ def test_gray_synth(self):
[0, 1, 0, 0, 1, 0],
]
angles = ["s", "t", "z", "s", "t", "t"]
c_gray = graysynth(cnots, angles)
c_gray = synth_func(cnots, angles)
unitary_gray = UnitaryGate(Operator(c_gray))

# Create the circuit displayed above:
Expand Down Expand Up @@ -200,11 +206,13 @@ def test_ccz(self):
self.assertEqual(unitary_gray, unitary_compare)


@ddt.ddt
class TestPatelMarkovHayes(QiskitTestCase):
"""Test the Patel-Markov-Hayes algorithm for synthesizing linear
CNOT-only circuits."""

def test_patel_markov_hayes(self):
@ddt.data(cnot_synth, synth_cnot_count_full_pmh)
def test_patel_markov_hayes(self, synth_func):
"""Test synthesis of a small linear circuit
(example from paper, Figure 3).
Expand Down Expand Up @@ -239,7 +247,7 @@ def test_patel_markov_hayes(self):
[1, 1, 0, 1, 1, 1],
[0, 0, 1, 1, 1, 0],
]
c_patel = synth_cnot_count_full_pmh(state)
c_patel = synth_func(state)
unitary_patel = UnitaryGate(Operator(c_patel))

# Create the circuit displayed above:
Expand Down

0 comments on commit 9b1dad5

Please sign in to comment.