ValueError: Can only return the expectation of a single Hamiltonian observable

Hi, I am employing VQE to solve the ground state of hydrogen molecule. However, when I try to estimate the expectation of Hamiltonian with finite shots, an error raises as “ValueError: Can only return the expectation of a single Hamiltonian observable”. What is the possible cause of this issue? Please let me know if any additional implementation details are needed to analyse.

Hi @Yang, welcome to the forum!

Yes, we need to see your code in order to help you.

Some things that you can check beforehand are:

  • Check that your Python version is at least 3.7 or higher
  • Check that you’re using the latest PennyLane version (v0.22)
  • Check the return statements in some of our quantum chemistry demos. On the right hand side you will be able to download the notebook and run it locally. If you find an error here then the problem may not be in your code but in your environment. If the demos run well but your code doesn’t then take a close look at what expectation values you’re trying to retrieve. It may be that the specific device you’re using causes problems too.

In any case do share with us your solution if you manage to fix your problem or your code in case that the items above don’t solve it.

I hope this helps though!

Thanks for your advice. Here is my code.

import pennylane as qml
from pennylane import numpy as np
import torch
import math

PauliGate = {
    'X': qml.PauliX,
    'Y': qml.PauliY,
    'Z': qml.PauliZ,
    'I': qml.Identity,
}

def gen_h(hamiltonian):
    coefs = []
    obs = []
    for h in hamiltonian:
        coefs.append(hamiltonian[h])
        ob = PauliGate[h[0]](0)
        for i in range(1, len(h)):
            ob = ob @ PauliGate[h[i]](i)
        obs.append(ob)
    return qml.Hamiltonian(coefs, obs, simplify=False, grouping_type='qwc')

def circuit_h2(param, A=None, p=0):
    qml.PauliX(0)
    qml.PauliX(1)
    for i in [0, 1, 2, 3]:
        qml.Rot(*param[i], wires=i)
    qml.CNOT(wires=[2, 3])
    qml.CNOT(wires=[2, 0])
    qml.CNOT(wires=[3, 1])
    if p > 0 and p < 1:
        for j in range(4):
            qml.DepolarizingChannel(p, wires=j)
    return qml.expval(A)

class VQE_H2(torch.nn.Module):
    def __init__(self, dev, n_qubits, hamiltonian, p=0, n_layers=2) -> None:
        super().__init__()

        self.param = torch.nn.Parameter(torch.FloatTensor(n_qubits, 3).uniform_(0, 2*math.pi))
        self.register_parameter('param', self.param)

        self.cir = qml.qnode(dev, interface='torch')(circuit_h2)
        self.hamiltonian = gen_h(hamiltonian)
        self.p = p

    def forward(self):
        return self.cir(self.param, A=self.hamiltonian, p=self.p)

if __name__ == '__main__':
    dev = qml.device("default.qubit", wires=4, shots=1000)
    h_part={'XXYY': -0.04221755692243391, 'XYYX': 0.04221755692243391, 'ZIIZ': 0.1768099603861226, 'YXXY': 0.04221755692243391}
    model = VQE_H2(dev, 4, h_part, p=0)
    loss = model()

I find that when I use the whole Hamiltonian of hydrogen molecule as observable, the code works well. When I use part of Hamiltonian terms as observable, it reports the error.

Hi @Yang,

Thanks for sharing your code. It runs correctly for me. What is the line that you change that makes it stop working? Could you please share the non-working code too?

Hi @CatalinaAlbornoz,
actually the code I share does not work for me. I run the code on the HPC in the Python environment with Python=3.7.7, PennyLane=0.22.2, Pytorch=1.10.1. It reports the ValueError. However, when I run on my laptop with Python=3.8.10, PennyLane=0.22.2, Pytorch=1.10.2, it works correctly as you. This phenomenon makes me quite confused.

Hi @Yang, what operating system are you using on the HPC and on your laptop? I just ran the code on a Python 3.7 environment with no errors.

You may have a ‘float64’ vs ‘float32’ problem too.

Please let me know if this helps.

