Skip to content

Commit

Permalink
Merge branch 'master' into capture-qnode
Browse files Browse the repository at this point in the history
  • Loading branch information
albi3ro committed Jun 3, 2024
2 parents cca8025 + 92ce59d commit aab3442
Show file tree
Hide file tree
Showing 70 changed files with 2,951 additions and 1,129 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
name: Docker builds
on:
push:
branches:
- master
on: workflow_dispatch

jobs:
base-tests:
Expand Down
6 changes: 3 additions & 3 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=numpy,scipy,autograd,toml,appdir,autograd.numpy,autograd.numpy.linalg,autograd.numpy.builtins,semantic_version,torch,tensorflow,tensorflow.contrib,tensorflow.contrib.eager,LazyLoader,networkx,networkx.dag
extension-pkg-whitelist=numpy,scipy,autograd,toml,appdir,autograd.numpy,autograd.numpy.linalg,autograd.numpy.builtins,semantic_version,packaging,torch,tensorflow,tensorflow.contrib,tensorflow.contrib.eager,LazyLoader,networkx,networkx.dag

[TYPECHECK]

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=numpy,scipy,autograd,toml,appdir,autograd.numpy,autograd.numpy.linalg,autograd.numpy.builtins,semantic_version,torch,tensorflow,tensorflow.contrib,tensorflow.contrib.eager,LazyLoader,networkx,networkx.dag,math,pennylane.numpy
ignored-modules=numpy,scipy,autograd,toml,appdir,autograd.numpy,autograd.numpy.linalg,autograd.numpy.builtins,semantic_version,packaging,torch,tensorflow,tensorflow.contrib,tensorflow.contrib.eager,LazyLoader,networkx,networkx.dag,math,pennylane.numpy

# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set). This supports can work
# with qualified names.
ignored-classes=numpy,scipy,autograd,toml,appdir,autograd.numpy,autograd.numpy.linalg,autograd.numpy.builtins,semantic_version,torch,tensorflow,tensorflow.contrib,tensorflow.contrib.eager,LazyLoader,networkx,networkx.dag,math,pennylane.numpy,pennylane.numpy.random,pennylane.numpy.linalg,pennylane.numpy.builtins,pennylane.operation,rustworkx,kahypar
ignored-classes=numpy,scipy,autograd,toml,appdir,autograd.numpy,autograd.numpy.linalg,autograd.numpy.builtins,semantic_version,packaging,torch,tensorflow,tensorflow.contrib,tensorflow.contrib.eager,LazyLoader,networkx,networkx.dag,math,pennylane.numpy,pennylane.numpy.random,pennylane.numpy.linalg,pennylane.numpy.builtins,pennylane.operation,rustworkx,kahypar

[MESSAGES CONTROL]

Expand Down
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ignore:
- "pennylane/devices/tests/*"
- "pennylane/data/base/_lazy_modules.py"
- "pennylane/logging/*"

codecov:
notify:
Expand Down
9 changes: 9 additions & 0 deletions doc/development/guide/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ be installed alongside PennyLane:
* `appdirs <https://github.com/ActiveState/appdirs>`_
* `semantic-version <https://github.com/rbarrois/python-semanticversion>`_ >= 2.7
* `autoray <https://github.com/jcmgray/autoray>`__ >= 0.6.11
* `packaging <https://github.com/pypa/packaging>`_

The following Python packages are optional:

Expand Down Expand Up @@ -66,6 +67,14 @@ importing PennyLane in Python.
requires ``pip install -e .`` to be re-run in the plugin repository
for the changes to take effect.

Apart from the core packages needed to run PennyLane. Some extra packages need
to be installed for several development processes, such as linting, testing, and
pre-commit quality checks. Those can be installed easily via ``pip``:

.. code-block:: bash
pip install -r requirements-dev.txt
Docker
------

Expand Down
44 changes: 29 additions & 15 deletions doc/development/guide/logging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,36 @@ To add logging support to components of PennyLane, we must define a module logge
which will be used within the given module, and track directories,
filenames and function names, as we have defined the appropriate types
within the formatter configuration (see :class:`pennylane.logging.DefaultFormatter`). With the logger defined, we can selectively add to the logger by if-else statements, which compare the given module’s log-level to any log record
message it receives. This step is not necessary, as the message will
only output if the level is enabled, though if an expensive function
call is required to build the string for the log-message, it can be
faster to perform this check:
within the formatter configuration (see :class:`pennylane.logging.DefaultFormatter`). With the logger defined, we can selectively add to the logger via two methods:

.. code:: python
#. Using decorators on the required functions and methods in a given module:

.. code:: python
# debug_logger can be used to decorate any method or free function
# debug_logger_init can be used to decorate class __init__ methods.
from pennylane.logging import debug_logger, debug_logger_init
@debug_logger
def my_func(arg1, arg2):
return arg1 + arg2
if logger.isEnabledFor(logging.DEBUG):
logger.debug(
"""Entry with args=(arg_name_1=%s, arg_name_2=%s, ..., arg_name_n=%s)""",
arg_name_1, arg_name_2, ..., arg_name_n,
)
#. Explicitly by if-else statements, which compare the given module’s log-level to any log record message it receives. This step is not necessary, as the message will
only output if the level is enabled, though if an expensive function
call is required to build the string for the log-message, it can be
faster to perform this check:

