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

[BUG] qml.ctrl() does queue but not return operations #6222

Closed
1 task done
cvjjm opened this issue Sep 5, 2024 · 3 comments
Closed
1 task done

[BUG] qml.ctrl() does queue but not return operations #6222

cvjjm opened this issue Sep 5, 2024 · 3 comments
Labels
bug 🐛 Something isn't working

Comments

@cvjjm
Copy link
Contributor

cvjjm commented Sep 5, 2024

Expected behavior

it is arguable whether this is a bug, but at least it is unexpected behavior:

Calling qml.MultiRZ(0.2, wires=range(4)) returns a instance of Operation, namely MultiRZ(0.2, wires=[0, 1, 2, 3]).

I know that I can get the Operation produced by qml.ctrl in the following, slightly roundabout way, but it is note "nice" of PennyLane that I have to do this:

def CCCRZ(theta, wires):
    with qml.QueuingManager.stop_recording():
        with qml.tape.QuantumTape() as tape:
            qml.ctrl(qml.RZ, control=wires[0:3])(0.2, wires=wires[3])
        return tape.operations[0]

CCCRZ(0.2, range(4))

The code returns Controlled(RZ(0.2, wires=[3]), control_wires=[0, 1, 2]) and I would expect that qml.ctrl(qml.RZ, control=(0, 1, 2))(0.2, wires=[3]) should return the same, not an empty list.

Actual behavior

Calling qml.ctrl(qml.RZ, control=(0, 1, 2))(0.2, wires=[3]) returns an empty list.

Additional information

No response

Source code

No response

Tracebacks

No response

System information

Name: PennyLane
Version: 0.35.1
Summary: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Home-page: https://github.com/PennyLaneAI/pennylane
Author:
Author-email:
License: Apache License 2.0
Location: /home/cvjjm/miniforge3/envs/[...]/lib/python3.11/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: matchgate_shadows, PennyLane_Lightning

Platform info:           Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.31
Python version:          3.11.9
Numpy version:           1.23.5
Scipy version:           1.13.0
Installed devices:
- lightning.qubit (PennyLane_Lightning-0.35.1)
- default.clifford (PennyLane-0.35.1)
- default.gaussian (PennyLane-0.35.1)
- default.mixed (PennyLane-0.35.1)
- default.qubit (PennyLane-0.35.1)
- default.qubit.autograd (PennyLane-0.35.1)
- default.qubit.jax (PennyLane-0.35.1)
- default.qubit.legacy (PennyLane-0.35.1)
- default.qubit.tf (PennyLane-0.35.1)
- default.qubit.torch (PennyLane-0.35.1)
- default.qutrit (PennyLane-0.35.1)
- null.qubit (PennyLane-0.35.1)

Existing GitHub issues

  • I have searched existing GitHub issues to make sure the issue does not already exist.
@cvjjm cvjjm added the bug 🐛 Something isn't working label Sep 5, 2024
@CatalinaAlbornoz
Copy link
Contributor

Hi @cvjjm , thank you for reporting this. We'll look into it.

@isaacdevlugt
Copy link
Contributor

Hey @cvjjm! It would be nice to know the context of the issue so that we have a better idea of possible problems with ctrl. That said, I don't think there is anything out of the ordinary with the code example you have in the issue description.

The docs for ctrl say that “If an Operator is provided, returns a Controlled version of the Operator”. In this example, one might expect that statement to apply:

print(qml.ctrl(qml.RZ, control=(0)), type(qml.ctrl(qml.RZ, control=(0))))
print(qml.ctrl(qml.RZ, control=(0))(0.1, 1))
<function RZ at 0x300fe1bc0> <class 'function'>
[]

However, qml.RZ all by itself is not an Operator, it's a callable. So, the second statement in the documentation applies: "If a function is provided, returns a function with the same call signature that creates a controlled version of the provided function".

If you want the first part of the documentation (i.e., "If an Operator is provided, returns a Controlled version of the Operator"), then qml.RZ(0.1, 1), for example, is an Operator, and:

print(qml.ctrl(qml.RZ(0.1, 1), control=(0)), type(qml.ctrl(qml.RZ(0.1, 1), control=(0))))
CRZ(0.1, wires=Wires([0, 1])) <class 'pennylane.ops.op_math.controlled_ops.CRZ'>

There's a small subtlety around the whole "empty list" thing that has to do with ctrl being in a QNode / queuing context or not. It's a little non-trivial to document and is best served by code examples instead so as to not confuse users overall.

Let me know if this helps!

@cvjjm
Copy link
Contributor Author

cvjjm commented Sep 18, 2024

Thanks, this makes sense. With this in mind I think the current behavior is consistent. Thanks for explaining.

@cvjjm cvjjm closed this as completed Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants