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

Test for comparing different devices with the default device #897

Merged
merged 73 commits into from
Dec 9, 2020

Conversation

alejomonbar
Copy link
Contributor

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 the
    change, 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 then
    run 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:

@codecov
Copy link

codecov bot commented Nov 11, 2020

Codecov Report

Merging #897 (4883be5) into master (ce7c1de) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #897   +/-   ##
=======================================
  Coverage   97.85%   97.85%           
=======================================
  Files         147      147           
  Lines       10127    10127           
=======================================
  Hits         9910     9910           
  Misses        217      217           
Impacted Files Coverage Δ
qchem/pennylane_qchem/qchem/structure.py 96.66% <ø> (ø)
pennylane/templates/utils.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ce7c1de...4883be5. Read the comment docs.

@trbromley
Copy link
Contributor

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.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""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.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""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):
Copy link
Contributor

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.

Suggested change
def test_pauliz_expectation(self, device, tol):
def test_pauliz_expectation_analytic(self, device, tol):

Copy link
Contributor

@antalszava antalszava left a 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.

Copy link
Contributor

@trbromley trbromley left a 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):
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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))
Copy link
Contributor

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))

Copy link
Contributor Author

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.

Copy link
Member

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!

@alejomonbar
Copy link
Contributor Author

@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 git push -f. Here is the file with the updates baf7ded

@co9olguy
Copy link
Member

Thanks @alejomonbar for contributing!

As a tip related to best practices, try not to use the -f option when pushing. This will do a "force push", which (potentially) overwrites the existing version control history. In this case, I don't think it's done any harm, but if other users have been working on the same remote branch, it could cause their version control history to break

@alejomonbar
Copy link
Contributor Author

@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.

@co9olguy
Copy link
Member

Thanks @alejomonbar. Did you run black with a line-limit of 100 characters? (our default is different than black's default)
i.e., use black -l 100 on the file test_compare_default_qubit.py

from pennylane import numpy as np
import pytest
from flaky import flaky
from pennylane.templates.layers import RandomLayers
Copy link
Contributor

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.

Copy link
Contributor

@antalszava antalszava left a 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.

@josh146
Copy link
Member

josh146 commented Dec 1, 2020

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

@josh146 josh146 added the review-ready 👌 PRs which are ready for review by someone from the core team. label Dec 1, 2020
@alejomonbar
Copy link
Contributor Author

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.
Yes, that's the version.

@co9olguy
Copy link
Member

co9olguy commented Dec 3, 2020

Looks like all tests are now passing! 💪

@co9olguy
Copy link
Member

co9olguy commented Dec 3, 2020

@antalszava @josh146 @trbromley where do we currently stand in the code review process?

@trbromley
Copy link
Contributor

Thanks @alejomonbar for the progress! I'm looking forward to take another look at this, hoping to do so tomorrow morning.

@antalszava
Copy link
Contributor

As the formatting is completed now, this one is good to go from my side. 💯

@trbromley
Copy link
Contributor

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 👍

Copy link
Contributor

@trbromley trbromley left a 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! 💯

pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
Comment on lines 15 to 24
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
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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.

Copy link
Contributor

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).

Copy link
Contributor

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?

Copy link
Contributor

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.

pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
Comment on lines +170 to +191
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,
]
Copy link
Contributor

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?

Copy link
Contributor

@antalszava antalszava Dec 7, 2020

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).

pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
alejomonbar and others added 2 commits December 8, 2020 08:01
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Copy link
Contributor

@trbromley trbromley left a comment

Choose a reason for hiding this comment

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

Thanks @alejomonbar!

pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
pennylane/devices/tests/test_compare_default_qubit.py Outdated Show resolved Hide resolved
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
@alejomonbar
Copy link
Contributor Author

Thanks @alejomonbar!

Thank you to you all for helping me through this process. Eager to continue learning and helping the Pennylane community.
@trbromley @josh146 @antalszava

@trbromley
Copy link
Contributor

Thanks @alejomonbar, one last thing I remembered - don't forget to update the CHANGELOG.md with a brief summary of this contribution as well as adding your name as a contributor.

We're very keen for additional contributions, and have been recently posting suggestions for what to work on in our issues page.

@alejomonbar
Copy link
Contributor Author

Thanks @alejomonbar, one last thing I remembered - don't forget to update the CHANGELOG.md with a brief summary of this contribution as well as adding your name as a contributor.

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 CHANGELOG.md. In # Release 0.14.0-dev (development release) should I add it as Improvements ?

@trbromley
Copy link
Contributor

Thanks @alejomonbar, one last thing I remembered - don't forget to update the CHANGELOG.md with a brief summary of this contribution as well as adding your name as a contributor.
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 CHANGELOG.md. In # Release 0.14.0-dev (development release) should I add it as Improvements ?

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.

@antalszava antalszava merged commit e1fb824 into PennyLaneAI:master Dec 9, 2020
@antalszava
Copy link
Contributor

🌟 🎊

* 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)
Copy link
Contributor

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review-ready 👌 PRs which are ready for review by someone from the core team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.