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

Custom boolean functions for supporting noise models #5674

Merged
merged 74 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
202c365
init
obliviateandsurrender Apr 26, 2024
4c03e36
init
obliviateandsurrender May 4, 2024
5ff822f
basic structure
obliviateandsurrender May 9, 2024
d49a88b
more versatile support
obliviateandsurrender May 9, 2024
2b8b65d
fix formatting
obliviateandsurrender May 9, 2024
72d25d0
Merge branch 'master' into noise-models-1
obliviateandsurrender May 9, 2024
1892a42
fix `pylint`?
obliviateandsurrender May 9, 2024
3e301a2
more fixes
obliviateandsurrender May 9, 2024
4b6c6b4
format tweaks
obliviateandsurrender May 9, 2024
1317189
add `partial_wires`
obliviateandsurrender May 10, 2024
5332c61
add tests
obliviateandsurrender May 10, 2024
edcb7a4
add repr test
obliviateandsurrender May 10, 2024
59d09de
happy `isort`
obliviateandsurrender May 10, 2024
edb464d
happy `isort`
obliviateandsurrender May 10, 2024
f7465d2
add test
obliviateandsurrender May 10, 2024
09936a6
happy `black`
obliviateandsurrender May 10, 2024
ec1f1c2
happy `isort`
obliviateandsurrender May 10, 2024
d4bfbaf
improve coverage
obliviateandsurrender May 10, 2024
07587a7
improve coverage and simplify bits
obliviateandsurrender May 10, 2024
3d5fe94
Merge branch 'master' into noise-models-1
obliviateandsurrender May 11, 2024
f30501f
happy ci for a while
obliviateandsurrender May 11, 2024
064c6a0
fix test
obliviateandsurrender May 12, 2024
087a007
add docstrings
obliviateandsurrender May 13, 2024
65e158f
add docstrings
obliviateandsurrender May 13, 2024
d806fa3
show in docs
obliviateandsurrender May 13, 2024
72a47e2
tweak
obliviateandsurrender May 13, 2024
75ee072
doc tweak
obliviateandsurrender May 13, 2024
7d92269
doc tweak
obliviateandsurrender May 13, 2024
299a030
Apply suggestions from code review
obliviateandsurrender May 13, 2024
e5d481e
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 13, 2024
4f27312
add support for arithmetic depth
obliviateandsurrender May 14, 2024
2797a53
make lc support robust
obliviateandsurrender May 14, 2024
7fc2dd2
fix coverage
obliviateandsurrender May 14, 2024
d1192b4
simplify doubts
obliviateandsurrender May 14, 2024
823daad
restructure
obliviateandsurrender May 16, 2024
8a2760d
Merge branch 'master' into noise-models-1
obliviateandsurrender May 16, 2024
6cdfda8
add `changelog`
obliviateandsurrender May 16, 2024
0adc86f
add dunder to bitwise
obliviateandsurrender May 17, 2024
f84811e
Merge branch 'master' into noise-models-1
obliviateandsurrender May 17, 2024
ca5adb8
improve coverage
obliviateandsurrender May 17, 2024
4da09b0
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 17, 2024
19c6fff
add doc page
obliviateandsurrender May 17, 2024
9dcd7d0
add docs
obliviateandsurrender May 17, 2024
e2e7a31
Merge branch 'master' into noise-models-1
Jaybsoni May 22, 2024
6caae2a
apply suggestions
obliviateandsurrender May 23, 2024
caf9def
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 23, 2024
dd45dcd
Merge branch 'master' into noise-models-1
obliviateandsurrender May 23, 2024
7e6c332
improve LC comparison
obliviateandsurrender May 26, 2024
d3c5fc6
improve docs
obliviateandsurrender May 27, 2024
0979d6d
add exp check
obliviateandsurrender May 27, 2024
6a565e9
tweak fixes
obliviateandsurrender May 27, 2024
4464bf1
tweak docs
obliviateandsurrender May 28, 2024
8fb77a2
tweak docs
obliviateandsurrender May 28, 2024
eb54e04
docs tweaks
obliviateandsurrender May 29, 2024
2f40fa3
improve docs
obliviateandsurrender May 29, 2024
8922964
little tweaks
obliviateandsurrender May 29, 2024
b08b836
Merge branch 'master' into noise-models-1
Jaybsoni May 29, 2024
c7ca37b
add suggestions
obliviateandsurrender May 29, 2024
4a9e787
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 29, 2024
85b63d1
add suggestions
obliviateandsurrender May 29, 2024
fe011f3
improve docs
obliviateandsurrender May 30, 2024
55ab757
Merge branch 'master' into noise-models-1
obliviateandsurrender May 30, 2024
72a28fe
tweak docs
obliviateandsurrender May 30, 2024
8e5cddf
Merge branch 'master' into noise-models-1
obliviateandsurrender May 31, 2024
636e2d0
Merge branch 'master' into noise-models-1
obliviateandsurrender May 31, 2024
420b845
Merge branch 'master' into noise-models-1
obliviateandsurrender Jun 4, 2024
1eb5d12
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
obliviateandsurrender Jun 6, 2024
c793e39
adapt for controlled
obliviateandsurrender Jun 6, 2024
7088b9c
minor tweak
obliviateandsurrender Jun 7, 2024
accbeda
Merge branch 'master' into noise-models-1
obliviateandsurrender Jun 10, 2024
da1ffb3
add suggestions to docs
obliviateandsurrender Jun 11, 2024
84e3738
minor fixups
obliviateandsurrender Jun 11, 2024
e34f9ad
hopeful final suggestion
obliviateandsurrender Jun 11, 2024
c93e483
Merge branch 'master' into noise-models-1
obliviateandsurrender Jun 11, 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
90 changes: 90 additions & 0 deletions doc/code/qml_noise.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
qml.noise
=========

