PennyLane v0.19.0 + CUDA

Hello.

It seems that CUDA support has been enhanced in PennyLane v0.19.0.

So I tried default.qubit + backprop, but I got an error.
Is there anything that can be done in the user code?

The following is the error message.
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cpu and cuda:0! (when checking argument for argument tensors in method wrapper___cat)

Here is the code I tried.

import pennylane as qml
import pytorch_lightning as pl
import torch
from torch import nn


class QNet(nn.Module):
    def __init__(self, n_input: int, q_dev: str, q_diff: str, n_layers: int) -> None:
        super().__init__()

        self.n_wires = n_input
        self.n_layers = n_layers

        dev = qml.device(q_dev, wires=self.n_wires)

        self.qnode = qml.QNode(self._circuit, dev, diff_method=q_diff)

        weight_shapes = {
            'params': qml.StronglyEntanglingLayers.shape(self.n_layers, self.n_wires)
        }

        self.model = qml.qnn.TorchLayer(self.qnode, weight_shapes)

    def forward(self, x):
        return self.model(x)

    def _circuit(self, inputs, params):
        qml.AngleEmbedding(inputs, wires=range(self.n_wires))
        qml.StronglyEntanglingLayers(params, wires=range(self.n_wires))
        return qml.expval(qml.PauliZ(0))


def main():
    n_features = 20
    batch_size = 16
    q_dev = 'default.qubit'
    q_diff = 'backprop'  # => error
    # q_diff = 'adjoint'   # => ok
    n_layers = 6

    model = QNet(
        n_features,
        q_dev,
        q_diff,
        n_layers
    )

    pl.seed_everything(42)

    device_name = 'cuda' if torch.cuda.is_available() else 'cpu'
    device = torch.device(device_name)

    x = torch.randn((batch_size, n_features), device=device)
    assert x.device != 'cpu'

    model = model.to(device)

    predicted = model(x)  # <= error occured
    assert predicted.device != 'cpu'


if __name__ == '__main__':
    main()

requirements.txt:

pennylane == 0.19.0
pytorch-lightning == 1.5.2
torch == 1.10.0

and tracebacks:

Traceback (most recent call last):
  File "pl_with_cuda_ng_shortest.py", line 67, in <module>
    main()
  File "pl_with_cuda_ng_shortest.py", line 58, in main
    predicted = model(x)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl
    return forward_call(*input, **kwargs)
  File "pl_with_cuda_ng_shortest.py", line 25, in forward
    return self.model(x)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl
    return forward_call(*input, **kwargs)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/qnn/torch.py", line 279, in forward
    reconstructor.append(self.forward(x))
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/qnn/torch.py", line 283, in forward
    return self._evaluate_qnode(inputs)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/qnn/torch.py", line 298, in _evaluate_qnode
    return self.qnode(**kwargs).type(x.dtype)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/qnode.py", line 699, in __call__
    res = self.qtape.execute(device=self.device)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/tape/tape.py", line 1324, in execute
    return self._execute(params, device=device)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/tape/tape.py", line 1355, in execute_device
    res = device.execute(self)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/devices/default_qubit_torch.py", line 173, in execute
    return super().execute(circuit, **kwargs)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/_qubit_device.py", line 194, in execute
    self.apply(circuit.operations, rotations=circuit.diagonalizing_gates, **kwargs)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/devices/default_qubit.py", line 217, in apply
    self._state = self._apply_operation(self._state, operation)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/devices/default_qubit_torch.py", line 273, in _apply_operation
    return super()._apply_operation(state, operation)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/devices/default_qubit.py", line 242, in _apply_operation
    matrix = self._get_unitary_matrix(operation)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/devices/default_qubit_torch.py", line 242, in _get_unitary_matrix
    return self._asarray(unitary.matrix, dtype=self.C_DTYPE)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/operation.py", line 763, in matrix
    op_matrix = self._matrix(*self.parameters)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/ops/qubit/parametric_ops.py", line 74, in _matrix
    [qml.math.stack([0, js]), qml.math.stack([js, 0])]
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/pennylane/math/multi_dispatch.py", line 365, in stack
    return np.stack(values, axis=axis, like=interface)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/autoray/autoray.py", line 84, in do
    return get_lib_fn(backend, fn)(*args, **kwargs)
  File "/home/asura/git/qml_ng/venv/lib/python3.8/site-packages/autoray/autoray.py", line 409, in translated_function
    return fn(**new_kwargs)

Hi @asr, welcome to the forum. :slightly_smiling_face:

Thank you for reporting this! The issue affects certain parametric operations such as the RX or RY rotation gates, we’re working on a fix to this.

Until the fix is in (and is released), changing to using the RZ rotation with qml.AngleEmbedding should help your specific example to run.

This would mean specifying the rotation argument to be rotation='Z':

qml.AngleEmbedding(inputs, wires=range(self.n_wires), rotation='Z')

Hope this helps, let us know if you come across further occurrences.

We’ll be posting also when the related fix is live! :slightly_smiling_face:

Hi @antalszava.

Thank you.
Yes, it did work by adding rotation='Z'.

I am looking forward to the release of the fix.

Hi @asr,

Great to hear! :slightly_smiling_face: Sure, we’ll reach out.

Hi @asr,

v0.19.1 of PennyLane has been released bringing fixes to GPU usage with default.qubit.torch. :slightly_smiling_face:

Hi @antalszava,

Thank you for the quick release.
I can confirm the aggressive use of the GPU.
I also tried 9 different ansatz and had no problems.

1 Like

That’s great to hear @asr! Thank you for your confirmation.