Skip to content

Commit

Permalink
Merge branch 'master' into no-grad-on-diff-method-none
Browse files Browse the repository at this point in the history
  • Loading branch information
albi3ro authored Jan 15, 2025
2 parents b13371d + 0bed5e8 commit 6097238
Show file tree
Hide file tree
Showing 124 changed files with 5,264 additions and 1,919 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
- reopened
- synchronize
- ready_for_review
branches-ignore:
- 'v[0-9]+.[0-9]+.[0-9]+-docs'
# Scheduled trigger on Monday at 2:47am UTC
schedule:
- cron: "47 2 * * 1"
Expand Down
8 changes: 4 additions & 4 deletions doc/code/qml_fermi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ the orbital it acts on. The values of the dictionary are one of ``'+'`` or ``'-'
denote creation and annihilation operators, respectively. The operator
:math:`a^{\dagger}_0 a_3 a^{\dagger}_1` can then be constructed with

>>> qml.fermi.FermiWord({(0, 0): '+', (1, 3): '-', (2, 1): '+'})
>>> qml.FermiWord({(0, 0): '+', (1, 3): '-', (2, 1): '+'})
a⁺(0) a(3) a⁺(1)

A Fermi sentence can be constructed directly by passing a dictionary of Fermi words and their
corresponding coefficients to the :class:`~pennylane.fermi.FermiSentence` class. For instance, the
Fermi sentence :math:`1.2 a^{\dagger}_0 a_0 + 2.3 a^{\dagger}_3 a_3` can be constructed as

>>> fw1 = qml.fermi.FermiWord({(0, 0): '+', (1, 0): '-'})
>>> fw2 = qml.fermi.FermiWord({(0, 3): '+', (1, 3): '-'})
>>> qml.fermi.FermiSentence({fw1: 1.2, fw2: 2.3})
>>> fw1 = qml.FermiWord({(0, 0): '+', (1, 0): '-'})
>>> fw2 = qml.FermiWord({(0, 3): '+', (1, 3): '-'})
>>> qml.FermiSentence({fw1: 1.2, fw2: 2.3})
1.2 * a⁺(0) a(0)
+ 2.3 * a⁺(3) a(3)
2 changes: 1 addition & 1 deletion doc/code/qml_noise.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ noise-related metadata can also be supplied to construct a noise model using:
~NoiseModel

Each conditional in the ``model_map`` (and ``meas_map``) evaluates the gate operations
(and terminal measurments) in the quantum circuit based on some condition of its attributes
(and terminal measurements) in the quantum circuit based on some condition of its attributes
(e.g., type, parameters, wires, etc.) and uses the corresponding callable to apply the
noise operations, using the user-provided metadata (e.g., hardware topologies or relaxation
times), whenever the condition is true. A noise model, once built, can be attached
Expand Down
1 change: 1 addition & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"TensorFlow, the TensorFlow logo, and any related marks are trademarks " "of Google Inc."
],
"google_analytics_tracking_id": "G-C480Z9JL0D",
"search_on_pennylane_ai": True,
}

edit_on_github_project = "PennyLaneAI/pennylane"
Expand Down
10 changes: 5 additions & 5 deletions doc/development/autograph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Python control flow:
return qml.expval(qml.PauliZ(0) + qml.PauliZ(3))
While this function cannot be captured directly because there is control flow that depends on the function's inputs' values—the inputs are treated as JAX tracers at capture time, which don't have concrete valuesit can be captured by converting to native PennyLane syntax
While this function cannot be captured directly because there is control flow that depends on the values of the function's inputs (the inputs are treated as JAX tracers at capture time, which don't have concrete values) it can be captured by converting to native PennyLane syntax
via AutoGraph. This is the default behaviour of :func:`~.autograph.make_plxpr`.

>>> weights = jnp.linspace(-1, 1, 20).reshape([5, 4])
Expand Down Expand Up @@ -351,7 +351,7 @@ For example, using a ``for`` loop with static bounds to index a JAX array is str
However, indexing within a ``for`` loop with AutoGraph will require that the object indexed is
a JAX array or dynamic runtime variable.

If the array you are indexing within the for loop is not a JAX array
If the array you are indexing within the ``for`` loop is not a JAX array
or dynamic variable, an error will be raised:

