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

Update transforms documentation #4682

Merged
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
f0253fb
Update deprecations page
trbromley Oct 16, 2023
98559a3
Update deprecation warning
trbromley Oct 16, 2023
3696f6c
Merge branch 'master' into sc-38900-the-transform-module-docstrings-a…
rmoyard Oct 19, 2023
de9f264
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
rmoyard Oct 19, 2023
e2d7b96
Gradient transforms update
rmoyard Oct 19, 2023
38ea389
Gradient transforms update
rmoyard Oct 19, 2023
1634249
QNode update
rmoyard Oct 19, 2023
7f42faf
QInfo update
rmoyard Oct 19, 2023
9cd3183
Shadow update
rmoyard Oct 19, 2023
b373d19
Add wrap for docs
rmoyard Oct 19, 2023
4fda3a8
Update
rmoyard Oct 19, 2023
0a3fb8a
Update __new__
rmoyard Oct 19, 2023
1acf61a
Typo
rmoyard Oct 19, 2023
a0fdbe6
Typo
rmoyard Oct 19, 2023
2604907
Merge branch 'master' into sc-38900-the-transform-module-docstrings-a…
rmoyard Oct 19, 2023
f166156
Merge branch 'master' into sc-38900-the-transform-module-docstrings-a…
rmoyard Oct 19, 2023
91febeb
Update docs
rmoyard Oct 19, 2023
354d48e
Merge branch 'sc-38900-the-transform-module-docstrings-are-improved' …
rmoyard Oct 19, 2023
d8f8a3d
Typo
rmoyard Oct 19, 2023
c08a4a8
Typo
rmoyard Oct 19, 2023
213dd20
Merge branch 'master' into sc-38900-the-transform-module-docstrings-a…
rmoyard Oct 19, 2023
4f171bc
Pylint
rmoyard Oct 20, 2023
33cb2eb
Merge branch 'sc-38900-the-transform-module-docstrings-are-improved' …
rmoyard Oct 20, 2023
5fa4b81
Update specs tests
rmoyard Oct 20, 2023
7180bfb
Update doc
rmoyard Oct 20, 2023
aefd06d
Update transform doc
rmoyard Oct 23, 2023
8df9bdb
More
rmoyard Oct 23, 2023
10ef886
Merge branch 'master' into sc-38900-the-transform-module-docstrings-a…
rmoyard Oct 23, 2023
3a487c9
Merge branch 'sc-38900-the-transform-module-docstrings-are-improved' …
rmoyard Oct 23, 2023
1efbf42
Reorder
rmoyard Oct 23, 2023
26fc161
Update qfunc transforms docs
rmoyard Oct 23, 2023
6ecea1f
Bump version to `0.34.0-dev` (#4713)
mudit2812 Oct 23, 2023
8c180b1
More qfunc update
rmoyard Oct 23, 2023
d330658
QNode -> circuit
rmoyard Oct 24, 2023
3b2aa38
Update transforms
rmoyard Oct 24, 2023
788ac10
Update transforms args and returns
rmoyard Oct 24, 2023
7c3a329
Merge branch 'master' into sc-38900-the-transform-module-docstrings-a…
rmoyard Oct 24, 2023
65a029d
Revert merge
rmoyard Oct 24, 2023
348f7ff
Double
rmoyard Oct 24, 2023
13c8e69
Linting
rmoyard Oct 24, 2023
6687efc
Top level import
rmoyard Oct 25, 2023
795127a
Pylint
rmoyard Oct 25, 2023
314214b
Apply suggestions from code review
rmoyard Oct 26, 2023
84fe400
Update pennylane/transforms/optimization/pattern_matching.py
rmoyard Oct 26, 2023
6ac86f3
Update pennylane/transforms/optimization/merge_rotations.py
rmoyard Oct 26, 2023
6dc0668
Update pennylane/gradients/parameter_shift_hessian.py
rmoyard Oct 26, 2023
d9d09bb
Update pennylane/transforms/__init__.py
rmoyard Oct 26, 2023
0636442
Review update
rmoyard Oct 26, 2023
c433b94
Merge branch 'sc-38900-the-transform-module-docstrings-are-improved' …
rmoyard Oct 26, 2023
7d47ace
Update pennylane/devices/preprocess.py
trbromley Oct 26, 2023
caf4a64
Update from review
rmoyard Oct 26, 2023
94d6475
Merge branch 'sc-38900-the-transform-module-docstrings-are-improved' …
rmoyard Oct 26, 2023
7b94bab
Small update
rmoyard Oct 26, 2023
c75375a
Change return
rmoyard Oct 26, 2023
f2a4967
Format return
rmoyard Oct 26, 2023
b11eca5
Tom's review
rmoyard Oct 27, 2023
98b2dad
Update transforms main page and dispatcher
trbromley Oct 27, 2023
ed4b4e1
Update TransformProgram
trbromley Oct 27, 2023
447f443
Add usage details
rmoyard Oct 27, 2023
205fe27
Merge branch 'sc-38900-the-transform-module-docstrings-are-improved' …
rmoyard Oct 27, 2023
af54fe6
Fix black in tranform program
rmoyard Oct 27, 2023
207fcf1
Update transform docs
trbromley Oct 27, 2023
bd37894
Minor tweaks
trbromley Oct 27, 2023
5800e2a
Black
rmoyard Oct 27, 2023
70e4209
Fix
rmoyard Oct 27, 2023
c598fe6
Class to func
rmoyard Oct 27, 2023
c411ca5
Fix auto summary
rmoyard Oct 27, 2023
1137a23
Update pennylane/transforms/__init__.py
trbromley Oct 27, 2023
77a8e3f
Update pennylane/transforms/core/transform.py
trbromley Oct 27, 2023
cbf989c
Update pennylane/transforms/core/transform.py
trbromley Oct 27, 2023
1006e56
Update pennylane/transforms/core/transform.py
trbromley Oct 27, 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
58 changes: 35 additions & 23 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,41 @@ Deprecations
Pending deprecations
--------------------

* Passing additional arguments to a transform that decorates a QNode should now be done through use
of ``functools.partial``. For example, the :func:`~pennylane.metric_tensor` transform has an
optional ``approx`` argument which should now be set using:

.. code-block:: python

from functools import partial

@partial(qml.metric_tensor, approx="block-diag")
@qml.qnode(dev)
def circuit(weights):
...

The previously-recommended approach is now deprecated:

.. code-block:: python

@qml.metric_tensor(approx="block-diag")
@qml.qnode(dev)
def circuit(weights):
...

Alternatively, consider calling the transform directly:

.. code-block:: python

@qml.qnode(dev)
def circuit(weights):
...

transformed_circuit = qml.metric_tensor(circuit, approx="block-diag")

- Deprecated in v0.33
- Will be removed in v0.35

* ``qml.ExpvalCost`` has been deprecated, and usage will now raise a warning.

- Deprecated in v0.24
Expand Down Expand Up @@ -155,29 +190,6 @@ Completed deprecation cycles
- Deprecated in v0.32
- Removed in v0.33

* The following decorator syntax for transforms has been deprecated:

.. code-block:: python

@transform_fn(**transform_kwargs)
@qml.qnode(dev)
def circuit():
...

If you are using a transform that has supporting ``transform_kwargs``, please call the
transform directly using ``circuit = transform_fn(circuit, **transform_kwargs)``,
or use ``functools.partial``:

.. code-block:: python

@functools.partial(transform_fn, **transform_kwargs)
@qml.qnode(dev)
def circuit():
...

- Deprecated in v0.33
- Will be removed in v0.34

* The ``mode`` keyword argument in ``QNode`` has been removed, as it was only used in the old return
system (which has also been removed). Please use ``grad_on_execution`` instead.

Expand Down
8 changes: 4 additions & 4 deletions doc/introduction/compiling_circuits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ For example, take the following decorated quantum function:

dev = qml.device('default.qubit', wires=[0, 1, 2])

@qml.compile
@qml.qnode(dev)
@qml.compile()
def qfunc(x, y, z):
def circuit(x, y, z):
qml.Hadamard(wires=0)
qml.Hadamard(wires=1)
qml.Hadamard(wires=2)
Expand All @@ -157,7 +157,7 @@ The default behaviour of :func:`~.pennylane.compile` applies a sequence of three
transforms: :func:`~.pennylane.transforms.commute_controlled`, :func:`~.pennylane.transforms.cancel_inverses`,
and then :func:`~.pennylane.transforms.merge_rotations`.

>>> print(qml.draw(qfunc)(0.2, 0.3, 0.4))
>>> print(qml.draw(circuit)(0.2, 0.3, 0.4))
0: ──H──RX(0.60)─────────────────┤ <Z>
1: ──H─╭X─────────────────────╭●─┤
2: ──H─╰●─────────RX(0.30)──Y─╰Z─┤
Expand All @@ -173,8 +173,8 @@ controlled gates and cancel adjacent inverses, we could do:
from pennylane.transforms import commute_controlled, cancel_inverses
pipeline = [commute_controlled, cancel_inverses]

@partial(qml.compile, pipeline=pipeline)
@qml.qnode(dev)
@qml.compile(pipeline=pipeline)
def qfunc(x, y, z):
qml.Hadamard(wires=0)
qml.Hadamard(wires=1)
Expand Down
1 change: 1 addition & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
from pennylane import qaoa
from pennylane.qnode import QNode, qnode
from pennylane.transforms import (
transform,
adjoint_metric_tensor,
batch_params,
batch_input,
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/device_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def preprocess(
**Example**

All the transforms that are part of the preprocessing need to respect the transform contract defined in
:func:`pennylane.transforms.core.transform`.
:func:`pennylane.transform`.

.. code-block:: python

Expand Down
51 changes: 18 additions & 33 deletions pennylane/devices/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
)
from pennylane.typing import ResultBatch, Result
from pennylane import DeviceError
from pennylane.transforms.core import transform
from pennylane import transform
from pennylane.wires import WireError

PostprocessingFn = Callable[[ResultBatch], Union[Result, ResultBatch]]
Expand Down Expand Up @@ -87,8 +87,12 @@ def no_sampling(
"""Raises an error if the tape has finite shots.

Args:
tape (QuantumTape): a quantum circuit
name="device" (str): name to use in error message.
tape (QuantumTape or .QNode or Callable): a quantum circuit
name (str): name to use in error message.

Returns:
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved


This transform can be added to forbid finite shots. For example, ``default.qubit`` uses it for
adjoint and backprop validation.
Expand All @@ -107,17 +111,13 @@ def validate_device_wires(
across all available wires.

Args:
tape (QuantumTape): a quantum circuit.
tape (QuantumTape or .QNode or Callable): a quantum circuit.
wires=None (Optional[Wires]): the allowed wires. Wires of ``None`` allows any wires
to be present in the tape.
name="device" (str): the name of the device to use in error messages.

Returns:
pennylane.QNode or qfunc or Tuple[List[.QuantumTape], Callable]: If a QNode is passed,
it returns a QNode with the transform added to its transform program.
If a tape is passed, returns a tuple containing a list of
quantum tapes to be evaluated, and a function to be applied to these
tape executions.
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

Raises:
WireError: if the tape has a wire not present in the provided wires.
Expand Down Expand Up @@ -153,16 +153,13 @@ def validate_multiprocessing_workers(
threads per worker.

Args:
tape (QuantumTape): a quantum circuit.
tape (QuantumTape or .QNode or Callable): a quantum circuit.
max_workers (int): Maximal number of multiprocessing workers
device (pennylane.devices.Device): The device to be checked.

Returns:
pennylane.QNode or qfunc or Tuple[List[.QuantumTape], Callable]: If a QNode is passed,
it returns a QNode with the transform added to its transform program.
If a tape is passed, returns a tuple containing a list of
quantum tapes to be evaluated, and a function to be applied to these
tape executions.
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

"""
if max_workers is not None:
threads_per_proc = os.cpu_count() # all threads by default
Expand Down Expand Up @@ -238,7 +235,7 @@ def decompose(
"""Decompose operations until the stopping condition is met.

Args:
tape (QuantumTape): a quantum circuit.
tape (QuantumTape, QNode, Callable): a quantum circuit.
stopping_condition (Callable): a function from an operator to a boolean. If ``False``, the operator
should be decomposed. If an operator cannot be decomposed and is not accepted by ``stopping_condition``,
a ``DecompositionUndefinedError`` will be raised.
Expand All @@ -249,11 +246,7 @@ def decompose(


Returns:
pennylane.QNode or qfunc or Tuple[List[.QuantumTape], Callable]: If a QNode is passed,
it returns a QNode with the transform added to its transform program.
If a tape is passed, returns a tuple containing a list of
quantum tapes to be evaluated, and a function to be applied to these
tape executions.
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

Raises:
DecompositionUndefinedError: if an operator is not accepted and does not define a decomposition
Expand Down Expand Up @@ -339,16 +332,12 @@ def validate_observables(
"""Validates the observables and measurements for a circuit.

Args:
tape (QuantumTape): a quantum circuit.
tape (QuantumTape or .QNode or Callable): a quantum circuit.
stopping_condition (callable): a function that specifies whether or not an observable is accepted.
name (str): the name of the device to use in error messages.

Returns:
pennylane.QNode or qfunc or Tuple[List[.QuantumTape], Callable]: If a QNode is passed,
it returns a QNode with the transform added to its transform program.
If a tape is passed, returns a tuple containing a list of
quantum tapes to be evaluated, and a function to be applied to these
tape executions.
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

Raises:
DeviceError: if an observable is not supported
Expand Down Expand Up @@ -383,19 +372,15 @@ def validate_measurements(
"""Validates the supported state and sample based measurement processes.

Args:
tape (QuantumTape): a quantum circuit.
tape (QuantumTape, .QNode, Callable): a quantum circuit.
analytic_measurements (Callable[[MeasurementProcess], bool]): a function from a measurement process
to whether or not it is accepted in analytic simulations.
sample_measurements (Callable[[MeasurementProcess], bool]): a function from a measurement process
to whether or not it accepted for finite shot siutations
name (str): the name to use in error messages.

Returns:
pennylane.QNode or qfunc or Tuple[List[.QuantumTape], Callable]: If a QNode is passed,
it returns a QNode with the transform added to its transform program.
If a tape is passed, returns a tuple containing a list of
quantum tapes to be evaluated, and a function to be applied to these
tape executions.
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

Raises:
DeviceError: if a measurement process is not supported.
Expand Down
8 changes: 4 additions & 4 deletions pennylane/fourier/circuit_spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
preprocessing in the QNode."""
from typing import Sequence, Callable
from functools import partial
from pennylane.transforms.core import transform
from pennylane import transform
from pennylane.tape import QuantumTape
from .utils import get_spectrum, join_spectra

Expand Down Expand Up @@ -48,15 +48,14 @@ def circuit_spectrum(
If no input-encoding gates are found, an empty dictionary is returned.

Args:
tape (QuantumTape): a quantum node representing a circuit in which
tape (pennylane.QNode or pennylane.tape.QuantumTape or Callable): a quantum circuit in which
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
input-encoding gates are marked by their ``id`` attribute
encoding_gates (list[str]): list of input-encoding gate ``id`` strings
for which to compute the frequency spectra
decimals (int): number of decimals to which to round frequencies.

Returns:
(dict[str, list[float]]): Dictionary with the input-encoding gate ``id`` as keys and
their frequency spectra as values.
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved


**Details**
Expand Down Expand Up @@ -185,6 +184,7 @@ def circuit(x):
"""

def processing_fn(tapes):
"""Process the tapes extract the spectrum of the circuit."""
tape = tapes[0]
freqs = {}
for op in tape.operations:
Expand Down
20 changes: 7 additions & 13 deletions pennylane/gradients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,6 @@
stoch_pulse_grad
pulse_odegen

Custom gradients
^^^^^^^^^^^^^^^^

.. autosummary::
:toctree: api

gradient_transform
hessian_transform

Utility functions
^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -131,7 +122,10 @@ def circuit(weights):
Transforming QNodes
-------------------

Alternatively, quantum gradient transforms can be applied manually to QNodes.
Alternatively, quantum gradient transforms can be applied manually to QNodes. This is not
recommended because PennyLane must compute the classical Jacobian of the parameters and multiply it with
the quantum Jacobian, we recommend using the ``diff_method`` kwargs with your favorite machine learning
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
framework.
trbromley marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: python

Expand Down Expand Up @@ -301,12 +295,12 @@ def circuit(weights):
Custom gradient transforms
--------------------------

Using the :class:`~.gradient_transform` decorator, custom gradient transforms
Using the :class:`pennylane.transform` decorator, custom gradient transforms
can be created:

.. code-block:: python

@gradient_transform
@transform
def my_custom_gradient(tape, **kwargs):
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
...
return gradient_tapes, processing_fn
Expand All @@ -315,7 +309,7 @@ def my_custom_gradient(tape, **kwargs):
to QNodes, or registered as the quantum gradient transform to use
during autodifferentiation.

For more details, please see the :class:`~.gradient_transform`
For more details, please see the :class:`pennylane.transform`
documentation.
"""
import pennylane as qml
Expand Down
23 changes: 8 additions & 15 deletions pennylane/gradients/finite_difference.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import pennylane as qml
from pennylane.measurements import ProbabilityMP
from pennylane.transforms.core import transform
from pennylane import transform
from pennylane.transforms.tape_expand import expand_invalid_trainable
from pennylane.gradients.gradient_transform import _contract_qjac_with_cjac

Expand Down Expand Up @@ -210,10 +210,10 @@ def finite_diff(
f0=None,
validate_params=True,
) -> (Sequence[qml.tape.QuantumTape], Callable):
r"""Transform a QNode to compute the finite-difference gradient of all gate parameters with respect to its inputs.
r"""Transform a circuit to compute the finite-difference gradient of all gate parameters with respect to its inputs.

Args:
tape (pennylane.QNode or .QuantumTape): quantum tape or QNode to differentiate
tape (pennylane.QNode or .QuantumTape): quantum circuit to differentiate
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
argnum (int or list[int] or None): Trainable parameter indices to differentiate
with respect to. If not provided, the derivatives with respect to all
trainable parameters are returned.
Expand All @@ -237,17 +237,7 @@ def finite_diff(
If ``False``, the finite-difference method will be applied to all parameters.

Returns:
function or tuple[list[QuantumTape], function]:

- If the input is a QNode, an object representing the Jacobian (function) of the QNode
that can be executed to obtain the Jacobian.
The type of the Jacobian returned is either a tensor, a tuple or a
nested tuple depending on the nesting structure of the original QNode output.

- If the input is a tape, a tuple containing a
list of generated tapes, together with a post-processing
function to be applied to the results of the evaluated tapes
in order to obtain the Jacobian.
qnode (pennylane.QNode) or tuple[List[.QuantumTape], function]: The transformed circuit as described in :class:`pennylane.transform` documentation.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

**Example**

Expand Down Expand Up @@ -287,7 +277,10 @@ def finite_diff(
.. details::
:title: Usage Details

This gradient transform can also be applied directly to :class:`QNode <pennylane.QNode>` objects:
This gradient transform can also be applied directly to :class:`QNode <pennylane.QNode>` objects. This is not
recommended because PennyLane must compute the classical Jacobian of the parameters and multiply it with
the quantum Jacobian, we recommend using the ``diff_method`` kwargs with your favorite machine learning
framework.

>>> @qml.qnode(dev)
... def circuit(params):
Expand Down
Loading
Loading