Skip to content

Commit

Permalink
Remove decomp_depth from qml.device constructor (#6234)
Browse files Browse the repository at this point in the history
The `decomp_depth` keyword argument only served to prevent operations
from being fully decomposed to the target gateset. It is now removed.


[sc-72706]

---------

Co-authored-by: Astral Cai <astral.cai@xanadu.ai>
Co-authored-by: Mudit Pandey <mudit.pandey@xanadu.ai>
  • Loading branch information
3 people authored Sep 17, 2024
1 parent a40e3e7 commit 2d8cd54
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 114 deletions.
10 changes: 5 additions & 5 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ Pending deprecations
- Deprecated in v0.39
- Will be removed in v0.40

* The ``decomp_depth`` argument in ``qml.device`` is deprecated.

- Deprecated in v0.38
- Will be removed in v0.39

* The ``simplify`` argument in ``qml.Hamiltonian`` and ``qml.ops.LinearCombination`` is deprecated.
Instead, ``qml.simplify()`` can be called on the constructed operator.

Expand Down Expand Up @@ -106,6 +101,11 @@ Other deprecations
Completed deprecation cycles
----------------------------

* The ``decomp_depth`` argument in ``qml.device`` is removed.

- Deprecated in v0.38
- Removed in v0.39

* The functions ``qml.qinfo.classical_fisher`` and ``qml.qinfo.quantum_fisher`` have been removed and migrated to the ``qml.gradients``
module. Therefore, ``qml.gradients.classical_fisher`` and ``qml.gradients.quantum_fisher`` should be used instead.

Expand Down
3 changes: 3 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
Please use `qml.transforms.split_non_commuting` instead.
[(#6204)](https://github.com/PennyLaneAI/pennylane/pull/6204)

* The `decomp_depth` keyword argument to `qml.device` is removed.
[(#6234)](https://github.com/PennyLaneAI/pennylane/pull/6234)

* `Operator.expand` is now removed. Use `qml.tape.QuantumScript(op.deocomposition())` instead.
[(#6227)](https://github.com/PennyLaneAI/pennylane/pull/6227)

Expand Down
43 changes: 13 additions & 30 deletions pennylane/devices/device_constructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"""
This module contains code for the main device construction delegation logic.
"""
import warnings
from importlib import metadata
from sys import version_info

Expand Down Expand Up @@ -57,8 +56,7 @@ def refresh_devices():

# pylint: disable=protected-access
def device(name, *args, **kwargs):
r"""
Load a device and return the instance.
r"""Load a device and return the instance.
This function is used to load a particular quantum device,
which can then be used to construct QNodes.
Expand Down Expand Up @@ -105,12 +103,6 @@ def device(name, *args, **kwargs):
that contains global and/or device specific configurations.
custom_decomps (Dict[Union(str, Operator), Callable]): Custom
decompositions to be applied by the device at runtime.
decomp_depth (int): For when custom decompositions are specified,
the maximum expansion depth used by the expansion function.
.. warning::
The ``decomp_depth`` argument is deprecated and will be removed in version 0.39.
All devices must be loaded by specifying their **short-name** as listed above,
followed by the **wires** (subsystems) you wish to initialize. The ``wires``
Expand All @@ -122,10 +114,10 @@ def device(name, *args, **kwargs):
dev = qml.device('default.qubit', wires=5)
def circuit():
qml.Hadamard(wires=1)
qml.Hadamard(wires=[0])
qml.CNOT(wires=[3, 4])
...
qml.Hadamard(wires=1)
qml.Hadamard(wires=[0])
qml.CNOT(wires=[3, 4])
...
The ``wires`` argument can also be a sequence of unique numbers or strings, specifying custom wire labels
that the user employs to address the wires:
Expand All @@ -135,10 +127,10 @@ def circuit():
dev = qml.device('default.qubit', wires=['ancilla', 'q11', 'q12', -1, 1])
def circuit():
qml.Hadamard(wires='q11')
qml.Hadamard(wires=['ancilla'])
qml.CNOT(wires=['q12', -1])
...
qml.Hadamard(wires='q11')
qml.Hadamard(wires=['ancilla'])
qml.CNOT(wires=['q12', -1])
...
On some newer devices, such as ``default.qubit``, the ``wires`` argument can be omitted altogether,
and instead the wires will be computed when executing a circuit depending on its contents.
Expand All @@ -157,8 +149,8 @@ def circuit():
@qml.qnode(dev)
def circuit(a):
qml.RX(a, wires=0)
return qml.sample(qml.Z(0))
qml.RX(a, wires=0)
return qml.sample(qml.Z(0))
>>> circuit(0.8) # 10 samples are returned
array([ 1, 1, 1, 1, -1, 1, 1, -1, 1, 1])
Expand Down Expand Up @@ -243,15 +235,6 @@ def run_cnot():
# Pop the custom decomposition keyword argument; we will use it here
# only and not pass it to the device.
custom_decomps = kwargs.pop("custom_decomps", None)
decomp_depth = kwargs.pop("decomp_depth", None)

if decomp_depth is not None:
warnings.warn(
"The decomp_depth argument is deprecated and will be removed in version 0.39. ",
qml.PennyLaneDeprecationWarning,
)
else:
decomp_depth = 10

kwargs.pop("config", None)
options.update(kwargs)
Expand Down Expand Up @@ -284,12 +267,12 @@ def _safe_specifier_set(version_str):
if custom_decomps is not None:
if isinstance(dev, qml.devices.LegacyDevice):
custom_decomp_expand_fn = qml.transforms.create_decomp_expand_fn(
custom_decomps, dev, decomp_depth=decomp_depth
custom_decomps, dev, decomp_depth=10
)
dev.custom_expand(custom_decomp_expand_fn)
else:
custom_decomp_preprocess = qml.transforms.tape_expand._create_decomp_preprocessing(
custom_decomps, dev, decomp_depth=decomp_depth
custom_decomps, dev, decomp_depth=10
)
dev.preprocess = custom_decomp_preprocess

Expand Down
9 changes: 0 additions & 9 deletions tests/devices/test_legacy_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -1074,15 +1074,6 @@ def test_shot_vector_property(self):

assert dev.shots.total_shots == 22

def test_decomp_depth_is_deprecated(self):
"""Test that a warning is raised when using the deprecated decomp_depth argument"""

with pytest.warns(
qml.PennyLaneDeprecationWarning,
match="The decomp_depth argument is deprecated",
):
qml.device("default.qubit", decomp_depth=1)


class TestBatchExecution:
"""Tests for the batch_execute method."""
Expand Down
70 changes: 0 additions & 70 deletions tests/transforms/test_tape_expand.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,30 +539,6 @@ def circuit():

assert decomp_ops[2].name == "CNOT"

@pytest.mark.parametrize("device_name", ["default.qubit", "default.qubit.legacy"])
def test_no_decomp_with_depth_zero(self, device_name):
"""Test that specifying a single custom decomposition works as expected."""

custom_decomps = {"Hadamard": custom_hadamard, "CNOT": custom_cnot}
with pytest.warns(
qml.PennyLaneDeprecationWarning, match="The decomp_depth argument is deprecated"
):
decomp_dev = qml.device(
device_name, wires=2, custom_decomps=custom_decomps, decomp_depth=0
)

@qml.qnode(decomp_dev)
def circuit():
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
return qml.expval(qml.PauliZ(0))

decomp_ops = qml.workflow.construct_batch(circuit, level=None)()[0][0].operations

assert len(decomp_ops) == 2
assert decomp_ops[0].name == "Hadamard"
assert decomp_ops[1].name == "CNOT"

@pytest.mark.parametrize("device_name", ["default.qubit", "default.qubit.legacy"])
def test_one_custom_decomp_gradient(self, device_name):
"""Test that gradients are still correctly computed after a decomposition
Expand Down Expand Up @@ -713,52 +689,6 @@ def circuit():
assert decomp_ops[4].name == "CNOT"
assert decomp_ops[4].wires == Wires([0, 1])

@pytest.mark.parametrize("device_name", ["default.qubit", "default.qubit.legacy"])
def test_custom_decomp_different_depth(self, device_name):
"""Test that alternative expansion depths can be specified."""

# BasicEntanglerLayers custom decomposition involves AngleEmbedding. If
# expansion depth is 2, the AngleEmbedding will still be decomposed into
# RX (since it's not a supported operation on the device), but the RX will
# not be further decomposed even though the custom decomposition is specified.
custom_decomps = {"BasicEntanglerLayers": custom_basic_entangler_layers, "RX": custom_rx}

with pytest.warns(
qml.PennyLaneDeprecationWarning, match="The decomp_depth argument is deprecated"
):
decomp_dev_2 = qml.device(
device_name, wires=2, custom_decomps=custom_decomps, decomp_depth=2
)

decomp_dev_3 = qml.device(
device_name, wires=2, custom_decomps=custom_decomps, decomp_depth=3
)

def circuit():
qml.BasicEntanglerLayers([[0.1, 0.2]], wires=[0, 1])
return qml.expval(qml.PauliZ(0))

circuit2 = qml.QNode(circuit, decomp_dev_2)
circuit3 = qml.QNode(circuit, decomp_dev_3)

decomp_ops = qml.workflow.construct_batch(circuit2, level=None)()[0][0].operations

assert len(decomp_ops) == 3

assert decomp_ops[0].name == "RX"
assert np.isclose(decomp_ops[0].parameters[0], 0.1)
assert decomp_ops[0].wires == Wires(0)

assert decomp_ops[1].name == "RX"
assert np.isclose(decomp_ops[1].parameters[0], 0.2)
assert decomp_ops[1].wires == Wires(1)

assert decomp_ops[2].name == "CNOT"
assert decomp_ops[2].wires == Wires([0, 1])

decomp_ops = qml.workflow.construct_batch(circuit3, level=None)()[0][0].operations
assert len(decomp_ops) == 5

@pytest.mark.parametrize("device_name", ["default.qubit", "default.qubit.legacy"])
def test_custom_decomp_with_adjoint(self, device_name):
"""Test that applying an adjoint in the circuit results in the adjoint
Expand Down

0 comments on commit 2d8cd54

Please sign in to comment.