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

Clean-up Wires object usage across source code #6689

Merged
merged 53 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
6a6f0b5
fix: Update PauliX operator
andrijapau Dec 9, 2024
1c572ac
fix: PauliError channel
andrijapau Dec 9, 2024
0276a0f
Revert "fix: PauliError channel"
andrijapau Dec 9, 2024
018ec06
fix: Remove wires=None from channel.py
andrijapau Dec 9, 2024
1e23082
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 9, 2024
0cd6957
fix: Update test_default_mixed_autograd.py for new PauliError signature
andrijapau Dec 9, 2024
0576be0
fix: Update test_default_mixed_jax.py for new PauliError signature
andrijapau Dec 9, 2024
34ec719
fix: Update test_default_mixed_tf.py for new PauliError signature
andrijapau Dec 9, 2024
e6c2b16
fix: Update test_default_mixed_torch.py for new PauliError signature
andrijapau Dec 9, 2024
ada9b98
fix: Update test_default_clifford.py for new PauliError signature
andrijapau Dec 9, 2024
cba441c
fix: Update test_default_mixed_jax.py for new PauliError signature
andrijapau Dec 9, 2024
0c5a37e
fix: Update test_default_mixed_tf.py for new PauliError signature
andrijapau Dec 9, 2024
9769340
fix: Update test_default_mixed_torch.py for new PauliError signature
andrijapau Dec 9, 2024
cf5a69c
fix: Update PCPhase operator to disallow wires=None and adjust test_q…
andrijapau Dec 9, 2024
b43e1a9
fix: Remove ', *,' from signatures I changed :)
andrijapau Dec 9, 2024
654873e
fix: Disallow wires=None in ClassicalShadowMP in classical_shadow.py
andrijapau Dec 9, 2024
2aa2907
fix: Disallow wires=None from Identity and GlobalPhase
andrijapau Dec 9, 2024
c5d5c81
fix: Revert changes to tests/devices/
andrijapau Dec 9, 2024
8af5e07
fix: Revert changes to test_qsvt.py
andrijapau Dec 9, 2024
610643a
fix: Update pauli_arithmetic.py to disallow wire_order=None
andrijapau Dec 9, 2024
e42d29f
feat: Add type hinting to MultiControlledX
andrijapau Dec 10, 2024
bb05f87
feat: Add type hinting to WireCut
andrijapau Dec 10, 2024
0e3e0b2
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 16, 2024
061a988
fix: More updates
andrijapau Dec 16, 2024
7349983
fix: Update tests
andrijapau Dec 16, 2024
99ef3f1
fix: Update classical_shadow.py
andrijapau Dec 17, 2024
aac11f2
fix: Update MultiControlledX in controlled_ops.py
andrijapau Dec 17, 2024
893a9f7
fix: Update qft.py
andrijapau Dec 17, 2024
3781691
fix: Update grover.py
andrijapau Dec 17, 2024
12b82d2
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 17, 2024
5e0e85b
fix: Improve coverage on qft.py
andrijapau Dec 17, 2024
6d696bb
fix: Update controlled.py
andrijapau Dec 18, 2024
69b2eb9
fix: Update meta.py to remove unnecessary pylint disable
andrijapau Dec 19, 2024
e95ee22
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 19, 2024
885421c
fix: Update grover.py
andrijapau Dec 19, 2024
5586497
fix: Update grover.py
andrijapau Dec 19, 2024
080da37
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 19, 2024
0e39ee9
fix: clean up controlled_*.py
andrijapau Dec 19, 2024
5fe2e84
fix: clean up phase_adder.py
andrijapau Dec 19, 2024
b6e306a
fix: further clean-up in controlled.py
andrijapau Dec 19, 2024
fe8d4a5
Revert "fix: further clean-up in controlled.py"
andrijapau Dec 19, 2024
153984c
fix: Update controlled_ops.py
andrijapau Dec 19, 2024
d0e252f
fix: Update controlled_ops.py
andrijapau Dec 19, 2024
4d7633b
Revert "fix: Update controlled_ops.py"
andrijapau Dec 19, 2024
67b1276
Revert "fix: Update controlled_ops.py"
andrijapau Dec 19, 2024
6839d94
Revert "fix: clean up controlled_*.py"
andrijapau Dec 19, 2024
3ab6174
Update pennylane/ops/meta.py
andrijapau Dec 20, 2024
49336ae
Revert "Update pennylane/ops/meta.py"
andrijapau Dec 20, 2024
6455bfb
fix: Update qft.py to not need n_wires
andrijapau Dec 20, 2024
b9c568d
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 20, 2024
0c9d0dc
fix: Update WireCut __init__ in meta.py
andrijapau Dec 20, 2024
4395eb8
Merge branch 'master' into remove-wires-eq-none
andrijapau Dec 20, 2024
7c3a7d9
doc: Update changelog-dev.md
andrijapau Dec 20, 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
3 changes: 3 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ such as `shots`, `rng` and `prng_key`.