The above line can be added below the function/method entry point,
and the provided arguments can be used to populate the log message. This
allows us a way to track the inputs and calls through the stack in the
order they are executed, as is the basis for following a trail of
.. code:: python
if logger.isEnabledFor(logging.DEBUG):
logger.debug(
"""Entry with args=(arg_name_1=%s, arg_name_2=%s, ..., arg_name_n=%s)""",
arg_name_1, arg_name_2, ..., arg_name_n,
)
Both versions provide similar functionality, though the explicit logger call allows more custom message-formatting, such as expanding functions as string representation, filtering of data, and other useful processing for a valid record.

These logging options allow us a way to track the inputs and calls through the stack in the order they are executed, as is the basis for following a trail of
execution as needed.

All debug log-statements currently added to the PennyLane execution
Expand Down Expand Up @@ -82,6 +94,8 @@ messages based on some criteria, we can add these to the respective
handlers. As an example, we can go through the configuration file and
explore the options.

For ease-of-development, the function :func:`pennylane.logging.edit_system_config` opens an editor (if the ``EDITOR`` environment variable is set), or a viewer of the existing file configuration, which can be used to modify the existing options.

Modifying the configuration options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
12 changes: 6 additions & 6 deletions doc/development/guide/tests.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ Software tests

Requirements
~~~~~~~~~~~~
The PennyLane test suite requires the Python ``pytest`` package, as well as:
The PennyLane test suite requires the Python ``pytest`` package, as well as
some extentions thereof, for example:

* ``pytest-cov``: determines test coverage
* ``pytest-mock``: allows replacing components with dummy/mock objects
* ``flaky``: manages tests with non-deterministic behaviour
* ``pytest-benchmark``: benchmarks the performance of functions, and can be used to ensure consistent runtime
* ``pytest-xdist``: currently used to force some tests to run on the same thread to avoid race conditions

These requirements can be installed via ``pip``:

.. code-block:: bash
pip install pytest pytest-cov pytest-mock flaky
If you properly followed the :doc:`installation guide <./installation>`, you should have all of these packages and others installed in your
environment, so you can go ahead and put your code to the test!

Creating a test
~~~~~~~~~~~~~~~
Expand Down
3 changes: 3 additions & 0 deletions doc/introduction/logging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ outputs to the default configured handler, which is directed to the standard out
level = "DEBUG" # Set to TRACE for highest verbosity
propagate = false
Viewing the existing logging configuration file is possible by calling the :func:`pennylane.logging.edit_system_config` function which will open the file in an existing browser or editor window.

For more info on the customization of the logging options, please see the logging development guide at :doc:`/development/guide/logging`, and the `Python logging documentation <https://docs.python.org/3/library/logging.html>`_.
23 changes: 23 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@

<h3>Improvements 🛠</h3>

