-
Notifications
You must be signed in to change notification settings - Fork 603
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
Changes from 59 commits
20eef13
c814e7e
f120900
508bb8b
3d7de97
18bffe2
f82ea4d
86829ee
ad62173
f45dc3e
26f28f9
ac476fa
5b1ad2c
f7feadb
2c25488
2d7bfbf
2e00723
bb32caa
9b9c99b
a897a47
8cd8255
6751e87
f537c39
74a2292
47163f9
9ef7b88
bdf7ba8
d61bd16
6d2d310
eb8e852
8d3b944
4e7d83c
d969314
089554f
1d4eae1
3f9585d
a0b2150
aaef07a
13f55f0
6705bd5
18b75df
7b31827
84890ff
1d03db1
1ad2d3c
7ca926e
035788e
1a652a7
cf7e012
50a3573
6416ca8
7a30274
c5f9e11
01270d4
40365a8
a8536e6
6bc260b
e488f57
78f060d
0825da4
4e9dfd4
9a6dda6
85c2e6c
c1c9ea0
98d9340
0ba330d
bbfe092
1a09b8c
75099f0
6a107e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it intended for snapshots to show up here? 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Though There was a problem hiding this comment. Choose a reason for hiding this commentThe 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──┤ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added 👍🏼