Hi @CatalinaAlbornoz, the system on HPC and my laptop is CentOS release 6.9 (Final) and Windows 10.

This is very strange @Yang :thinking:

Could you please send me the full error traceback?

Also, did you try the option of setting the default dtype to float32 and float64 as explained in the pytorch docs?

Finally, it could help if you could send me the output of import pennylane as qml; qml.about()

@CatalinaAlbornoz Yes, quite strange. I tried to set dtype to float64 in pytorch and the error still exists. Here are the full error information:

/var/spool/PBS/mom_priv/jobs/6288971.pbsserver.SC: line 10: py37/bin/activate: No such file or directory
 Traceback (most recent call last):
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/_device.py", line 703, in batch_transform
     return qml.transforms.hamiltonian_expand(circuit, group=False)
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/transforms/hamiltonian_expand.py", line 144, in hamiltonian_expand
     for indices in hamiltonian.grouping_indices
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/transforms/hamiltonian_expand.py", line 144, in <listcomp>
     for indices in hamiltonian.grouping_indices
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/math/multi_dispatch.py", line 178, in wrapper
     return fn(*args, **kwargs)
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/math/multi_dispatch.py", line 543, in stack
     return np.stack(values, axis=axis, like=like)
   File "/home/xxx/py37/lib/python3.7/site-packages/autoray/autoray.py", line 84, in do
     return get_lib_fn(backend, fn)(*args, **kwargs)
   File "<__array_function__ internals>", line 6, in stack
   File "/home/xxx/py37/lib/python3.7/site-packages/numpy/core/shape_base.py", line 423, in stack
     raise ValueError('need at least one array to stack')
 ValueError: need at least one array to stack

 The above exception was the direct cause of the following exception:

 Traceback (most recent call last):
   File "demo.py", line 32, in <module>
     loss = model()
   File "/home/xxx/py37/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl
     return forward_call(*input, **kwargs)
   File "/xxx/circuit/vqe_pl.py", line 82, in forward
     return self.cir(self.param, A=self.hamiltonian, p=self.p)
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/qnode.py", line 585, in __call__
     **self.execute_kwargs,
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/interfaces/batch/__init__.py", line 314, in execute
     tapes, batch_fn = qml.transforms.map_batch_transform(device.batch_transform, tapes)
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/transforms/batch_transform.py", line 476, in map_batch_transform
     new_tapes, fn = transform(t)
   File "/home/xxx/py37/lib/python3.7/site-packages/pennylane/_device.py", line 708, in batch_transform
     ) from e
 ValueError: Can only return the expectation of a single Hamiltonian observable

And the following is the output of qml.about()

 Name: PennyLane
 Version: 0.22.2
 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: /home/yqia7342/py37/lib/python3.7/site-packages
 Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, retworkx, scipy, semantic-version, toml
 Required-by: PennyLane-Lightning, PennyLane-qiskit
 Platform info:           Linux-2.6.32-696.16.1.el6.x86_64-x86_64-with-centos-6.9-Final
 Python version:          3.7.7
 Numpy version:           1.20.1
 Scipy version:           1.6.1
 Installed devices:
 - default.gaussian (PennyLane-0.22.2)
 - default.mixed (PennyLane-0.22.2)
 - default.qubit (PennyLane-0.22.2)
 - default.qubit.autograd (PennyLane-0.22.2)
 - default.qubit.jax (PennyLane-0.22.2)
 - default.qubit.tf (PennyLane-0.22.2)
 - default.qubit.torch (PennyLane-0.22.2)
 - qiskit.aer (PennyLane-qiskit-0.17.0)
 - qiskit.basicaer (PennyLane-qiskit-0.17.0)
 - qiskit.ibmq (PennyLane-qiskit-0.17.0)
 - lightning.qubit (PennyLane-Lightning-0.22.1)

Hi @Yang, I think the problem may be due to the way PyTorch is built in your HPC environment. I would recommend that you try with a new virtual environment. If that doesn’t work maybe you can try a new virtual machine. If that doesn’t work the problem may be with CentOS.

Please let me know if you manage to get it working there!