>>> @qml.qnode(dev)
Expand All @@ -378,7 +378,7 @@ a JAX array:
>>> eval_jaxpr(plxpr.jaxpr, plxpr.consts)
[Array(0.99500417, dtype=float64)]

If the object you are indexing **cannot** be converted to a JAX array, it is not possible for AutoGraph to capture this for loop.
If the object you are indexing **cannot** be converted to a JAX array, it is not possible for AutoGraph to capture this ``for`` loop.

If you are updating elements of the array, this must be done using the JAX ``.at`` and ``.set`` syntax.

Expand Down Expand Up @@ -440,7 +440,7 @@ However, like with conditionals, a similar restriction applies: variables
which are updated across iterations of the loop must have a JAX compilable
type (Booleans, Python numeric types, and JAX arrays).

You can also utilize temporary variables within a for loop:
You can also utilize temporary variables within a ``for`` loop:

>>> def f(x):
... for y in [0, 4, 5]:
Expand Down Expand Up @@ -520,7 +520,7 @@ To allow AutoGraph conversion to work in this case, simply convert the list to a
>>> eval_jaxpr(plxpr.jaxpr, plxpr.consts)
[Array(0.99500417, dtype=float64)]

If the object you are indexing **cannot** be converted to a JAX array, it is not possible for AutoGraph to capture this for loop.
If the object you are indexing **cannot** be converted to a JAX array, it is not possible for AutoGraph to capture this ``while`` loop.

If you are updating elements of the array, this must be done using the JAX ``.at`` and ``.set`` syntax.

Expand Down
44 changes: 17 additions & 27 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ deprecations are listed below.
Pending deprecations
--------------------

* The ``qsvt_legacy`` function has been deprecated.
Instead, use ``qml.qsvt``. The new functionality takes an input polynomial instead of angles.

- Deprecated in v0.40
- Will be removed in v0.41

* The ``tape`` and ``qtape`` properties of ``QNode`` have been deprecated.
Instead, use the ``qml.workflow.construct_tape`` function.

Expand All @@ -31,31 +25,11 @@ Pending deprecations
- Deprecated in v0.40
- Will be removed in v0.41

* The ``output_dim`` property of ``qml.tape.QuantumScript`` has been deprecated. Instead, use method ``shape`` of ``QuantumScript`` or ``MeasurementProcess`` to get the same information.

- Deprecated in v0.40
- Will be removed in v0.41

* The ``QNode.get_best_method`` and ``QNode.best_method_str`` methods have been deprecated.
Instead, use the ``qml.workflow.get_best_diff_method`` function.

- Deprecated in v0.40
- Will be removed in v0.41

* The ``gradient_fn`` keyword argument to ``qml.execute`` has been renamed ``diff_method``.

- Deprecated in v0.40
- Will be removed in v0.41

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

* The ``QubitStateVector`` template is deprecated.
Instead, use ``StatePrep``.

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

* ``op.ops`` and ``op.coeffs`` for ``Sum`` and ``Prod`` will be removed in the future. Use
:meth:`~.Operator.terms` instead.

Expand All @@ -70,7 +44,6 @@ Pending deprecations
values with a bit string. In the future, it will no longer accepts strings as control values.

- Deprecated in v0.36
- Will be removed in v0.37

Completed removal of legacy operator arithmetic
-----------------------------------------------
Expand Down Expand Up @@ -100,6 +73,23 @@ for details on how to port your legacy code to the new system. The following fun
Completed deprecation cycles
----------------------------

* The ``QNode.get_best_method`` and ``QNode.best_method_str`` methods have been removed.
Instead, use the ``qml.workflow.get_best_diff_method`` function.

- Deprecated in v0.40
- Removed in v0.41

* The ``output_dim`` property of ``qml.tape.QuantumScript`` has been removed. Instead, use method ``shape`` of ``QuantumScript`` or ``MeasurementProcess`` to get the same information.

- Deprecated in v0.40
- Removed in v0.41

* The ``qml.qsvt_legacy`` function has been removed.
Instead, use ``qml.qsvt``. The new functionality takes an input polynomial instead of angles.

- Deprecated in v0.40
- Removed in v0.41

* The ``qml.qinfo`` module has been removed. Please see the respective functions in the ``qml.math`` and ``qml.measurements``
modules instead.