This module contains the functionality for building and manipulating noise models.
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

Overview
--------

In PennyLane, noise models are defined via a mapping of conditions defined as ``Conditionals``
to functions specified as ``Callables``, along with some additional noise-related metadata.
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

::

NoiseModel: ({Conditionals --> Callables}, metadata)
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

Each ``Conditional`` evaluates the gate operations in the quantum circuit based on some
condition of its attributes (e.g., type, parameters, wires, etc.) and use the corresponding
``Callable`` to apply the noise operations, using the user-provided metadata (e.g., hardware
topologies or relaxation times), whenever the condition results true.
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

.. currentmodule:: pennylane.noise

Conditional Constructors
^^^^^^^^^^^^^^^^^^^^^^^^
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
.. currentmodule:: pennylane.noise.conditionals
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

.. autosummary::
:toctree: api

~op_eq
~op_in
~wires_eq
~wires_in
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
Arbitrary conditionals can also be defined by wrapping the functional form
of custom conditions with the following decorator:
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

.. currentmodule:: pennylane

.. autosummary::
:toctree: api

~BooleanFn

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
.. note::

Conditionals built via these constructors or decorator can be combined using
standard bit-wise operators, such as ``&``, ``|``, ``^``, or ``~``. The resulting
combination will still behave like a single conditional and store the individual
components in the ``operands`` attribute. As Python will evaluate the expression
in the same order, i.e., left to right, the order of composition could matter,
even though bitwise operations are symmetric by definition.
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

Callable Constructor
^^^^^^^^^^^^^^^^^^^^
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
.. currentmodule:: pennylane.noise.conditionals

.. autosummary::
:toctree: api

~partial_wires

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
.. note::

The signature of any user-defined callable must be -
``callable(op: Operation, **kwargs) -> None``, i.e., it accepts
an operation and some metadata-based keyword arguments. It should
then let one queue the noisy gates corresponding to that operation
similar to a quantum function but without returning any measurements.
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
Conditional Classes
^^^^^^^^^^^^^^^^^^^
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

.. currentmodule:: pennylane.noise.conditionals

.. autosummary::
:toctree: api

~OpEq
~OpIn
~WiresEq
~WiresIn

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
Class Inheritence Diagram
^^^^^^^^^^^^^^^^^^^^^^^^^