* The wires for the `default.tensor` device are selected at runtime if they are not provided by user.
[(#5744)](https://github.com/PennyLaneAI/pennylane/pull/5744)

* Added `packaging` in the required list of packages.
[(#5769)](https://github.com/PennyLaneAI/pennylane/pull/5769).

* Logging now allows for an easier opt-in across the stack, and also extends control support to `catalyst`.
[(#5528)](https://github.com/PennyLaneAI/pennylane/pull/5528).

* A number of templates have been updated to be valid pytrees and PennyLane operations.
[(#5698)](https://github.com/PennyLaneAI/pennylane/pull/5698)

Expand All @@ -21,6 +30,9 @@
* The sorting order of parameter-shift terms is now guaranteed to resolve ties in the absolute value with the sign of the shifts.
[(#5582)](https://github.com/PennyLaneAI/pennylane/pull/5582)

* `qml.transforms.split_non_commuting` can now handle circuits containing measurements of multi-term observables.
[(#5729)](https://github.com/PennyLaneAI/pennylane/pull/5729)

<h4>Mid-circuit measurements and dynamic circuits</h4>

* The `dynamic_one_shot` transform uses a single auxiliary tape with a shot vector and `default.qubit` implements the loop over shots with `jax.vmap`.
Expand Down Expand Up @@ -100,6 +112,7 @@
[(#5564)](https://github.com/PennyLaneAI/pennylane/pull/5564)
[(#5511)](https://github.com/PennyLaneAI/pennylane/pull/5511)
[(#5708)](https://github.com/PennyLaneAI/pennylane/pull/5708)
[(#5523)](https://github.com/PennyLaneAI/pennylane/pull/5523)

* The `decompose` transform has an `error` kwarg to specify the type of error that should be raised,
allowing error types to be more consistent with the context the `decompose` function is used in.
Expand Down Expand Up @@ -187,6 +200,12 @@

<h3>Bug fixes 🐛</h3>

* Disable Docker builds on PR merge.
[(#5777)](https://github.com/PennyLaneAI/pennylane/pull/5777)

* The validation of the adjoint method in `DefaultQubit` correctly handles device wires now.
[(#5761)](https://github.com/PennyLaneAI/pennylane/pull/5761)

* `QuantumPhaseEstimation.map_wires` on longer modifies the original operation instance.
[(#5698)](https://github.com/PennyLaneAI/pennylane/pull/5698)

Expand Down Expand Up @@ -240,6 +259,9 @@
* Fixes a bug in `qml.math.dot` that raises an error when only one of the operands is a scalar.
[(#5702)](https://github.com/PennyLaneAI/pennylane/pull/5702)

* `qml.matrix` is now compatible with qnodes compiled by catalyst.qjit.
[(#5753)](https://github.com/PennyLaneAI/pennylane/pull/5753)

<h3>Contributors ✍️</h3>

This release contains contributions from (in alphabetical order):
Expand All @@ -260,4 +282,5 @@ Vincent Michaud-Rioux,
Lee James O'Riordan,
Mudit Pandey,
Kenya Sakka,
Haochen Paul Wang,
David Wierichs.
1 change: 1 addition & 0 deletions doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ m2r2
numpy
pygments-github-lexers
semantic_version==2.10
packaging
scipy
docutils==0.16
sphinx~=3.5.0; python_version < "3.10"
Expand Down
3 changes: 2 additions & 1 deletion pennylane/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2018-2021 Xanadu Quantum Technologies Inc.
# Copyright 2018-2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,7 @@


import numpy as _np

from semantic_version import SimpleSpec, Version

from pennylane.boolean_fn import BooleanFn
Expand Down
2 changes: 1 addition & 1 deletion pennylane/capture/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def qfunc(a):
(where ``cls`` indicates the class) if:
* The operator does not accept wires, like :class:`~.SymbolicOp` or :class:`~.CompositeOp`.
* The operator needs to enforce a data/ metadata distinction, like :class:`~.PauliRot`.
* The operator needs to enforce a data / metadata distinction, like :class:`~.PauliRot`.
In such cases, the operator developer can override ``cls._primitive_bind_call``, which
will be called when constructing a new class instance instead of ``type.__call__``. For example,
Expand Down
2 changes: 1 addition & 1 deletion pennylane/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from sys import version_info
from typing import List, Optional

from semantic_version import Version
from packaging.version import Version

PL_CATALYST_MIN_VERSION = Version("0.6.0")

Expand Down
12 changes: 12 additions & 0 deletions pennylane/devices/default_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import functools
import itertools
import logging
from collections import defaultdict
from string import ascii_letters as ABC

Expand All @@ -29,6 +30,7 @@
import pennylane as qml
import pennylane.math as qnp
from pennylane import BasisState, DeviceError, QubitDensityMatrix, QubitDevice, Snapshot, StatePrep
from pennylane.logging import debug_logger, debug_logger_init
from pennylane.measurements import (
CountsMP,
DensityMatrixMP,
Expand All @@ -47,6 +49,9 @@

from .._version import __version__

logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())

ABC_ARRAY = np.array(list(ABC))
tolerance = 1e-10

Expand Down Expand Up @@ -181,6 +186,7 @@ def _asarray(array, dtype=None):
res = qnp.cast(array, dtype=dtype)
return res

@debug_logger_init
def __init__(
self,
wires,
Expand Down Expand Up @@ -252,6 +258,7 @@ def state(self):
# User obtains state as a matrix
return qnp.reshape(self._pre_rotated_state, (dim, dim))

@debug_logger
def density_matrix(self, wires):
"""Returns the reduced density matrix over the given wires.
Expand All @@ -266,19 +273,22 @@ def density_matrix(self, wires):
wires = self.map_wires(wires)
return qml.math.reduce_dm(state, indices=wires, c_dtype=self.C_DTYPE)

@debug_logger
def purity(self, mp, **kwargs): # pylint: disable=unused-argument
"""Returns the purity of the final state"""
state = getattr(self, "state", None)
wires = self.map_wires(mp.wires)
return qml.math.purity(state, indices=wires, c_dtype=self.C_DTYPE)

@debug_logger
def reset(self):
"""Resets the device"""
super().reset()

self._state = self._create_basis_state(0)
self._pre_rotated_state = self._state

@debug_logger
def analytic_probability(self, wires=None):
if self._state is None:
return None
Expand Down Expand Up @@ -706,6 +716,7 @@ def _apply_operation(self, operation):

# pylint: disable=arguments-differ

@debug_logger
def execute(self, circuit, **kwargs):
"""Execute a queue of quantum operations on the device and then
measure the given observables.
Expand Down Expand Up @@ -760,6 +771,7 @@ def execute(self, circuit, **kwargs):
self.measured_wires = qml.wires.Wires.all_wires(wires_list)
return super().execute(circuit, **kwargs)

@debug_logger
def apply(self, operations, rotations=None, **kwargs):
rotations = rotations or []

Expand Down
Loading

0 comments on commit aab3442

Please sign in to comment.