-
Notifications
You must be signed in to change notification settings - Fork 600
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
Test for comparing different devices with the default device #897
Conversation
Updating my master branch
Codecov Report
@@ Coverage Diff @@
## master #897 +/- ##
=======================================
Coverage 97.85% 97.85%
=======================================
Files 147 147
Lines 10127 10127
=======================================
Hits 9910 9910
Misses 217 217
Continue to review full report at Codecov.
|
Thanks @alejomonbar this looks great! We'll take a look asap! |
pytest.skip("Skipped because device does not support the Hermitian observable.") | ||
|
||
if dev.name == dev_def.name: | ||
pytest.skip("Device is the default.qubit.") |
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.
pytest.skip("Device is the default.qubit.") | |
pytest.skip("Device is default.qubit.") |
assert np.allclose(grad(theta, phi), grad_def(theta, phi), atol=tol(dev.analytic)) | ||
|
||
def test_pauliz_expectation(self, device, tol): | ||
"""Test that PauliZ expectation value is correct""" |
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.
"""Test that PauliZ expectation value is correct""" | |
"""Test that the PauliZ expectation value is correct""" |
dev = device(n_wires) | ||
dev_def = qml.device("default.qubit", wires=n_wires) | ||
if dev.name == dev_def.name: | ||
pytest.skip("Device is the default.qubit.") |
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.
pytest.skip("Device is the default.qubit.") | |
pytest.skip("Device is default.qubit.") |
dev = device(n_wires) | ||
dev_def = qml.device("default.qubit", wires=n_wires) | ||
if dev.name == dev_def.name: | ||
pytest.skip("Device is the default.qubit.") |
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.
pytest.skip("Device is the default.qubit.") | |
pytest.skip("Device is default.qubit.") |
assert np.allclose(grad(theta, phi), grad_def(theta, phi), atol=tol(dev.analytic)) | ||
|
||
def test_random_circuit(self, device, tol): | ||
"""Test that random expectation value is correct""" |
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.
"""Test that random expectation value is correct""" | |
"""Test that the random expectation value is correct""" |
assert np.allclose(qnode(theta, phi), qnode_def(theta, phi), atol=tol(dev.analytic)) | ||
assert np.allclose(grad(theta, phi), grad_def(theta, phi), atol=tol(dev.analytic)) | ||
|
||
def test_pauliz_expectation(self, device, tol): |
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.
(Minor suggestion): could be worth including in the name, that the test targets devices run in analytic mode.
def test_pauliz_expectation(self, device, tol): | |
def test_pauliz_expectation_analytic(self, device, tol): |
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.
Hi @alejomonbar, had a look at the addition, this is looking really great and useful! 🙂 🎊
Left a couple of comments/suggestions. One main change that would be nice to have is the ability to skip tests that use tensor observables.
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.
Thanks @alejomonbar, looking good so far! I've left a few comments. Don't forget to update the changelog. Cheers!
|
||
@flaky(max_runs=10) | ||
class TestQubit: | ||
def test_easy_circuit(self, device, tol): |
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.
def test_easy_circuit(self, device, tol): | |
def test_hermitian_expectation(self, device, tol): |
|
||
def circuit(weights): | ||
RandomLayers(weights, wires=range(n_wires)) | ||
return qml.expval(qml.PauliZ(wires=0) @ qml.PauliX(wires=1)) |
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.
It would be cool to also have a pytest parametrization over return types that apply to observables, e.g.
@pytest.mark.parametrize("ret", [qml.expval, qml.sample, qml.var])
def test_random_circuit(self, device, tol, ret):
...
return ret(qml.PauliZ(wires=0) @ qml.PauliX(wires=1))
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 not completely sure but I think I cannot use qml.samples with qml.grad. Let me know if I can set this test with qml.samples. I implemented the other two in this random circuit. By the way, thank you for the feedback.
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.
@alejomonbar that's correct, qml.sample
does not currently support gradients. Feel free to remove it from the parametrization!
@josh146 @trbromley @antalszava Thank you for your suggestions, I made some changes. I'm not sure if I did it correctly. I'm new updating repositories on GitHub, I used |
Thanks @alejomonbar for contributing! As a tip related to best practices, try not to use the |
@josh146 @antalszava does this solution works or should I do something else? By the way, I used Black to reformat the new file but it does not pass the test. Also, I included a function that randomly select gates from a set of gates for the last test. |
Thanks @alejomonbar. Did you run |
from pennylane import numpy as np | ||
import pytest | ||
from flaky import flaky | ||
from pennylane.templates.layers import RandomLayers |
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 codefactor warnings could be resolved by running isort
on this file. isort
can be installed with pip
and it sorts the imports in the expected order.
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.
Hi @alejomonbar, thank you so much for the adjustments! Overall the addition looks good to me. 🎊 💯
The last thing that remains would be to update the imports and format using black
(let us know if that doesn't come along). After that, this would be merge-ready from my side.
Hi @alejomonbar, I just pushed a fix that will hopefully fix the CI issue! With respect to black, are you using the latest version of Black? On the CI check, we are using the following version: $ black --version
black, version 20.8b1 |
Hi @josh146. |
Looks like all tests are now passing! 💪 |
@antalszava @josh146 @trbromley where do we currently stand in the code review process? |
Thanks @alejomonbar for the progress! I'm looking forward to take another look at this, hoping to do so tomorrow morning. |
As the formatting is completed now, this one is good to go from my side. 💯 |
I will probably not get a chance to review this until early next week. If it's good to merge, don't let me be a blocker 👍 |
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.
Thanks @alejomonbar, some really nice tests! I have a few more suggestions, but this seems pretty close to merging! Thanks for the contribution! 💯
import random | ||
|
||
import pytest | ||
from flaky import flaky | ||
|
||
import pennylane as qml | ||
|
||
# pylint: disable=no-self-use | ||
from pennylane import numpy as np | ||
from pennylane.templates.layers import RandomLayers |
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.
import random | |
import pytest | |
from flaky import flaky | |
import pennylane as qml | |
# pylint: disable=no-self-use | |
from pennylane import numpy as np | |
from pennylane.templates.layers import RandomLayers | |
import random | |
# pylint: disable=no-self-use | |
import numpy as np | |
import pytest | |
from flaky import flaky | |
import pennylane as qml | |
from pennylane.templates.layers import RandomLayers |
^ Main change was that I believe we don't need from pennylane import numpy as np
and instead import numpy as np
is sufficient. Then the rest is a run of isort
.
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.
@trbromley adding from pennylane import numpy as np
was a suggestion from my part previously (see #897 (comment)). Maybe we could leave a comment here to make it explicit, e.g., (# Importing NumPy from PennyLane to test the environment demonstrations use
or something similar).
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.
Thanks @antalszava! Sure I'm potentially happy to have from pennylane import numpy as np
(although would be good to add a no-member
to the pylint disable).
What do you mean about environment demonstrations? As in the demos here?
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.
Yep, some demos (e.g., Variational classifier, Quanvolutional Neural Networks) have this import and use arrays to represent data. When processing user questions it turned out that the difference between using a pennylane.numpy.tensor
instead of the original np.array
can result in errors due to bugs.
Perhaps the word environment
is not the best to use here, could also go with # Importing NumPy from PennyLane to use similar imports as in QML demonstrations
or something better.
gates = [ | ||
qml.PauliX, | ||
qml.PauliY, | ||
qml.PauliZ, | ||
qml.S, | ||
qml.T, | ||
qml.RX, | ||
qml.RY, | ||
qml.RZ, | ||
qml.Hadamard, | ||
qml.Rot, | ||
qml.CRot, | ||
qml.Toffoli, | ||
qml.SWAP, | ||
qml.CSWAP, | ||
qml.U1, | ||
qml.U2, | ||
qml.U3, | ||
qml.CRX, | ||
qml.CRY, | ||
qml.CRZ, | ||
] |
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.
@antalszava @josh146 is there a way in PL to automate the creation of this list, so that it goes over all defined ops?
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.
Could go with [getattr(qml, op) for op in qml.ops.qubit.__all__]
. This will dynamically pull every operation that was defined in qml.ops.qubit.__all__
(that is care needs to be taken if some operations are meant to be explicitly excluded).
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
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.
Thanks @alejomonbar!
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Thank you to you all for helping me through this process. Eager to continue learning and helping the Pennylane community. |
Thanks @alejomonbar, one last thing I remembered - don't forget to update the We're very keen for additional contributions, and have been recently posting suggestions for what to work on in our issues page. |
I'm not completely sure about how to edit the |
Yes, you can add a few lines in the improvements of 0.14.0-dev. This should follow the established style, with a link to the PR at the end. |
🌟 🎊 |
* A new test series, pennylane/devices/tests/test_compare_default_qubit.py, has been added, allowing to test if | ||
a chosen device gives the same result as the default device. Three tests are added `test_hermitian_expectation`, | ||
`test_pauliz_expectation_analytic`, and `test_random_circuit`. | ||
[(#848)](https://github.com/PennyLaneAI/pennylane/pull/848) |
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.
(we may want to update to 897, better to link to the PR than the issue)
Before submitting
Please complete the following checklist when submitting a PR:
All new features must include a unit test.
If you've fixed a bug or added code that should be tested, add a test to the
test directory!
All new functions and code must be clearly commented and documented.
If you do make documentation changes, make sure that the docs build and
render correctly by running
make docs
.Ensure that the test suite passes, by running
make test
.Add a new entry to the
.github/CHANGELOG.md
file, summarizing thechange, and including a link back to the PR.
The PennyLane source code conforms to
PEP8 standards.
We check all of our code against Pylint.
To lint modified files, simply
pip install pylint
, and thenrun
pylint pennylane/path/to/file.py
.When all the above are checked, delete everything above the dashed
line and fill in the pull request template.
Context:
The solution to Issue #848
Description of the Change:
New file to test if a device different from the default device gives the same results that the default device.
Benefits:
Possible Drawbacks:
Related GitHub Issues: