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

Shots refactor I of III #1075

Merged
merged 33 commits into from
Feb 10, 2021
Merged

Shots refactor I of III #1075

merged 33 commits into from
Feb 10, 2021

Conversation

mariaschuld
Copy link
Contributor

Context:

The shots refactor is a long-planned change that makes the execution of circuits with varying numbers of shots more flexible.

The first change adds an optional kwarg to the qnode's __call__ function which temporarily changes the number of shots that the device is executed with.

Description of the Change:

  • Temporarily set the number of shots in qnode's __call__ function.

  • Add a test.

  • Change docs and changelog.

Benefits:

In every execution one can now overwrite the device's default shot argument.

dev = qml.device('default.qubit', wires=1, shots=10)

@qml.qnode(dev)
def circuit(a):
    qml.RX(a, wires=0)
    return qml.sample(qml.PauliZ(wires=0))

print(circuit(0.8))  # [ 1  1  1 -1 -1  1  1  1  1  1]
print(circuit(0.8, shots=3))  # [ 1  1  1]
print(circuit(0.8))  # [ 1  1  1 -1 -1  1  1  1  1  1]

Possible Drawbacks:

If a user creates a qfunc with a custom shots keyword argument used in the circuit, the kwarg will be popped from the argument list and is never fed into the circuit. This leads to unexpected behaviour, such as

dev = qml.device('default.qubit', wires=2, shots=10)

@qml.qnode(dev)
def circuit(a, shots=1):
    qml.RX(a, wires=shots)
    return qml.sample(qml.PauliZ(wires=0))

print(circuit(0.8, shots=0)) 
>>> "pennylane._device.DeviceError: The specified number of shots needs to be at least 1. Got 0."

In some sense, we make shots a reserved argument.

@codecov
Copy link

codecov bot commented Feb 8, 2021

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.72%. Comparing base (5dc52a5) to head (4f780f0).
Report is 2639 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1075   +/-   ##
=======================================
  Coverage   97.72%   97.72%           
=======================================
  Files         154      154           
  Lines       11647    11658   +11     
=======================================
+ Hits        11382    11393   +11     
  Misses        265      265           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

pennylane/tape/qnode.py Outdated Show resolved Hide resolved
pennylane/__init__.py Show resolved Hide resolved
pennylane/tape/qnode.py Outdated Show resolved Hide resolved
tests/tape/tapes/test_qnode.py Show resolved Hide resolved
.github/CHANGELOG.md Outdated Show resolved Hide resolved
doc/introduction/circuits.rst Outdated Show resolved Hide resolved
pennylane/__init__.py Show resolved Hide resolved
pennylane/tape/qnode.py Outdated Show resolved Hide resolved
tests/tape/tapes/test_qnode.py Show resolved Hide resolved
tests/tape/tapes/test_qnode.py Show resolved Hide resolved
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.

Looks good @mariaschuld! My only major comment I think was regarding warning vs. exception, the rest were all minor docstring suggestions :)

.github/CHANGELOG.md Outdated Show resolved Hide resolved
doc/introduction/circuits.rst Outdated Show resolved Hide resolved
pennylane/__init__.py Outdated Show resolved Hide resolved
pennylane/__init__.py Outdated Show resolved Hide resolved
pennylane/__init__.py Outdated Show resolved Hide resolved
Comment on lines 144 to 146
raise qml.QuantumFunctionError(
"The shots argument is reserved and will be overwritten!"
)
Copy link
Member

Choose a reason for hiding this comment

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

I would make this a warning rather than an exception. I can't quite explain, but it 'feels' more like a warning.

Like, we shouldn't stop the user from creating the qnode, but we should warn them that the shots argument won't act as they expect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason why I changed to the error is that I played around and all sorts of strange things happened until I realised that I used a shots argument in my code and I had just overlooked the warning...

I think a warning is more appropriate but an exception safer? Happy to change though!

pennylane/tape/qnode.py Outdated Show resolved Hide resolved
assert len(circuit(0.8)) == 10

def test_shots_reserved_qfunc_argument(self):
"""Tests that a warning is raised if the quantum function has a shots argument."""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@josh146 is this the test you had in mind?

Copy link
Member

Choose a reason for hiding this comment

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

Yep looks good!

pennylane/__init__.py Outdated Show resolved Hide resolved
assert len(circuit(0.8)) == 10

def test_shots_reserved_qfunc_argument(self):
"""Tests that a warning is raised if the quantum function has a shots argument."""
Copy link
Member

Choose a reason for hiding this comment

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

Yep looks good!

@mariaschuld
Copy link
Contributor Author

[ch4089]

@mariaschuld
Copy link
Contributor Author

mariaschuld commented Feb 9, 2021

@josh146 and @Thenerdstation, thanks for the comments!

I made a few more changes which ensure backwards compatibility. So we have:

  • If users have a shots argument or keyword argument in the qfunc, the per-call-shot-mutation is switched off and their argument gets precedence. However, they will get a deprecation warning that discourages the use of shots args/kwargs.
  • If they do not have a shots arg/kwarg we interpret (for example) shots=8 as a temporary overwrite to the device's shots argument

tests/tape/tapes/test_qnode.py Show resolved Hide resolved
.github/CHANGELOG.md Show resolved Hide resolved
pennylane/tape/qnode.py Outdated Show resolved Hide resolved
Co-authored-by: Chase Roberts <chase@xanadu.ai>
[ 1 1 1]
>>> circuit(0.8)
[ 1 1 1 -1 -1 1 1 1 1 1]

Copy link
Contributor

Choose a reason for hiding this comment

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

I can't suggest it, but you need 3 backticks here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants