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

Refactor template tests #409

Merged
merged 45 commits into from
Nov 13, 2019
Merged

Refactor template tests #409

merged 45 commits into from
Nov 13, 2019

Conversation

mariaschuld
Copy link
Contributor

@mariaschuld mariaschuld commented Nov 8, 2019

Context: This PR is part of the templates redesign.

Description of the Change: Heavily improves and extends the integration tests. They are now fully automated, so that a developer only has to add the template and inputs to be tested into a list, and it gets automatically tested for different interfaces and different ways to pass parameters.

Benefits: Simpler, more elegant and more extensive tests.

Possible Drawbacks: This PR necessarily contains the small changes in PR #403, which fixes how the templates iterate through weight arrays (making it compatible with tensorflow). I would therefore recommend merging #403 first.

Tests that will be added are integrations for different hyperparameters. However, these tests will fail at the moment, an issue addressed in a separate PR (which will also update the tests).

Related GitHub Issues: -

@codecov
Copy link

codecov bot commented Nov 8, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@9c4eb72). Click here to learn what that means.
The diff coverage is 100%.

@@            Coverage Diff            @@
##             master     #409   +/-   ##
=========================================
  Coverage          ?   99.24%           
=========================================
  Files             ?       42           
  Lines             ?     3030           
  Branches          ?        0           
=========================================
  Hits              ?     3007           
  Misses            ?       23           
  Partials          ?        0
Impacted Files Coverage Δ
pennylane/templates/layers.py 100% <100%> (ø)

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 9c4eb72...97dd76b. Read the comment docs.

@mariaschuld mariaschuld requested review from josh146 and co9olguy and removed request for josh146 November 8, 2019 07:28
Copy link
Member

@co9olguy co9olguy left a comment

Choose a reason for hiding this comment

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

Left a few minor suggestions. My main question is whether the list comprehension which explicitly casts each entry to a numpy array might be masking anything, i.e., shouldn't we also check the cases where the inputs are standard python numbers? Or are there no situations like this, due to how the parameters of a layer are structured?

tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
mariaschuld and others added 5 commits November 8, 2019 17:16
Co-Authored-By: Nathan Killoran <co9olguy@users.noreply.github.com>
Co-Authored-By: Nathan Killoran <co9olguy@users.noreply.github.com>
Co-Authored-By: Nathan Killoran <co9olguy@users.noreply.github.com>
This was referenced Nov 11, 2019
@mariaschuld mariaschuld self-assigned this Nov 11, 2019
@mariaschuld mariaschuld added templates 📁 Updates and additions to the templates review-ready 👌 PRs which are ready for review by someone from the core team. labels Nov 11, 2019
Copy link
Member

@josh146 josh146 left a comment

Choose a reason for hiding this comment

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

Nice work @mariaschuld!

There are two things I think that are missing though:

  • An integration test for the def circuit(weights): pattern a user might try

  • Gradient tests. Something simple, such as doing qml.grad(), torch.backwards() and tape.grad() for each of the three interfaces, and making sure this does not raise an exception or return None. Especially working on the VQE module, I found cases where evaluating a circuit with templates would work fine, but then the gradient would raise an exception with TF.

    Note: with the latter, interface parametrization won't work --- better to have a gradient test class per interface

tests/conftest.py Show resolved Hide resolved
tests/test_templates.py Show resolved Hide resolved
tests/test_templates.py Show resolved Hide resolved
@josh146
Copy link
Member

josh146 commented Nov 12, 2019

Oh, another thought - could you also add the test case that you know fails (using the class instead of the decorator), but mark it as xfail using Pytest? That way we have a benchmark for when it is fixed 🙂

@mariaschuld
Copy link
Contributor Author

Working on the grad tests and the xfail one.

Isn't the case circuit(weights) covered by test_integration_XX_args in test_templates.py? Only that the number of weights is dynamically inferred.

@mariaschuld
Copy link
Contributor Author

Thinking about it - it is major code duplication to add the xfail tests, which would then test something that is completely unrelated to templates.

I suggest we rather add a test to qnode itself.

Copying the MWE here:

import pennylane as qml
import torch

inpts = [[1], [2]]
inpts = [torch.tensor(i) for i in inpts]
dev = qml.device('default.qubit', wires=2)

# Decorator version works well: 
qml.qnode(dev, interface='torch')
def circuit1(*inp_):
    return qml.expval(qml.PauliX(1))
print("Works:", circuit1(*inpts))

# Manual version fails: 
def circuit2(*inp_):
    return qml.expval(qml.PauliX(1))
circuit2 = qml.QNode(circuit2, dev)
circuit2.to_torch()
print("Fails:", circuit2(*inpts))

@mariaschuld
Copy link
Contributor Author

From discussion with @josh146 :

  • The xfail to keep track of a bug in manual qnode construction has to be added in another module.
  • For now we will limit the test to the elegant circuit(*weights) signature, since it would require a very complex rewrite to also include circuit(weights) [however, we should keep an eye on this because interfaces may have some exotic differences in how the cases are handled].
  • Gradient tests are now added

Copy link
Member

@co9olguy co9olguy left a comment

Choose a reason for hiding this comment

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

Thanks @mariaschuld. I only have a couple small questions and comments, but nothing to block merging

pennylane/templates/layers.py Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
tests/test_templates.py Outdated Show resolved Hide resolved
n_wires = len(wires)
if n_wires > 1:
for i in range(n_wires):
imprimitive(wires=[wires[i], wires[(i + r) % n_wires]])

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is smuggled in from a later PR, but it makes the tests run with 1 wire as well...

class TestParameterIntegration:
""" Integration tests for the parameter generation methods from pennylane.init
and pennylane.templates.layers."""
interfaces = [('numpy', np.array)]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From here on the diff becomes unreadable...I recommend looking at it in the file...

qnode(weights)
assert excinfo.value.args[0] == "StronglyEntanglingLayer requires at least two wires or subsystems to apply " \
"the imprimitive gates."


Copy link
Contributor Author

Choose a reason for hiding this comment

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

See smuggled in fix, now SEL can take 1 wire too

@mariaschuld mariaschuld merged commit 3acf0ec into master Nov 13, 2019
@mariaschuld mariaschuld deleted the refactor_template_tests branch November 13, 2019 12:27
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. templates 📁 Updates and additions to the templates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants