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.27k stars 586 forks source link

Error for pennylane.numpy.tensor with plugin devices using non-differentiable syntax #900

Closed antalszava closed 3 years ago

antalszava commented 3 years ago

Issue description

When a pennylane.numpy.tensor is passed to a QNode as a keyword argument, it is considered as a non-differentiable parameter. Unlike in the case when it is handled as a differentiable parameter, it is not cast into a ndarray.

When indexing into a pennylane.numpy.tensor, one can end up having a single element sequence. Certain devices (e.g., qiskit.aer, forest.wavefunction), are not capable of supporting the application of a gate taking this type of argument and raise an error. Gates can take such a pennylane.numpy.tensor as gate parameter, when passed as a non-differentiable parameter.

import pennylane as qml
from pennylane.numpy import tensor

dev = qml.device("qiskit.aer", wires=4)

@qml.qnode(dev)
def circuit(phi=None):
    for y in phi:
        for idx, x in enumerate(y):
            qml.RX(x, wires=idx)
    return qml.expval(qml.PauliZ(0))

phi = tensor([[0.04439891, 0.14490549, 3.29725643, 2.51240058]])

circuit(phi=phi)

A special case using RandomLayers was tackled in PR #893. This is an example that is used in the Quanvolutional Neural Networks demonstration.

RuntimeError: Invalid number of dimensions!

Further errors may arise for other devices (see https://github.com/PennyLaneAI/pennylane/pull/893#issuecomment-726153779 for error messages that were thrown when using `RandomLayers`).

* *Reproduces how often:* (What percentage of the time does it reproduce?)
For certain plugin devices, each time a `pennylane.numpy.tensor` type sequence is passed as a gate parameter during execution.

* *System information:*

Name: PennyLane Version: 0.13.0.dev0 Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc. Home-page: https://github.com/XanaduAI/pennylane Author: None Author-email: None License: Apache License 2.0 Location: Requires: numpy, scipy, networkx, autograd, toml, appdirs, semantic-version Required-by: PennyLane-SF, PennyLane-Qchem, PennyLane-Forest, PennyLane-qsharp, pennylane-qulacs, PennyLane-lightning, PennyLane-qiskit, PennyLane-AQT, PennyLane-Cirq Platform info: Linux-4.19.11-041911-generic-x86_64-with-debian-buster-sid Python version: 3.7.6 Numpy version: 1.18.5 Scipy version: 1.4.1 Installed devices:

Source code and tracebacks

Additional information

A solution could be to create a case for pennylane.numpy.tensor type sequence parameters in each plugin device implementation (see https://github.com/PennyLaneAI/pennylane/pull/893#issuecomment-725935113 containing a suggestion).

Seems that this problem does not arise in tape mode.

josh146 commented 3 years ago

Thanks for catching this @antalszava @mariaschuld.

I think this is a result of the old + new QNode variable marking system clashing.

As a result, when tape-mode is default this issue should disappear. However, in the meantime, I suggest we add

if isinstance(x, qml.numpy.tensor) and x.ndim == 0:
    x = x.unwrap()

either to the (old) autograd interface, the (old) BaseQNode, or QubitDevice, depending on which one makes more sense; this way we don't have to update all plugins.

My gut feeling is that it makes more sense to fix this in BaseQNode, since it will be deleted anyway when tape mode is default.