PennyLaneAI / pennylane

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.
https://pennylane.ai
Apache License 2.0
2.34k stars 601 forks source link

More informative error message needed for lack of support for parameter-broadcasting with `adjoint` #4180

Closed isaacdevlugt closed 1 year ago

isaacdevlugt commented 1 year ago

Expected behavior

If a circuit with diff_method = "adjoint" is attempted to be broadcasted, the error message should say something to the effect that that isn't supported.

Actual behavior

import pennylane as qml

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

@qml.qnode(dev, diff_method="adjoint")
def circuit(x):
    qml.RX(x, wires=0)
    return qml.expval(qml.PauliZ(0))

>>> circuit([1/2, 1/2, 1/2, 1/2])
ValueError: could not broadcast input array from shape (4,2,2) into shape (2,2)

Additional information

Indirectly found from a forum post: https://discuss.pennylane.ai/t/parameter-broadcast-bug/2975/3

Source code

import pennylane as qml

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

@qml.qnode(dev, diff_method="adjoint")
def circuit(x):
    qml.RX(x, wires=0)
    return qml.expval(qml.PauliZ(0))

circuit([1/2, 1/2, 1/2, 1/2])

Tracebacks

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[10], line 8
      5     qml.RX(x, wires=0)
      6     return qml.expval(qml.PauliZ(0))
----> 8 circuit([1/2, 1/2, 1/2, 1/2])

File ~/pennylane-torch/lib/python3.9/site-packages/pennylane/qnode.py:867, in QNode.__call__(self, *args, **kwargs)
    865     self.execute_kwargs.pop("mode")
    866 # pylint: disable=unexpected-keyword-arg
--> 867 res = qml.execute(
    868     [self.tape],
    869     device=self.device,
    870     gradient_fn=self.gradient_fn,
    871     interface=self.interface,
    872     gradient_kwargs=self.gradient_kwargs,
    873     override_shots=override_shots,
    874     **self.execute_kwargs,
    875 )
    877 res = res[0]
    879 if old_interface == "auto":

File ~/pennylane-torch/lib/python3.9/site-packages/pennylane/interfaces/execution.py:483, in execute(tapes, device, gradient_fn, interface, grad_on_execution, gradient_kwargs, cache, cachesize, max_diff, override_shots, expand_fn, max_expansion, device_batch_transform)
    480     elif mapped_interface == "jax":
    481         _execute = _get_jax_execute_fn(interface, tapes)
...
-> 1939     bras[kk, ...] = self._apply_operation(ket, tape.observables[kk])
   1941 expanded_ops = []
   1942 for op in reversed(tape.operations):

ValueError: could not broadcast input array from shape (4,2,2) into shape (2,2)

System information

Name: PennyLane
Version: 0.30.0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author:
Author-email:
License: Apache License 2.0
Location: /Users/isaac/pennylane-torch/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml
Required-by: PennyLane-Lightning

Platform info:           macOS-13.3.1-x86_64-i386-64bit
Python version:          3.9.14
Numpy version:           1.23.5
Scipy version:           1.10.1
Installed devices:
- default.gaussian (PennyLane-0.30.0)
- default.mixed (PennyLane-0.30.0)
- default.qubit (PennyLane-0.30.0)
- default.qubit.autograd (PennyLane-0.30.0)
- default.qubit.jax (PennyLane-0.30.0)
- default.qubit.tf (PennyLane-0.30.0)
- default.qubit.torch (PennyLane-0.30.0)
- default.qutrit (PennyLane-0.30.0)
- null.qubit (PennyLane-0.30.0)
- lightning.qubit (PennyLane-Lightning-0.30.0)

Existing GitHub issues

josh146 commented 1 year ago

Thanks @isaacdevlugt! I'm curious, I thought we had a fallback option in PL for devices that didn't support broadcasting 🤔

albi3ro commented 1 year ago

The problem is that default qubit execution supports broadcasting, just not device differentiation.

albi3ro commented 1 year ago

Boils down to "preprocessing needs to be able to depend on the circuit and what we want to do to the circuit".