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

Deprecate qiskit.extensions #10725

Merged
merged 26 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
29cc524
big moves, import still works
Cryoris Aug 18, 2023
9e000bb
most tests pass (some I cannot seem to run locally)
Cryoris Aug 18, 2023
1afc35c
fix tests -- how to remove DiagonalGate?
Cryoris Aug 18, 2023
5fe1a8b
typehints and docs
Cryoris Aug 22, 2023
4ffea01
more type hints
Cryoris Aug 23, 2023
ec48a1b
Deprecate SQU
Cryoris Aug 23, 2023
90ffaf2
deprecate Snapshot
Cryoris Aug 29, 2023
3a988da
Merge branch 'main' into deprecate-extensions
Cryoris Aug 29, 2023
dd47bde
Fix missing future annotations import
Cryoris Aug 29, 2023
f9112a3
minimize deprecation effort
Cryoris Aug 30, 2023
26e0683
Merge branch 'main' into deprecate-extensions
Cryoris Aug 30, 2023
5f672b7
Change to pending deprecation, no exact-location import supported
Cryoris Sep 4, 2023
53991db
Merge branch 'deprecate-extensions' of github.com:Cryoris/qiskit-terr…
Cryoris Sep 4, 2023
30f787a
Merge branch 'main' into deprecate-extensions
Cryoris Sep 4, 2023
1503f06
fix MCG<->MGC typo and snapshot deprecation
Cryoris Sep 4, 2023
ee7d4d3
Merge branch 'deprecate-extensions' of github.com:Cryoris/qiskit-terr…
Cryoris Sep 4, 2023
9d8915b
fix pylint, try fixing docs
Cryoris Sep 5, 2023
0f97a95
remove gates from extensions toctree
Cryoris Sep 5, 2023
1013c38
Merge branch 'main' into deprecate-extensions
Cryoris Sep 15, 2023
1e7c72e
Add reno, fully deprecate SQU and Snapshot
Cryoris Sep 15, 2023
7b09ab4
Merge branch 'main' into deprecate-extensions
Cryoris Sep 20, 2023
3e92ab3
Apply Sasha's review comments
Cryoris Sep 20, 2023
1accd97
capture snapshot deprecation warning
Cryoris Sep 20, 2023
80ace24
review comments
Cryoris Sep 28, 2023
e2e7807
missed `diagonal` method
Cryoris Sep 28, 2023
4bd902b
Merge branch 'main' into deprecate-extensions
alexanderivrii Sep 28, 2023
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
26 changes: 18 additions & 8 deletions qiskit/assembler/disassemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@
# and a header dictionary.
PulseModule = NewType("PulseModule", Tuple[List[pulse.Schedule], Dict[str, Any], Dict[str, Any]])

# Prevent the disassembler from accessing deprecated circuit methods. This can happen for
# gates where the name of the gate matches a circuit method (e.g. Isometry.name is "isometry")
# and the circuit attribute is also QuantumCircuit.isometry
_DEPRECATED_CIRCUIT_METHODS = [
"isometry",
"snapshot",
"ucrx",
"ucry",
"ucrz",
"squ",
"diagonal",
"hamiltonian",
]


def disassemble(qobj) -> Union[CircuitModule, PulseModule]:
"""Disassemble a qobj and return the circuits or pulse schedules, run_config, and user header.
Expand Down Expand Up @@ -165,16 +179,12 @@ def _experiments_to_circuits(qobj):
clbits.append(creg_dict[clbit_label[0]][clbit_label[1]])
except Exception: # pylint: disable=broad-except
pass
if hasattr(circuit, name):
# TODO remove the check that name is not in the deprecated circuit methods
# once the methods have been removed
if hasattr(circuit, name) and name not in _DEPRECATED_CIRCUIT_METHODS:
Cryoris marked this conversation as resolved.
Show resolved Hide resolved
instr_method = getattr(circuit, name)
if i.name in ["snapshot"]:
_inst = instr_method(
i.label, snapshot_type=i.snapshot_type, qubits=qubits, params=params
)
elif i.name == "initialize":
if i.name == "initialize":
_inst = instr_method(params, qubits)
elif i.name == "isometry":
_inst = instr_method(*params, qubits, clbits)
elif i.name in ["mcx", "mcu1", "mcp"]:
_inst = instr_method(*params, qubits[:-1], qubits[-1], *clbits)
else:
Expand Down
2 changes: 1 addition & 1 deletion qiskit/circuit/add_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from __future__ import annotations

from qiskit.circuit.exceptions import CircuitError
from qiskit.extensions import UnitaryGate
from qiskit.circuit.library import UnitaryGate
from . import ControlledGate, Gate, QuantumRegister, QuantumCircuit
from ._utils import _ctrl_state_to_int

Expand Down
4 changes: 3 additions & 1 deletion qiskit/circuit/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ def power(self, exponent: float):
CircuitError: If Gate is not unitary
"""
from qiskit.quantum_info.operators import Operator # pylint: disable=cyclic-import
from qiskit.extensions.unitary import UnitaryGate # pylint: disable=cyclic-import
from qiskit.circuit.library.generalized_gates import (
UnitaryGate,
) # pylint: disable=cyclic-import
from scipy.linalg import schur