<h4>Other Improvements</h4>

* `Wires` object usage across Pennylane source code has been tidied up.
[(#6689)](https://github.com/PennyLaneAI/pennylane/pull/6689)

* `qml.equal` now supports `PauliWord` and `PauliSentence` instances.
[(#6703)](https://github.com/PennyLaneAI/pennylane/pull/6703)

Expand Down
9 changes: 6 additions & 3 deletions pennylane/measurements/classical_shadow.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import pennylane as qml
from pennylane.operation import Operator
from pennylane.wires import Wires
from pennylane.wires import Wires, WiresLike

from .measurements import MeasurementShapeError, MeasurementTransform, Shadow, ShadowExpval

Expand Down Expand Up @@ -89,7 +89,7 @@ def circuit(x, obs):
return ShadowExpvalMP(H=H, seed=seed, k=k)


def classical_shadow(wires, seed=None):
def classical_shadow(wires: WiresLike, seed=None):
"""
The classical shadow measurement protocol.

Expand Down Expand Up @@ -227,7 +227,10 @@ class ClassicalShadowMP(MeasurementTransform):
"""

def __init__(
self, wires: Optional[Wires] = None, seed: Optional[int] = None, id: Optional[str] = None
self,
wires: Optional[WiresLike] = None,
seed: Optional[int] = None,
id: Optional[str] = None,
):
self.seed = seed
super().__init__(wires=wires, id=id)
Expand Down
13 changes: 9 additions & 4 deletions pennylane/ops/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from pennylane import math as np
from pennylane.operation import AnyWires, Channel
from pennylane.wires import Wires, WiresLike


class AmplitudeDamping(Channel):
Expand Down Expand Up @@ -58,7 +59,8 @@
num_wires = 1
grad_method = "F"

def __init__(self, gamma, wires, id=None):
def __init__(self, gamma, wires: WiresLike, id=None):
wires = Wires(wires)
super().__init__(gamma, wires=wires, id=id)

@staticmethod
Expand Down Expand Up @@ -563,7 +565,8 @@
num_params = 2
"""int: Number of trainable parameters that the operator depends on."""

def __init__(self, operators, p, wires=None, id=None):
def __init__(self, operators, p, wires: WiresLike, id=None):
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
wires = Wires(wires)
super().__init__(operators, p, wires=wires, id=id)

# check if the specified operators are legal
Expand Down Expand Up @@ -713,7 +716,8 @@
num_wires = AnyWires
grad_method = None

def __init__(self, K_list, wires=None, id=None):
def __init__(self, K_list, wires: WiresLike, id=None):
wires = Wires(wires)
super().__init__(*K_list, wires=wires, id=id)

# check all Kraus matrices are square matrices
Expand Down Expand Up @@ -744,7 +748,8 @@

# pylint: disable=arguments-differ, unused-argument
@classmethod
def _primitive_bind_call(cls, K_list, wires=None, id=None):
def _primitive_bind_call(cls, K_list, wires: WiresLike, id=None):
wires = Wires(wires)
return super()._primitive_bind_call(*K_list, wires=wires)

@staticmethod
Expand Down Expand Up @@ -858,7 +863,7 @@
id (str or None): String representing the operation (optional)
"""

num_params = 4

Check notice on line 866 in pennylane/ops/channel.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane/ops/channel.py#L866

Too many positional arguments (7/5) (too-many-positional-arguments)
num_wires = 1
grad_method = "F"

Expand Down
23 changes: 14 additions & 9 deletions pennylane/ops/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
Operation,
SparseMatrixUndefinedError,
)
from pennylane.wires import WiresLike


class Identity(CVObservable, Operation):
Expand Down Expand Up @@ -61,15 +62,16 @@ class Identity(CVObservable, Operation):
ev_order = 1

@classmethod
def _primitive_bind_call(cls, wires=None, **kwargs): # pylint: disable=arguments-differ
wires = [] if wires is None else wires
def _primitive_bind_call(
cls, wires: WiresLike = (), **kwargs
): # pylint: disable=arguments-differ
return super()._primitive_bind_call(wires=wires, **kwargs)

def _flatten(self):
return tuple(), (self.wires, tuple())

def __init__(self, wires=None, id=None):
super().__init__(wires=[] if wires is None else wires, id=id)
def __init__(self, wires: WiresLike = (), id=None):
super().__init__(wires=wires, id=id)
self._hyperparameters = {"n_wires": len(self.wires)}
self._pauli_rep = qml.pauli.PauliSentence({qml.pauli.PauliWord({}): 1.0})

Expand Down Expand Up @@ -308,12 +310,13 @@ def circuit():
grad_method = None

@classmethod
def _primitive_bind_call(cls, phi, wires=None, **kwargs): # pylint: disable=arguments-differ
wires = [] if wires is None else wires
def _primitive_bind_call(
cls, phi, wires: WiresLike = (), **kwargs
): # pylint: disable=arguments-differ
return super()._primitive_bind_call(phi, wires=wires, **kwargs)

def __init__(self, phi, wires=None, id=None):
super().__init__(phi, wires=[] if wires is None else wires, id=id)
def __init__(self, phi, wires: WiresLike = (), id=None):
super().__init__(phi, wires=wires, id=id)

@staticmethod
def compute_eigvals(phi, n_wires=1): # pylint: disable=arguments-differ
Expand Down Expand Up @@ -412,7 +415,9 @@ def compute_diagonalizing_gates(
return []

@staticmethod
def compute_decomposition(phi, wires=None): # pylint:disable=arguments-differ,unused-argument
def compute_decomposition(
phi, wires: WiresLike = ()
): # pylint:disable=arguments-differ,unused-argument
r"""Representation of the operator as a product of other operators (static method).

.. note::
Expand Down
17 changes: 7 additions & 10 deletions pennylane/ops/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import pennylane as qml
from pennylane.operation import AnyWires, Operation
from pennylane.wires import Wires # pylint: disable=unused-import
from pennylane.wires import Wires, WiresLike


class Barrier(Operation):
Expand All @@ -46,7 +46,8 @@ class Barrier(Operation):
num_wires = AnyWires
par_domain = None

def __init__(self, wires=Wires([]), only_visual=False, id=None):
def __init__(self, wires: WiresLike = (), only_visual=False, id=None):
wires = Wires(wires)
self.only_visual = only_visual
self.hyperparameters["only_visual"] = only_visual
super().__init__(wires=wires, id=id)
Expand Down Expand Up @@ -119,16 +120,12 @@ class WireCut(Operation):
num_wires = AnyWires
grad_method = None

def __init__(self, *params, wires=None, id=None):
if wires == []:
raise ValueError(
f"{self.__class__.__name__}: wrong number of wires. "
f"At least one wire has to be given."
)
super().__init__(*params, wires=wires, id=id)
def __init__(self, wires: WiresLike = (), id=None):
wires = Wires(wires)
super().__init__(wires=wires, id=id)

@staticmethod
def compute_decomposition(wires): # pylint: disable=unused-argument
def compute_decomposition(wires: WiresLike): # pylint: disable=unused-argument
r"""Representation of the operator as a product of other operators (static method).

Since this operator is a placeholder inside a circuit, it decomposes into an empty list.
Expand Down
15 changes: 11 additions & 4 deletions pennylane/ops/op_math/controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from pennylane.capture.capture_diff import create_non_interpreted_prim
from pennylane.compiler import compiler
from pennylane.operation import Operator
from pennylane.wires import Wires
from pennylane.wires import Wires, WiresLike

from .controlled_decompositions import ctrl_decomp_bisect, ctrl_decomp_zyz
from .symbolicop import SymbolicOp
Expand Down Expand Up @@ -175,7 +175,7 @@
# Flatten nested controlled operations to a multi-controlled operation for better
# decomposition algorithms. This includes special cases like CRX, CRot, etc.
if isinstance(op, Controlled):
work_wires = work_wires or []
work_wires = () if work_wires is None else work_wires
return ctrl(
op.base,
control=control + op.control_wires,
Expand Down Expand Up @@ -480,7 +480,7 @@

# pylint: disable=arguments-differ
@classmethod
def _primitive_bind_call(

Check notice on line 483 in pennylane/ops/op_math/controlled.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane/ops/op_math/controlled.py#L483

Too many positional arguments (6/5) (too-many-positional-arguments)
cls, base, control_wires, control_values=None, work_wires=None, id=None
):
control_wires = Wires(control_wires)
Expand All @@ -489,9 +489,16 @@
)

# pylint: disable=too-many-function-args
def __init__(self, base, control_wires, control_values=None, work_wires=None, id=None):
def __init__(

Check notice on line 492 in pennylane/ops/op_math/controlled.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane/ops/op_math/controlled.py#L492

Too many positional arguments (6/5) (too-many-positional-arguments)
self,
base,
control_wires: WiresLike,
control_values=None,
work_wires: WiresLike = None,
id=None,
):
control_wires = Wires(control_wires)
work_wires = Wires([]) if work_wires is None else Wires(work_wires)
work_wires = Wires(() if work_wires is None else work_wires)

if control_values is None:
control_values = [True] * len(control_wires)
Expand Down Expand Up @@ -918,7 +925,7 @@
# check the grad_recipe validity
if self.grad_recipe is None:
# Make sure grad_recipe is an iterable of correct length instead of None
self.grad_recipe = [None] * self.num_params

Check notice on line 928 in pennylane/ops/op_math/controlled.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane/ops/op_math/controlled.py#L928

Too many positional arguments (6/5) (too-many-positional-arguments)

@property
def name(self):
Expand Down
33 changes: 21 additions & 12 deletions pennylane/ops/op_math/controlled_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,16 @@ def _primitive_bind_call(cls, wires, control_values=None, work_wires=None, id=No
)

# pylint: disable=too-many-arguments
def __init__(self, control_wires=None, wires=None, control_values=None, work_wires=None):
def __init__(
self,
control_wires: WiresLike = (),
wires: WiresLike = (),
control_values=None,
work_wires: WiresLike = (),
):
control_wires = Wires(() if control_wires is None else control_wires)
wires = Wires(() if wires is None else wires)
work_wires = Wires(() if work_wires is None else work_wires)

# First raise deprecation warnings regardless of the validity of other arguments
if isinstance(control_values, str):
Expand All @@ -1164,22 +1173,19 @@ def __init__(self, control_wires=None, wires=None, control_values=None, work_wir
"supported in future releases, Use a list of booleans or integers instead.",
qml.PennyLaneDeprecationWarning,
)
if control_wires is not None:
if len(control_wires) > 0:
warnings.warn(
"The control_wires keyword for MultiControlledX is deprecated, and will "
"be removed soon. Use wires = (*control_wires, target_wire) instead.",
UserWarning,
)

if wires is None:
if len(wires) == 0:
raise ValueError("Must specify the wires where the operation acts on")

wires = wires if isinstance(wires, Wires) else Wires(wires)

if control_wires is not None:
if len(control_wires) > 0:
if len(wires) != 1:
raise ValueError("MultiControlledX accepts a single target wire.")
control_wires = Wires(control_wires)
else:
if len(wires) < 2:
raise ValueError(
Expand Down Expand Up @@ -1212,7 +1218,7 @@ def wires(self):

# pylint: disable=unused-argument, arguments-differ
@staticmethod
def compute_matrix(control_wires, control_values=None, **kwargs):
def compute_matrix(control_wires: WiresLike, control_values=None, **kwargs):
r"""Representation of the operator as a canonical matrix in the computational basis (static method).

The canonical matrix is the textbook matrix representation that does not consider wires.
Expand Down Expand Up @@ -1255,7 +1261,9 @@ def matrix(self, wire_order=None):

# pylint: disable=unused-argument, arguments-differ
@staticmethod
def compute_decomposition(wires=None, work_wires=None, control_values=None, **kwargs):
def compute_decomposition(
wires: WiresLike = None, work_wires: WiresLike = None, control_values=None, **kwargs
):
r"""Representation of the operator as a product of other operators (static method).

.. math:: O = O_1 O_2 \dots O_n.
Expand All @@ -1282,6 +1290,7 @@ def compute_decomposition(wires=None, work_wires=None, control_values=None, **kw
Toffoli(wires=[0, 1, 'aux'])]

"""
wires = Wires(() if wires is None else wires)

if len(wires) < 2:
raise ValueError(f"Wrong number of wires. {len(wires)} given. Need at least 2.")
Expand Down Expand Up @@ -1357,7 +1366,7 @@ class CRX(ControlledOp):
name = "CRX"
parameter_frequencies = [(0.5, 1.0)]

def __init__(self, phi, wires, id=None):
def __init__(self, phi, wires: WiresLike, id=None):
# We use type.__call__ instead of calling the class directly so that we don't bind the
# operator primitive when new program capture is enabled
base = type.__call__(qml.RX, phi, wires=wires[1:])
Expand All @@ -1374,7 +1383,7 @@ def _unflatten(cls, data, metadata):
return cls(*data, wires=metadata[0])

@classmethod
def _primitive_bind_call(cls, phi, wires, id=None):
def _primitive_bind_call(cls, phi, wires: WiresLike, id=None):
return cls._primitive.bind(phi, *wires, n_wires=len(wires))

@staticmethod
Expand Down Expand Up @@ -1425,7 +1434,7 @@ def compute_matrix(theta): # pylint: disable=arguments-differ
return qml.math.stack([stack_last(row) for row in matrix], axis=-2)

@staticmethod
def compute_decomposition(phi, wires): # pylint: disable=arguments-differ
def compute_decomposition(phi, wires: WiresLike): # pylint: disable=arguments-differ
r"""Representation of the operator as a product of other operators (static method). :

.. math:: O = O_1 O_2 \dots O_n.
Expand Down
2 changes: 1 addition & 1 deletion pennylane/ops/qubit/non_parametric_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def pauli_rep(self):
)
return self._pauli_rep

def __init__(self, wires: Optional[WiresLike] = None, id: Optional[str] = None):
def __init__(self, wires: WiresLike, id: Optional[str] = None):
super().__init__(wires=wires, id=id)

def label(
Expand Down
2 changes: 1 addition & 1 deletion pennylane/ops/qubit/parametric_ops_multi_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ def compute_eigvals(*params: TensorLike, **hyperparams) -> TensorLike:

@staticmethod
def compute_decomposition(
*params: TensorLike, wires: Optional[WiresLike] = None, **hyperparams
*params: TensorLike, wires: WiresLike, **hyperparams
) -> list["qml.operation.Operator"]:
r"""Representation of the operator as a product of other operators (static method).

Expand Down
6 changes: 3 additions & 3 deletions pennylane/pauli/pauli_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from pennylane import math
from pennylane.ops import Identity, PauliX, PauliY, PauliZ, Prod, SProd, Sum
from pennylane.typing import TensorLike
from pennylane.wires import Wires
from pennylane.wires import Wires, WiresLike

I = "I"
X = "X"
Expand Down Expand Up @@ -504,7 +504,7 @@ def _get_csr_indices(self, wire_order):
current_size *= 2
return indices

def operation(self, wire_order=None):
def operation(self, wire_order: WiresLike = ()):
"""Returns a native PennyLane :class:`~pennylane.operation.Operation` representing the PauliWord."""
if len(self) == 0:
return Identity(wires=wire_order)
Expand Down Expand Up @@ -1001,7 +1001,7 @@ def _sum_different_structure_pws(indices, data):
matrix.eliminate_zeros()
return matrix

def operation(self, wire_order=None):
def operation(self, wire_order: WiresLike = ()):
"""Returns a native PennyLane :class:`~pennylane.operation.Operation` representing the PauliSentence."""
if len(self) == 0:
return qml.s_prod(0, Identity(wires=wire_order))
Expand Down
Loading
Loading