-
Notifications
You must be signed in to change notification settings - Fork 575
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
[TEMPLATES] Rewrite subroutines as operations #1192
Conversation
Hadamard(wires=r) | ||
RX(-np.pi / 2, wires=q) | ||
Hadamard(wires=p) | ||
qml.Hadamard(wires=s) |
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.
Just to be consistent...trying to import as little as possible.
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.
I don't know if this matters here, but having objects in a more local namespace improves speed slightly.
For example, calling CNOT(wires=0,1)
is 4% faster than qml.CNOT(wires=(0,1))
, but that is a difference of 3.85 microseconds to 4.01 microseconds. It can add up if something gets called many times, but we usually have bigger things to worry about.
wires1 (Iterable or Wires): Wires of the qubits representing the subset of occupied orbitals | ||
in the interval ``[s, r]``. Accepts an iterable of numbers or strings, or a Wires object, | ||
with minimum length 2. The first wire is interpreted as ``s`` and the last wire as ``r``. | ||
weight (float or tensor_like): angle :math:`\theta` entering the Z rotation acting on wire ``p`` |
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 tensor_like, because the scalar could also be a 0-dim tensor...
the last wire is interpreted as ``p``. Wires in between are acted on with CNOT gates | ||
to compute the parity of the set of qubits. | ||
|
||
Raises: | ||
ValueError: if inputs do not have the correct format | ||
|
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.
PL does not declare "Raises" anywhere else, so removing them from docstrings
|
||
self.wires1 = list(wires1) | ||
self.wires2 = list(wires2) | ||
wires = wires1 + wires2 |
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.
Here I am trying to parse to wires as late as possible (i.e. in the parent function called by super
). This is a result of the insight that parsing to Wires
is costly...
import pennylane as qml | ||
from pennylane.wires import Wires | ||
|
||
|
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.
These tests were just moved for now...
Codecov Report
@@ Coverage Diff @@
## master #1192 +/- ##
=======================================
Coverage 98.12% 98.13%
=======================================
Files 145 145
Lines 10903 10941 +38
=======================================
+ Hits 10699 10737 +38
Misses 204 204
Continue to review full report at Codecov.
|
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.
Looks good!
I left some minor feedback, but nothing that would block merging.
I stopped looking at the tests with as much detail at some point, so I'll trust you on some of that.
.github/CHANGELOG.md
Outdated
from `Operation`, and define the ansatz in their `expand()` method. This | ||
change does not affect the user interface. | ||
[(#1138)](https://github.com/PennyLaneAI/pennylane/pull/1138) | ||
[(#1156)](https://github.com/PennyLaneAI/pennylane/pull/1156) | ||
|
||
For convenience, `BasicEntanglerLayers` has a method that returns the shape of the | ||
trainable parameter tensor, i.e., | ||
For convenience, some templates now have a method that returns the expected |
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.
enumerate which ones?
|
||
# Apply the seventh layer | ||
_layer7(weight, s, r, q, p, set_cnot_wires) | ||
_layer1(weight, s, r, q, p, set_cnot_wires) |
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.
Should we make the layer functions members of the class?
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.
I think it's fine this way - they are not user facing anyways.
Actually, these templates may be deprecated soon!
Hadamard(wires=r) | ||
RX(-np.pi / 2, wires=q) | ||
Hadamard(wires=p) | ||
qml.Hadamard(wires=s) |
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.
I don't know if this matters here, but having objects in a more local namespace improves speed slightly.
For example, calling CNOT(wires=0,1)
is 4% faster than qml.CNOT(wires=(0,1))
, but that is a difference of 3.85 microseconds to 4.01 microseconds. It can add up if something gets called many times, but we usually have bigger things to worry about.
def test_jax(self, tol): | ||
"""Tests the jax interface.""" | ||
|
||
jax = pytest.importorskip("jax") |
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.
👍 got that this time :)
|
||
res = circuit(weights) | ||
res2 = circuit2(weights) | ||
assert qml.math.allclose(res, res2, atol=tol, rtol=0) |
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.
Says list_and_tuples
but only tests for weights as a list. I remember seeing a similar test before that then executed the circuits with:
weights = tuple(weights)
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.
You are right - renamed the test to check a scalar float.
|
||
res = circuit(weights) | ||
res2 = circuit2(weights) | ||
assert qml.math.allclose(res, res2, atol=tol, rtol=0) |
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.
Why do some use qml.math.allclose
but other use np.allclose
?
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.
Because the results of the circuits are tensor objects in the interface that the test used :/
Thanks @albi3ro. About this comment, I did not know about the speed difference. Will keep that in mind! |
This is the fourth PR to refactor the templates (following 1156, 1163 and 1190).
Changes:
expand
function.__init__
function.Drawbacks:
Interferometer
was not refactored, because an operation of that name already exists. Will make a separate PR with a deprecation warning!