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

Adding documentation for qml.breakpoint() and qml.PLDB #5789

Merged
merged 70 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
20eef13
implement breakpoint()
Jaybsoni Apr 30, 2024
c814e7e
added docstring and tests
Jaybsoni Apr 30, 2024
f120900
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni Apr 30, 2024
508bb8b
format
Jaybsoni Apr 30, 2024
3d7de97
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni May 7, 2024
18bffe2
Add missing test coverage
Jaybsoni May 10, 2024
f82ea4d
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni May 10, 2024
86829ee
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni May 21, 2024
ad62173
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni May 23, 2024
f45dc3e
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni May 23, 2024
26f28f9
Merge branch 'master' into algo_debug_breakpoint
Jaybsoni May 27, 2024
ac476fa
Added support for measurements
Jaybsoni May 28, 2024
5b1ad2c
Added tests
Jaybsoni May 28, 2024
f7feadb
Address code review comments
Jaybsoni May 30, 2024
2c25488
initial commit
Jaybsoni May 30, 2024
2d7bfbf
Merge branch 'algo_debug_breakpoint' into algo_debug_measurements
Jaybsoni May 30, 2024
2e00723
add context manager + address code review comments
Jaybsoni May 30, 2024
bb32caa
Merge branch 'master' into debugging_feature
Jaybsoni May 30, 2024
9b9c99b
merge
Jaybsoni May 30, 2024
a897a47
[skip ci]
Jaybsoni May 30, 2024
8cd8255
merge [skip ci]
Jaybsoni May 30, 2024
6751e87
fix typo
Jaybsoni May 31, 2024
f537c39
pull class method back into class
Jaybsoni May 31, 2024
74a2292
Add probs support
Jaybsoni Jun 3, 2024
47163f9
Merge branch 'master' into debugging_feature
Jaybsoni Jun 3, 2024
9ef7b88
[skip ci]
Jaybsoni Jun 3, 2024
bdf7ba8
[skip ci]
Jaybsoni Jun 3, 2024
d61bd16
initial commit
Jaybsoni Jun 3, 2024
6d2d310
[skip ci]
Jaybsoni Jun 3, 2024
eb8e852
fix output, [skip ci]
Jaybsoni Jun 3, 2024
8d3b944
[skip ci]
Jaybsoni Jun 3, 2024
4e7d83c
Added doc-strings [skip ci]
Jaybsoni Jun 4, 2024
d969314
fix render, [skip ci]
Jaybsoni Jun 4, 2024
089554f
Added main docs page
Jaybsoni Jun 4, 2024
1d4eae1
update module doc, [skip ci]
Jaybsoni Jun 4, 2024
3f9585d
expand state to device wires
Jaybsoni Jun 4, 2024
a0b2150
[skip ci]
Jaybsoni Jun 4, 2024
aaef07a
Finished docs
Jaybsoni Jun 5, 2024
13f55f0
Apply suggestions from code review
Jaybsoni Jun 5, 2024
6705bd5
Merge branch 'master' into debugging_feature
Jaybsoni Jun 5, 2024
18b75df
[skip ci]
Jaybsoni Jun 5, 2024
7b31827
Addressed code review comments
Jaybsoni Jun 5, 2024
84890ff
format tests
Jaybsoni Jun 5, 2024
1d03db1
fix bugs
Jaybsoni Jun 5, 2024
1ad2d3c
merge base branch, [skip ci]
Jaybsoni Jun 5, 2024
7ca926e
missing test, [skip ci]
Jaybsoni Jun 5, 2024
035788e
Merge branch 'algo_debug_measurements' into algo_debug_docs
Jaybsoni Jun 5, 2024
1a652a7
Implement `qml.breakpoint()` and initial integration with `Pdb` (#5600)
Jaybsoni Jun 6, 2024
cf7e012
Support dynamic measurements with debugger (#5749)
Jaybsoni Jun 7, 2024
50a3573
Merge branch 'debugging_feature' into algo_debug_docs
Jaybsoni Jun 7, 2024
6416ca8
Apply suggestions from code review
Jaybsoni Jun 7, 2024
7a30274
Merge branch 'master' into algo_debug_docs
Jaybsoni Jun 7, 2024
c5f9e11
Apply suggestions from code review
Jaybsoni Jun 10, 2024
01270d4
addressed code review
Jaybsoni Jun 11, 2024
40365a8
small typo
Jaybsoni Jun 11, 2024
a8536e6
fix merge conflicts
Jaybsoni Jun 13, 2024
6bc260b
[skip ci]
Jaybsoni Jun 13, 2024
e488f57
Apply suggestions from code review
Jaybsoni Jun 13, 2024
78f060d
fix merge conflict
Jaybsoni Jun 13, 2024
0825da4
Update naming
Jaybsoni Jun 13, 2024
4e9dfd4
Fix link
Jaybsoni Jun 13, 2024
9a6dda6
fix broken link [skip-ci]
Jaybsoni Jun 14, 2024
85c2e6c
maybe this?
Jaybsoni Jun 14, 2024
c1c9ea0
maybe this>?
Jaybsoni Jun 14, 2024
98d9340
Merge branch 'master' into algo_debug_docs
Jaybsoni Jun 14, 2024
0ba330d
remove example
Jaybsoni Jun 14, 2024
bbfe092
Merge branch 'master' into algo_debug_docs
Jaybsoni Jun 17, 2024
1a09b8c
changelog example
DSGuala Jun 17, 2024
75099f0
re-remove changelog example
DSGuala Jun 20, 2024
6a107e0
Merge branch 'master' into algo_debug_docs
Jaybsoni Jun 20, 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
222 changes: 222 additions & 0 deletions doc/code/qml_debugging.rst
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to this module, it would be nice to have a short section just below here in the quickstart.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 👍🏼

Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
qml.debugging
=============

.. automodapi:: pennylane.debugging
:no-heading:
:no-inherited-members:
:skip: PLDB
:skip: pldb_device_manager
Comment on lines +4 to +8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intended for snapshots to show up here? 🤔
Overall, it might make sense. Just curious.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though snapshots is also a top-level accessible function but it's showing up as qml.debugging.snapshots

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intended on purpose to place snapshots here. Originally, the snapshots logic and the debugger were both located in the same python file.


Entering the Debugging Context
------------------------------

The :func:`~.breakpoint <qml.breakpoint()>` function provides an interface for interacting with and
Jaybsoni marked this conversation as resolved.
Show resolved Hide resolved
stepping through a quantum circuit during execution. It allows for faster debugging
by providing access to the internal state of the circuit and the ``QuantumTape`` as
the circuit operations are applied. The functionality is highlighted by the example
circuit below.

.. code-block:: python

import pennylane as qml

@qml.qnode(qml.device('default.qubit', wires=(0,1,2)))
def circuit(x):
qml.breakpoint()

qml.Hadamard(wires=0)
qml.CNOT(wires=(0,2))

for w in (0, 1, 2):
qml.RX(2*x, wires=w)

qml.breakpoint()
qml.RX(-x, wires=1)
return qml.sample()

circuit(1.2345)

Running the above python script opens up the interactive ``[pldb]:`` prompt in the terminal.
When this code reaches ``qml.breakpoint()`` it will pause and launch an interactive
debugging prompt. The prompt specifies the path to the script and the next line to be
executed after the breakpoint:

.. code-block:: console

> /Users/your/path/to/script.py(7)circuit()
-> qml.Hadamard(wires=0)
[pldb]:

Controlling Code Execution in the Debugging Context
---------------------------------------------------

The Pennylane Debugger (PLDB) is built from the native python debugger (Pdb), as such
it shares a similar interface. We can interact with the debugger using the
builtin commands: ``list``, ``longlist``, ``next``, ``continue``, and ``quit``. Any
variables defined in the scope of the quantum function can also be accessed from the
debugger.

.. code-block:: console

[pldb]: print(x)
1.2345

The ``list`` (and ``longlist``) command will print a section of code around the
breakpoint, highlighting the next line to be executed. This can be used to determine
the location of execution in the circuit.

.. code-block:: console

[pldb]: longlist
3 @qml.qnode(qml.device('default.qubit', wires=(0,1,2)))
4 def circuit(x):
5 qml.breakpoint()
6
7 -> qml.Hadamard(wires=0)
8 qml.CNOT(wires=(0,2))
9
10 for w in (0, 1, 2):
11 qml.RX(2*x, wires=w)
12
13 qml.breakpoint()
14 qml.RX(-x, wires=1)
15 return qml.sample()

The ``next`` command will execute the next line of code, and print the following
line to be executed, e.g., the next operation to execute is ``CNOT``.

.. code-block:: console

[pldb]: next
> /Users/your/path/to/script.py(8)circuit()
-> qml.CNOT(wires=(0,2))
[pldb]: list
3 @qml.qnode(qml.device('default.qubit', wires=(0,1,2)))
4 def circuit(x):
5 qml.breakpoint()
6
7 qml.Hadamard(wires=0)
8 -> qml.CNOT(wires=(0,2))
9
10 for w in (0, 1, 2):
11 qml.RX(2*x, wires=w)
12
13 qml.breakpoint()

Alternative, the ``continue`` command allows for jumping between breakpoints. This command resumes
code execution until the next breakpoint is reached. Finally, the ``quit`` command
ends the debugging prompt.

.. code-block:: console

[pldb]: continue
> /Users/your/path/to/script.py(14)circuit()
-> qml.RX(-x, wires=1)
[pldb]: list
9
10 for w in (0, 1, 2):
11 qml.RX(2*x, wires=w)
12
13 qml.breakpoint()
14 -> qml.RX(-x, wires=1)
15 return qml.sample()
16
17 circuit(1.2345)
[EOF]
[pldb]: quit


Extracting Circuit Information
------------------------------

While in the debugging prompt, we can extract information and perform measurements
on the qunatum circuit. Specifically we can make measurements using
:func:`~pennylane.debugging.expval`, :func:`~pennylane.debugging.state`,
:func:`~pennylane.debugging.probs`, and access the gates in the circuit using
:func:`~pennylane.debugging.tape`.

Consider the circuit from above,

.. code-block:: console

> /Users/your/path/to/script.py(7)circuit()
-> qml.Hadamard(wires=0)
[pldb]: longlist
3 @qml.qnode(qml.device('default.qubit', wires=(0,1,2)))
4 def circuit(x):
5 qml.breakpoint()
6
7 -> qml.Hadamard(wires=0)
8 qml.CNOT(wires=(0,2))
9
10 for w in (0, 1, 2):
11 qml.RX(2*x, wires=w)
12
13 qml.breakpoint()
14 qml.RX(-x, wires=1)
15 return qml.sample()
[pldb]: next
> /Users/your/path/to/script.py(8)circuit()
-> qml.CNOT(wires=(0,2))
[pldb]: next
> /Users/your/path/to/script.py(10)circuit()
-> for w in (0, 1, 2):
[pldb]:

All of the operations applied so far are tracked in the circuit's ``QuantumTape``
which is accessible using :func:`~pennylane.debugging.tape`. This can be used to
*visually* debug the circuit.

.. code-block:: console

[pldb]: qtape = qml.debugging.tape()
[pldb]: qtape.operations
[Hadamard(wires=[0]), CNOT(wires=[0, 2])]
[pldb]: print(qtape.draw())
0: ──H─╭●─┤
2: ────╰X─┤

The quantum state of the circuit at this point can be extracted using
:func:`~pennylane.debugging.state`. The associated probability distribution
for the wires of interest can be probed using :func:`~pennylane.debugging.probs`.

.. code-block:: console

[pldb]: qml.debugging.state()
array([0.70710678+0.j, 0. +0.j, 0. +0.j, 0. +0.j,
0. +0.j, 0.70710678+0.j, 0. +0.j, 0. +0.j])
[pldb]: qml.debugging.probs(wires=(0,2))
array([0.5, 0. , 0. , 0.5])

Another method for probing the system is by measuring observables via
:func:`~pennylane.debugging.expval`.

.. code-block:: console

[pldb]: qml.debugging.expval(qml.Z(0))
0.0
[pldb]: qml.debugging.expval(qml.X(0)@qml.X(2))
0.9999999999999996

Additionally, the quantum circuit can be dynamically updated by adding gates directly
from the prompt. This allows users to modify the circuit *on-the-fly*!

.. code-block:: console

[pldb]: continue
> /Users/your/path/to/script.py(14)circuit()
-> qml.RX(-x, wires=1)
[pldb]: qtape = qml.debugging.tape()
[pldb]: print(qtape.draw(wire_order=(0,1,2)))
0: ──H─╭●──RX─┤
1: ────│───RX─┤
2: ────╰X──RX─┤
[pldb]: qml.RZ(0.5*x, wires=0)
RZ(0.61725, wires=[0])
[pldb]: qml.CZ(wires=(1,2))
CZ(wires=[1, 2])
[pldb]: qtape = qml.debugging.tape()
[pldb]: print(qtape.draw(wire_order=(0,1,2)))
0: ──H─╭●──RX──RZ─┤
1: ────│───RX─╭●──┤
2: ────╰X──RX─╰Z──┤
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ PennyLane is **free** and **open source**, released under the Apache License, Ve
code/qml
code/qml_compiler
code/qml_data
code/qml_debugging
code/qml_drawer
code/qml_fermi
code/qml_fourier
Expand Down
52 changes: 52 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,58 @@

<h3>New features since last release</h3>

* Added a quantum debugger (`PLDB`) which interfaces via `qml.breakpoint()` and provides tools for
Jaybsoni marked this conversation as resolved.
Show resolved Hide resolved
debugging quantum circuits. Users can step through the quantum circuit operations, dynamically
queue operations and make measurements using (`qml.debugging.state()`, `qml.debugging.probs()`,
`qml.debugging.expval()`, and `qml.debugging.tape()`). Consider the following python script
containing the quantum circuit with breakpoints.
[(#5680)](https://github.com/PennyLaneAI/pennylane/pull/5680)
[(#5749)](https://github.com/PennyLaneAI/pennylane/pull/5749)
[(#5789)](https://github.com/PennyLaneAI/pennylane/pull/5789)

```python
dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev)
def circuit(x):
qml.breakpoint()
qml.RX(x, wires=0)
qml.Hadamard(wires=1)
qml.breakpoint()
qml.CNOT(wires=[0, 1])
return qml.expval(qml.Z(0))

circuit(1.23)
```

Running the above python script opens up the interactive :code:`[pldb]:` prompt in the terminal.

```console
> /Users/your/path/to/script.py(8)circuit()
-> qml.RX(x, wires=0)
[pldb]: x
1.23
[pldb]: list
3
4 @qml.qnode(dev)
5 def circuit(x):

Check warning on line 41 in doc/releases/changelog-dev.md

View workflow job for this annotation

GitHub Actions / sphinx

Inline literal start-string without end-string.

Check warning on line 41 in doc/releases/changelog-dev.md

View workflow job for this annotation

GitHub Actions / sphinx

Inline interpreted text or phrase reference start-string without end-string.
6 qml.breakpoint()
7
8 -> qml.RX(x, wires=0)
9 qml.Hadamard(wires=1)
10
11 qml.breakpoint()
12
13 qml.CNOT(wires=[0, 1])
[pldb]: next
> /Users/your/path/to/script.py(9)circuit()
-> qml.Hadamard(wires=1)
[pldb]: continue
> /Users/your/path/to/script.py(13)circuit()
-> qml.CNOT(wires=[0, 1])
[pldb]: quit
```

* The `default.tensor` device now supports the `tn` method to simulate quantum circuits using exact tensor networks.
[(#5786)](https://github.com/PennyLaneAI/pennylane/pull/5786)

Expand All @@ -19,7 +71,7 @@
@qml.qnode(dev)
def circuit():

# the third index is encoded in the control wires [0, 1]

Check warning on line 74 in doc/releases/changelog-dev.md

View workflow job for this annotation

GitHub Actions / sphinx

Inline literal start-string without end-string.

Check warning on line 74 in doc/releases/changelog-dev.md

View workflow job for this annotation

GitHub Actions / sphinx

Inline interpreted text or phrase reference start-string without end-string.
qml.BasisEmbedding(2, wires = [0,1])

qml.QROM(bitstrings = bitstrings,
Expand Down
Loading
Loading