# Should be diagonalized because it's a unitary.
Expand Down
29 changes: 28 additions & 1 deletion qiskit/circuit/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
:template: autosummary/class_no_inherited_members.rst

Diagonal
DiagonalGate
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would've liked to deprecate this as the Diagonal circuit exists, but DiagonalGate seems to be used in the Aer simulators.

Copy link
Member

Choose a reason for hiding this comment

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

imo it should be the circuit that gets removed not the gate, since circuits inherently define an eager synthesis, but that's not important.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, maybe this would best be part of an overhaul to consistently use Gate or Circuits (probably the first) 🙂

Copy link
Member

@ShellyGarion ShellyGarion Sep 11, 2023

Choose a reason for hiding this comment

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

I agree that this is quite confusing. Maybe it's worth to add a comment somewhere about the difference between them, and which one will be deprecated?
(although we also have Permutation and PermutationGate)

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we had the plans to deprecate Permutation circuit once PermutationGate is around. Do you think it's a good idea?

MCMT
MCMTVChain
Permutation
Expand All @@ -195,9 +196,17 @@
MCXGrayCode
MCXRecursive
MCXVChain
MGCupDiag
RVGate
PauliGate
LinearFunction
Isometry
UnitaryGate
UCGate
UCPauliRotGate
UCRXGate
UCRYGate
UCRZGate

Boolean Logic Circuits
======================
Expand Down Expand Up @@ -324,6 +333,7 @@
PhaseOracle
EvolvedOperatorAnsatz
PauliEvolutionGate
HamiltonianGate


N-local circuits
Expand Down Expand Up @@ -360,6 +370,7 @@
ZFeatureMap
ZZFeatureMap
StatePreparation
Initialize

Template circuits
=================
Expand Down Expand Up @@ -492,6 +503,7 @@
from .blueprintcircuit import BlueprintCircuit
from .generalized_gates import (
Diagonal,
DiagonalGate,
MCMT,
MCMTVChain,
Permutation,
Expand All @@ -505,8 +517,17 @@
RVGate,
PauliGate,
LinearFunction,
Isometry,
UnitaryGate,
UCGate,
UCPauliRotGate,
UCRXGate,
UCRYGate,
UCRZGate,
MCGupDiag,
)
ShellyGarion marked this conversation as resolved.
Show resolved Hide resolved
from .pauli_evolution import PauliEvolutionGate
from .hamiltonian_gate import HamiltonianGate
from .boolean_logic import (
AND,
OR,
Expand Down Expand Up @@ -542,7 +563,13 @@
ExcitationPreserving,
QAOAAnsatz,
)
from .data_preparation import PauliFeatureMap, ZFeatureMap, ZZFeatureMap, StatePreparation
from .data_preparation import (
PauliFeatureMap,
ZFeatureMap,
ZZFeatureMap,
StatePreparation,
Initialize,
)
from .quantum_volume import QuantumVolume
from .fourier_checking import FourierChecking
from .graph_state import GraphState
Expand Down
2 changes: 1 addition & 1 deletion qiskit/circuit/library/arithmetic/exact_reciprocal.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from math import isclose
import numpy as np
from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.extensions.quantum_initializer import UCRYGate
from qiskit.circuit.library.generalized_gates import UCRYGate


class ExactReciprocal(QuantumCircuit):
Expand Down
3 changes: 2 additions & 1 deletion qiskit/circuit/library/data_preparation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
from .z_feature_map import ZFeatureMap
from .zz_feature_map import ZZFeatureMap
from .state_preparation import StatePreparation
from .initializer import Initialize

__all__ = ["PauliFeatureMap", "ZFeatureMap", "ZZFeatureMap", "StatePreparation"]
__all__ = ["PauliFeatureMap", "ZFeatureMap", "ZZFeatureMap", "StatePreparation", "Initialize"]
93 changes: 93 additions & 0 deletions qiskit/circuit/library/data_preparation/initializer.py
Cryoris marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# 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.

"""
Initialize qubit registers to desired arbitrary state.
"""

from __future__ import annotations
from collections.abc import Sequence


from qiskit.circuit import QuantumCircuit
from qiskit.circuit import QuantumRegister
from qiskit.circuit import Instruction
from qiskit.circuit.library.data_preparation import StatePreparation
from qiskit.quantum_info import Statevector

