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 23 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
20 changes: 10 additions & 10 deletions docs/legacy_release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3619,7 +3619,7 @@ Bug Fixes
.. releasenotes/notes/0.24/qasm2-exporter-rewrite-8993dd24f930b180.yaml @ b'4152009ee6d1bae8704f1e7b9ccc5727a53933bd'

- The OpenQASM 2 exporter (:meth:`.QuantumCircuit.qasm`) will now handle multiple and nested
definitions of :class:`.UnitaryGate`. See
definitions of :class:`~.library.UnitaryGate`. See
`#4623 <https://github.com/Qiskit/qiskit-terra/issues/4623>`__,
`#6712 <https://github.com/Qiskit/qiskit-terra/issues/6712>`__,
`#7772 <https://github.com/Qiskit/qiskit-terra/issues/7772>`__, and
Expand Down Expand Up @@ -5123,7 +5123,7 @@ New Features
library gate classes have been updated to return more specific
gate objects that result in a less lossy and more efficient output.
For example, running :meth:`~.IGate.power` now returns an :class:`~.IGate`
instance instead of :class:`~.UnitaryGate` as was done previously.
instance instead of :class:`~.library.UnitaryGate` as was done previously.

The full list of output types that have been improved are:

Expand Down Expand Up @@ -9148,7 +9148,7 @@ Bug Fixes
.. releasenotes/notes/0.22/fix-qasm2-identity-as-unitary-aa2feeb05707a597.yaml @ b'618770367f7a5a3a22fd43ea9fcfb7f17393eb6a'

- The OpenQASM 2 exporter (:meth:`.QuantumCircuit.qasm`) will now correctly
define the qubit parameters for :class:`.UnitaryGate` operations that do
define the qubit parameters for :class:`~.library.UnitaryGate` operations that do
not affect all the qubits they are defined over.
Fixed `#8224 <https://github.com/Qiskit/qiskit-terra/issues/8224>`__.

Expand Down Expand Up @@ -9372,7 +9372,7 @@ Known Issues
.. releasenotes/notes/0.11/non-x86_ibm_cpu-493e51313ba222a6.yaml @ b'b7c4a322f8409fc2809b57b0701d1da6717c7efd'

- When running on Linux s390x platforms (or other big endian platforms)
running circuits that contain :class:`~.UnitaryGate` operations will not
running circuits that contain :class:`~.library.UnitaryGate` operations will not
work because of an endianess bug.
See `#1506 <https://github.com/Qiskit/qiskit-aer/issues/1506>`__ for more
details.
Expand Down Expand Up @@ -9692,7 +9692,7 @@ Bug Fixes
.. releasenotes/notes/fix-evolvedop-to-instruction-c90c4f1aa6b4232a.yaml @ b'664747a66e2199a4b20abb9b7180cccb12c61a3f'

- Fix :meth:`~.EvolvedOp.to_instruction` which previously tried to create a
:class:`~.UnitaryGate` without exponentiating the operator to evolve.
:class:`~.library.UnitaryGate` without exponentiating the operator to evolve.
Since this operator is generally not unitary, this raised an error (and if
the operator would have been unitary by chance, it would not have been the expected result).

Expand Down Expand Up @@ -10076,7 +10076,7 @@ New Features
Shannon Decomposition of arbitrary unitaries. This functionality replaces
the previous isometry-based approach in the default unitary synthesis
transpiler pass as well as when adding unitaries to a circuit using a
:class:`.UnitaryGate`.
:class:`~.library.UnitaryGate`.

The Quantum Shannon Decomposition uses about half the cnot gates as the
isometry implementation when decomposing unitary matrices of greater than
Expand Down Expand Up @@ -10732,7 +10732,7 @@ Bug Fixes
.. releasenotes/notes/fix-qasm2-identity-as-unitary-aa2feeb05707a597.yaml @ b'd7f932c8b242f69c5577afd5593bf36f839657f7'

- The OpenQASM 2 exporter (:meth:`.QuantumCircuit.qasm`) will now correctly
define the qubit parameters for :class:`.UnitaryGate` operations that do
define the qubit parameters for :class:`~.library.UnitaryGate` operations that do
not affect all the qubits they are defined over.
Fixed `#8224 <https://github.com/Qiskit/qiskit-terra/issues/8224>`__.

Expand Down Expand Up @@ -10914,10 +10914,10 @@ Known Issues
.. releasenotes/notes/ucr-gates-qpy-b8f6fb1e34fae258.yaml @ b'625b202a4dd0c223579dca44eec530b8a0813d76'