.. inheritance-diagram:: pennylane.noise.conditionals
:parts: 1
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ PennyLane is **free** and **open source**, released under the Apache License, Ve
code/qml_kernels
code/qml_logging
code/qml_math
code/qml_noise
code/qml_numpy
code/qml_ops_op_math
code/qml_pauli
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 @@ -47,6 +47,8 @@
* The `default.tensor` device is introduced to perform tensor network simulation of a quantum circuit.
[(#5699)](https://github.com/PennyLaneAI/pennylane/pull/5699)

* A new `qml.noise` module which contains utililty functions for building `NoiseModels`.
[(#5674)](https://github.com/PennyLaneAI/pennylane/pull/5674)

<h3>Improvements 🛠</h3>

Expand Down Expand Up @@ -366,6 +368,7 @@
This release contains contributions from (in alphabetical order):

Guillermo Alonso-Linaje,
Utkarsh Azad,
Lillian M. A. Frederiksen,
Gabriel Bottrill,
Astral Cai,
Expand Down
1 change: 1 addition & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
import pennylane.compiler

import pennylane.data
import pennylane.noise

from packaging.specifiers import SpecifierSet
from packaging.version import Version
Expand Down
133 changes: 124 additions & 9 deletions pennylane/boolean_fn.py
trbromley marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -19,13 +19,14 @@
import functools


# pylint: disable=unnecessary-lambda
class BooleanFn:
r"""Wrapper for simple callables with boolean output that can be
manipulated and combined with bit-wise operators.
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved

Args:
fn (callable): Function to be wrapped. It must accept a single
argument, and must return a boolean.
fn (callable): Function to be wrapped. It can accept any number
of arguments, and must return a boolean.

obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
**Example**

Expand Down Expand Up @@ -77,18 +78,132 @@ class BooleanFn:

"""

def __init__(self, fn):
def __init__(self, fn, name=None):
self.fn = fn
self.name = name or self.fn.__name__
functools.update_wrapper(self, fn)

def __and__(self, other):
return BooleanFn(lambda obj: self.fn(obj) and other.fn(obj))
return And(self, other)

def __or__(self, other):
return BooleanFn(lambda obj: self.fn(obj) or other.fn(obj))
return Or(self, other)

def __xor__(self, other):
return Xor(self, other)

def __invert__(self):
return BooleanFn(lambda obj: not self.fn(obj))
return Not(self)

def __call__(self, *args, **kwargs):
return self.fn(*args, **kwargs)

def __repr__(self):
return f"BooleanFn({self.name})" if not (self.bitwise or self.conditional) else self.name

@property
def bitwise(self):
"""Determine whether wrapped callable performs a bit-wise operation or not.
This checks for the ``operands`` attribute that should be defined by it."""
return bool(getattr(self, "operands", tuple()))

@property
def conditional(self):
"""Determine whether wrapped callable is for a conditional or not.
This checks for the ``condition`` attribute that should be defined by it."""
return bool(getattr(self, "condition", None))


class And(BooleanFn):
"""Developer facing class for implemeting bit-wise ``AND`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
right (~.BooleanFn): Right operand in the bit-wise expression.
"""

def __init__(self, left, right):
self.operands = (left, right)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: left(*args, **kwargs) and right(*args, **kwargs),
f"And({left.name}, {right.name})",
)

def __str__(self):
return f"{self.operands[0].name} & {self.operands[1].name}"


class Or(BooleanFn):
"""Developer facing class for implemeting bit-wise ``OR`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
right (~.BooleanFn): Right operand in the bit-wise expression.
"""

def __init__(self, left, right):
self.operands = (left, right)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: left(*args, **kwargs) or right(*args, **kwargs),
f"Or({left.name}, {right.name})",
)

def __str__(self):
return f"{self.operands[0].name} | {self.operands[1].name}"


class Xor(BooleanFn):
"""Developer facing class for implemeting bit-wise ``XOR`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
right (~.BooleanFn): Right operand in the bit-wise expression.
"""

def __init__(self, left, right):
self.operands = (left, right)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: left(*args, **kwargs) ^ right(*args, **kwargs),
f"Xor({left.name}, {right.name})",
)

def __str__(self):
return f"{self.operands[0].name} ^ {self.operands[1].name}"


class Not(BooleanFn):
"""Developer facing class for implemeting bit-wise ``NOT`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
"""

def __init__(self, left):
self.operands = (left,)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: not left(*args, **kwargs),
f"Not({left.name})",
)

def __call__(self, obj):
return self.fn(obj)
def __str__(self):
return f"~{self.operands[0].name}"
16 changes: 16 additions & 0 deletions pennylane/noise/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 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.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module contains the functionality to work with noise models in PennyLane."""

from .conditionals import wires_in, wires_eq, op_in, op_eq, partial_wires
Loading
Loading