_EPS = 1e-10 # global variable used to chop very small numbers to zero


class Initialize(Instruction):
"""Complex amplitude initialization.

Class that initializes some flexible collection of qubit registers, implemented by calling
the :class:`qiskit.extensions.StatePreparation` Class.
alexanderivrii marked this conversation as resolved.
Show resolved Hide resolved
Note that Initialize is an Instruction and not a Gate since it contains a reset instruction,
which is not unitary.
"""

def __init__(
self,
params: Statevector | Sequence[complex] | str | int,
num_qubits: int | None = None,
normalize: bool = False,
) -> None:
r"""
Args:
params: The state to initialize to, can be either of the following.
* Statevector or vector of complex amplitudes to initialize to.
* Labels of basis states of the Pauli eigenstates Z, X, Y. See
:meth:`.Statevector.from_label`. Notice the order of the labels is reversed with
respect to the qubit index to be applied to. Example label '01' initializes the
qubit zero to :math:`|1\rangle` and the qubit one to :math:`|0\rangle`.
* An integer that is used as a bitmap indicating which qubits to initialize to
:math:`|1\rangle`. Example: setting params to 5 would initialize qubit 0 and qubit
2 to :math:`|1\rangle` and qubit 1 to :math:`|0\rangle`.

num_qubits: This parameter is only used if params is an int. Indicates the total
number of qubits in the `initialize` call. Example: `initialize` covers 5 qubits
and params is 3. This allows qubits 0 and 1 to be initialized to :math:`|1\rangle`
and the remaining 3 qubits to be initialized to :math:`|0\rangle`.
normalize: Whether to normalize an input array to a unit vector.
"""
self._stateprep = StatePreparation(params, num_qubits, normalize=normalize)

super().__init__("initialize", self._stateprep.num_qubits, 0, self._stateprep.params)

def _define(self):
q = QuantumRegister(self.num_qubits, "q")
initialize_circuit = QuantumCircuit(q, name="init_def")
initialize_circuit.reset(q)
initialize_circuit.append(self._stateprep, q)
self.definition = initialize_circuit

def gates_to_uncompute(self) -> QuantumCircuit:
"""Call to create a circuit with gates that take the desired vector to zero.

Returns:
Circuit to take ``self.params`` vector to :math:`|{00\\ldots0}\\rangle`
"""
return self._stateprep._gates_to_uncompute()

@property
def params(self):
"""Return initialize params."""
return self._stateprep.params

@params.setter
def params(self, parameters: Statevector | Sequence[complex] | str | int) -> None:
"""Set initialize params."""
self._stateprep.params = parameters

def broadcast_arguments(self, qargs, cargs):
return self._stateprep.broadcast_arguments(qargs, cargs)
2 changes: 1 addition & 1 deletion qiskit/circuit/library/evolved_operator_ansatz.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def preferred_init_points(self):

def _evolve_operator(self, operator, time):
from qiskit.opflow import OperatorBase, EvolutionBase
from qiskit.extensions import HamiltonianGate
from qiskit.circuit.library import HamiltonianGate

if isinstance(operator, OperatorBase):
if not isinstance(self.evolution, EvolutionBase):
Expand Down
6 changes: 4 additions & 2 deletions qiskit/circuit/library/fourier_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.exceptions import CircuitError

from .generalized_gates.diagonal import Diagonal


class FourierChecking(QuantumCircuit):
"""Fourier checking circuit.
Expand Down Expand Up @@ -83,11 +85,11 @@ def __init__(self, f: List[int], g: List[int]) -> None:

circuit.h(circuit.qubits)

circuit.diagonal(f, circuit.qubits)
circuit.compose(Diagonal(f), inplace=True)

circuit.h(circuit.qubits)

circuit.diagonal(g, circuit.qubits)
circuit.compose(Diagonal(g), inplace=True)

circuit.h(circuit.qubits)

Expand Down
10 changes: 9 additions & 1 deletion qiskit/circuit/library/generalized_gates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,19 @@

"""The circuit library module on generalized gates."""

from .diagonal import Diagonal
from .diagonal import Diagonal, DiagonalGate
from .permutation import Permutation, PermutationGate
from .mcmt import MCMT, MCMTVChain
from .gms import GMS, MSGate
from .gr import GR, GRX, GRY, GRZ
from .pauli import PauliGate
from .rv import RVGate
from .linear_function import LinearFunction
from .isometry import Isometry
from .uc import UCGate
from .uc_pauli_rot import UCPauliRotGate
from .ucrx import UCRXGate
from .ucry import UCRYGate
from .ucrz import UCRZGate
from .unitary import UnitaryGate
from .mcg_up_to_diagonal import MCGupDiag
Loading
Loading