Expand Down
29 changes: 18 additions & 11 deletions doc/development/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ For example:
This execute method works in tandem with the optional :meth:`Device.preprocess_transforms <pennylane.devices.Device.preprocess_transforms>`
and :meth:`Device.setup_execution_config`, described below in more detail. Preprocessing transforms
turns generic circuits into ones supported by the device, or raises an error if the circuit is invalid.
turns generic circuits into ones supported by the device or raises an error if the circuit is invalid.
Execution produces numerical results from those supported circuits.

In a more minimal example, for any initial batch of quantum tapes and a config object, we expect to be able to do:
Expand Down Expand Up @@ -376,7 +376,7 @@ Wires
Devices can now either:

1) Strictly use wires provided by the user on initialization: ``device(name, wires=wires)``
2) Infer the number and ordering of wires provided by the submitted circuit.
2) Infer the number and order of wires provided by the submitted circuit
3) Strictly require specific wire labels

Option 2 allows workflows to change the number and labeling of wires over time, but sometimes users want
Expand Down Expand Up @@ -434,18 +434,20 @@ The execution config stores two kinds of information:

Device options are any device specific options used to configure the behavior of an execution. For
example, ``default.qubit`` has ``max_workers``, ``rng``, and ``prng_key``. ``default.tensor`` has
``contract``, ``cutoff``, ``dtype``, ``method``, and ``max_bond_dim``. These options are often set
``contract``, ``contraction_optimizer``, ``cutoff``, ``c_dtype``, ``local_simplify``, ``method``, and ``max_bond_dim``. These options are often set
with default values on initialization. These values should be placed into the ``ExecutionConfig.device_options``
dictionary in :meth:`~.devices.Device.setup_execution_config`. Note that we do provide a default
implementation of this method, but you will most likely need to override it yourself.

>>> dev = qml.device('default.tensor', wires=2, max_bond_dim=4, contract="nonlocal", dtype=np.complex64)
>>> dev = qml.device('default.tensor', wires=2, max_bond_dim=4, contract="nonlocal", c_dtype=np.complex64)
>>> dev.setup_execution_config().device_options
{'contract': 'nonlocal',
'cutoff': 1.1920929e-07,
'dtype': numpy.complex64,
'method': 'mps',
'max_bond_dim': 4}
'contraction_optimizer': 'auto-hq',
'cutoff': None,
'c_dtype': numpy.complex64,
'local_simplify': 'ADCRS',
'max_bond_dim': 4,
'method': 'mps'}

Even if the property is stored as an attribute on the device, execution should pull the value of
these properties from the config instead of from the device instance. While not yet integrated at
Expand All @@ -470,12 +472,15 @@ pieces of functionality:
Note that these properties are only applicable to devices that provided derivatives or VJPs. If your device
does not provide derivatives, you can safely ignore these properties.

The workflow options are ``use_device_gradient``, ``use_device_jacobian_product``, and ``grad_on_execution``.
The workflow options are ``use_device_gradient``, ``use_device_jacobian_product``, ``grad_on_execution``,
and ``convert_to_numpy``.
``use_device_gradient=True`` indicates that workflow should request derivatives from the device.
``grad_on_execution=True`` indicates a preference to use ``execute_and_compute_derivatives`` instead
of ``execute`` followed by ``compute_derivatives``. Finally, ``use_device_jacobian_product`` indicates
of ``execute`` followed by ``compute_derivatives``. ``use_device_jacobian_product`` indicates
a request to call ``compute_vjp`` instead of ``compute_derivatives``. Note that if ``use_device_jacobian_product``
is ``True``, this takes precedence over calculating the full jacobian.
is ``True``, this takes precedence over calculating the full jacobian. If the device can accept ML framework parameters, like
jax, ``convert_to_numpy=False`` should be specified. Then the parameters will not be converted, and special
interface-specific processing (like executing inside a ``jax.pure_callback`` when using ``jax.jit``) will be needed.

>>> config = qml.devices.ExecutionConfig(gradient_method="adjoint")
>>> processed_config = qml.device('default.qubit').setup_execution_config(config)
Expand All @@ -485,6 +490,8 @@ True
True
>>> processed_config.grad_on_execution
True
>>> processed_config.convert_to_numpy
True

Execution
---------
Expand Down
Loading

0 comments on commit 6097238

Please sign in to comment.