- QPY deserialization with the :func:`.qpy.load` function of a directly
instantiated :class:`~.UCPauliRotGate` object in a circuit will fail
instantiated :class:`~.library.UCPauliRotGate` object in a circuit will fail
because the rotation axis argument to the class isn't stored in a standard
place. To workaround this you can instead use the subclasses:
:class:`~.UCRXGate`, :class:`~.UCRYGate`, or :class:`~.UCRZGate` (based on
:class:`~.library.UCRXGate`, :class:`~.library.UCRYGate`, or :class:`~.library.UCRZGate` (based on
whether you're using a rotation axis of ``"X"``, ``"Y"``, or ``"Z"``
respectively) which embeds the rotation axis in the class constructor and
will work correctly in QPY.
Expand Down Expand Up @@ -11016,7 +11016,7 @@ Bug Fixes
.. releasenotes/notes/ucr-gates-qpy-b8f6fb1e34fae258.yaml @ b'625b202a4dd0c223579dca44eec530b8a0813d76'

- Fixed an issue with QPY deserialization via the :func:`.qpy.load` function
of the :class:`~.UCRXGate`, :class:`~.UCRYGate`, and :class:`~.UCRZGate`
of the :class:`~.library.UCRXGate`, :class:`~.library.UCRYGate`, and :class:`~.library.UCRZGate`
classes.
Previously, a QPY file that contained any of these gates would error
when trying to load the file.
Expand Down
6 changes: 3 additions & 3 deletions docs/migration_guides/opflow_migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1004,8 +1004,8 @@ delayed synthesis of the gates or efficient transpilation of the circuits, so th
(for example, :class:`~qiskit.algorithms.time_evolvers.trotterization.TrotterQRTE`\).

In a similar manner, the :class:`qiskit.opflow.evolutions.MatrixEvolution` class performs evolution by classical matrix exponentiation,
constructing a circuit with :class:`.UnitaryGate`\s or :class:`.HamiltonianGate`\s containing the exponentiation of the operator.
This class is no longer necessary, as the :class:`.HamiltonianGate`\s can be directly handled by the algorithms.
constructing a circuit with :class:`~.library.UnitaryGate`\s or :class:`~.library.HamiltonianGate`\s containing the exponentiation of the operator.
This class is no longer necessary, as the :class:`~.library.HamiltonianGate`\s can be directly handled by the algorithms.

Trotterizations
---------------
Expand Down Expand Up @@ -1046,7 +1046,7 @@ Other Evolution Classes
- No direct replacement. The workflow no longer requires a specific operator for evolutions.

* - :class:`~qiskit.opflow.evolutions.MatrixEvolution`
- :class:`.HamiltonianGate`
- :class:`~.library.HamiltonianGate`

* - :class:`~qiskit.opflow.evolutions.PauliTrotterEvolution`
- :class:`.PauliEvolutionGate`
Expand Down
3 changes: 0 additions & 3 deletions qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@
# user config
from qiskit import user_config as _user_config

# The qiskit.extensions.x imports needs to be placed here due to the
# mechanism for adding gates dynamically.
import qiskit.extensions
alexanderivrii marked this conversation as resolved.
Show resolved Hide resolved
Comment on lines -69 to -71
Copy link
Member

Choose a reason for hiding this comment

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

Removing this in conjunction with all the rest of the work on removing uses of qiskit.extensions actually was a bit of a breaking change, because qiskit.extensions is no longer available just by having done import qiskit. In other words:

import qiskit

qiskit.extensions.CXGate

would have worked without error before, and now it'll say

AttributeError: module 'qiskit' has no attribute 'extensions'

and require you to do import qiskit.extensions.

That's minor and we can probably get away with it, but it was a dedicated submodule that was previously automatically imported, so just pointing out that these removals can cause issues.

import qiskit.circuit.measure
import qiskit.circuit.reset

Expand Down
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
8 changes: 5 additions & 3 deletions qiskit/circuit/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ def power(self, exponent: float):
exponent (float): Gate^exponent

Returns:
qiskit.extensions.UnitaryGate: To which `to_matrix` is self.to_matrix^exponent.
.library.UnitaryGate: To which `to_matrix` is self.to_matrix^exponent.

Raises:
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
# pylint: disable=cyclic-import
from qiskit.quantum_info.operators import Operator
from qiskit.circuit.library.generalized_gates.unitary import UnitaryGate

from scipy.linalg import schur

# Should be diagonalized because it's a unitary.
Expand Down
27 changes: 26 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 @@ -198,6 +199,13 @@
RVGate
PauliGate
LinearFunction
Isometry
UnitaryGate
UCGate
UCPauliRotGate
UCRXGate
UCRYGate
UCRZGate

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


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

Template circuits
=================
Expand Down Expand Up @@ -492,6 +502,7 @@
from .blueprintcircuit import BlueprintCircuit
from .generalized_gates import (
Diagonal,
DiagonalGate,
MCMT,
MCMTVChain,
Permutation,
Expand All @@ -505,8 +516,16 @@
RVGate,
PauliGate,
LinearFunction,
Isometry,
UnitaryGate,
UCGate,
UCPauliRotGate,
UCRXGate,
UCRYGate,
UCRZGate,
)
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 +561,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"]
96 changes: 96 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,96 @@
# 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
import typing

from qiskit.circuit.quantumcircuit import QuantumCircuit
from qiskit.circuit.quantumregister import QuantumRegister
from qiskit.circuit.instruction import Instruction
from .state_preparation import StatePreparation

if typing.TYPE_CHECKING:
from qiskit.quantum_info.states.statevector 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:`~.library.StatePreparation` class.
Note that ``Initialize`` is an :class:`~.circuit.Instruction` and not a :class:`.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)
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
import numpy as np

from qiskit.exceptions import QiskitError
from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit
from qiskit.circuit.quantumcircuit import QuantumCircuit
from qiskit.circuit.quantumregister import QuantumRegister, Qubit
from qiskit.circuit.gate import Gate
from qiskit.circuit.library.standard_gates.x import CXGate, XGate
from qiskit.circuit.library.standard_gates.h import HGate
from qiskit.circuit.library.standard_gates.s import SGate, SdgGate
from qiskit.circuit.library.standard_gates.ry import RYGate
from qiskit.circuit.library.standard_gates.rz import RZGate
from qiskit.circuit.exceptions import CircuitError
from qiskit.quantum_info import Statevector
from qiskit.quantum_info.states.statevector import Statevector # pylint: disable=cyclic-import

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

Expand Down
Loading