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

Update QNode for PyTree support #6378

Open
wants to merge 56 commits into
base: master
Choose a base branch
from
Open

Update QNode for PyTree support #6378

wants to merge 56 commits into from

Conversation

andrijapau
Copy link
Contributor

@andrijapau andrijapau commented Oct 10, 2024

Context:

Catalyst currently supports the handling of PyTrees as measurement outputs,

@qml.qnode(dev)
def circuit():
    return {"Exp Value": qml.expval(qml.Z(0)), "Probability": qml.probs()}

Pennylane currently doesn't have support for this but can be added using the existing qml.pytrees.

Description of the Change:

Makes use of the existing qml.pytrees.flatten and qml.pytrees.unflatten functions and updates how the results and qfunc_output is handled/validated.

Example

@qml.qnode(qml.device("default.qubit", wires=3, shots=500))
def circuit():
    qml.Hadamard(0)
    qml.measure(0)
    qml.CNOT([0,1])
    return (
             [
                  qml.probs(wires=1),
                  {"a": qml.probs(wires=0)}, 
                  qml.expval(qml.Z(0))
             ] , 
             {
                  "b": qml.probs(wires=0), 
                  "c": qml.expval(qml.X(1))
             }
     )

>>> circuit()
([array([0.494, 0.506]), {'a': array([0.494, 0.506])}, -0.012], {'b': array([0.494, 0.506]), 'c': -0.096})

Benefits: QNode now has PyTree support! 😄

Possible Drawbacks: None

[sc-66732]

Comment on lines 843 to 850
if isinstance(self._qfunc_output, qml.numpy.tensor):
measurement_processes = tuple(
self.tape.measurements,
)
elif isinstance(self._qfunc_output, dict):
measurement_processes = tuple(self._qfunc_output.values())
elif not isinstance(self._qfunc_output, Sequence):
measurement_processes = (self._qfunc_output,)
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps here we can switch this to measurement_processes = qml.pytrees.flatten(self._qfunc_output)[0].

Copy link
Contributor

Choose a reason for hiding this comment

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

Potentially we could switch to storing self._pytree_structure instead of self._qfunc_output. Basically we just need to store information somehow to remember how to postprocess the results.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that could be an improvement. However, the typing of qfunc_output would also need to be stored as well since it is used to type convert results. 😓

Copy link
Contributor

@albi3ro albi3ro left a comment

Choose a reason for hiding this comment

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

Note that while the main example was a dictinary, we should be able to handle any pytree of measurements. So another example might be:

return ([mp1, mp2], [mp3, mp4], {"a": mp5, "b": [mp6, mp7]})

as a convoluted example.

@andrijapau andrijapau self-assigned this Oct 10, 2024
@andrijapau andrijapau marked this pull request as ready for review October 11, 2024 20:23
@andrijapau andrijapau changed the title [WIP] Update QNode for PyTree support Update QNode for PyTree support Oct 11, 2024
@andrijapau andrijapau marked this pull request as draft October 11, 2024 20:35
@andrijapau andrijapau changed the title Update QNode for PyTree support [WIP] Update QNode for PyTree support Oct 11, 2024
tests/test_qnode_legacy.py Outdated Show resolved Hide resolved
tests/test_qnode.py Outdated Show resolved Hide resolved
@andrijapau andrijapau changed the title [WIP] Update QNode for PyTree support Update QNode for PyTree support Oct 16, 2024
@andrijapau andrijapau marked this pull request as ready for review October 16, 2024 15:06
Copy link

codecov bot commented Oct 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.46%. Comparing base (828c1ec) to head (3f4d8b9).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #6378   +/-   ##
=======================================
  Coverage   99.46%   99.46%           
=======================================
  Files         454      454           
  Lines       42649    42657    +8     
=======================================
+ Hits        42420    42428    +8     
  Misses        229      229           

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


🚨 Try these New Features:

@albi3ro
Copy link
Contributor

albi3ro commented Nov 6, 2024

Also just making a comment here. If we are having obscure edge cases that are difficult to fit into nice logic here and are causing problems, we can consider making a breaking change, if that means more consistent, logical behavior in the QNode.

Copy link
Contributor

@albi3ro albi3ro left a comment

Choose a reason for hiding this comment

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

❤️

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