# Problems on VQE with cuda

Hello! I’m still quite new here and I hope I can get some help.

I’m trying to conduct a VQE algorithm on a numpy Hermition matrix. When runing with CPU, I used hermitian = qml.Hermitian(matrixReal, wires=range(qubits)) H = qml.Hamiltonian((1, ), (hermitian, )) to convert the numpy matrixReal to a Hamiltonian operator and use it to obtain the energy ``. It works.

However, when I try to use cuda for acceleration, it failed and put out an error sayinig

Can only compute sparse representation for tensors whose operations act on consecutive wires;

Here is my code. The error occurs on line loss = ansatz(params, H)

import numpy as np
import pennylane as qml
import matplotlib.pyplot as plt
import time
import torch
from torch.optim.lr_scheduler import StepLR

def qmlVQE(matrix, maxIter=800, rate=0.1, reps=60):
timeStart = time.time()

matrixReal = complexToRealMatrix(matrix)
qubits = round(np.log2(matrixReal.shape[0]))

dev = qml.device('default.qubit.torch', wires=qubits)
base = torch.tensor(np.random.random(size=qubits * 2 * reps), device='cuda')

@qml.qnode(dev, interface='torch')
def ansatz(params, H):
cnt = 0
for index in range(reps):
for i in range(qubits):
qml.RY(params[cnt], wires=[i])
cnt += 1
for i in range(qubits):
qml.RZ(params[cnt], wires=[i])
cnt += 1
for i in range(qubits-1)[(index%2)::2]:
qml.CNOT(wires=[i, i+1]);
qml.Barrier(wires=range(qubits))
return qml.expval(H)

def ansatzState(params):
cnt = 0
for index in range(reps):
for i in range(qubits):
qml.RY(params[cnt], wires=[i])
cnt += 1
for i in range(qubits):
qml.RZ(params[cnt], wires=[i])
cnt += 1
for i in range(qubits-1)[(index%2)::2]:
qml.CNOT(wires=[i, i+1]);
qml.Barrier(wires=range(qubits))
return qml.state()

history = []
plt.figure()
def callBack(energy):
plt.clf()
plt.ion()
history.append(energy)
plt.title("Objective function value against iteration")
plt.xlabel("Iteration")
plt.ylabel("Objective function value")
plt.plot(range(len(history)), history)
plt.axhline(y=energy, color='black', linestyle='--')
plt.text(0.8,0.2, f'Latest : {energy:.4f}', color='black', ha='center', transform=plt.gcf().transFigure)
plt.draw()
plt.pause(0.15)

hermitian = qml.Hermitian(matrixReal, wires=range(qubits))
H = qml.Hamiltonian((1, ), (hermitian, ))

def train(params):
scheduler = StepLR(opt, step_size=10, gamma=0.99)

def closure():
loss = ansatz(params, H)
loss.backward()
return loss

for n in range(maxIter):
l = opt.step(closure)
timeEnd = time.time()
value = l.item()
callBack(value)
print(f"Step = {n},  Value = {value:.8f}, Time = {(timeEnd - timeStart):.2f}")
scheduler.step()

return params

params = train(base)
psiQuantum = ansatzState(params)
psi = realToComplexEigen(psiQuantum.cpu().detach().numpy().reshape(-1, 1))
plt.ioff()
return psi

Thanks for any assistance!

Hi @Chenjia , welcome to the Forum!

It looks like the error is arising from sparse_matrix but I’m not sure where the error is coming from.

Could you please provide the following information? It can help us understand the problem and find possible solutions:

2. A minimal (but self-contained) working example
This is the simplest version of the code that reproduces the problem. It should include all necessary imports, data, functions, etc., so that we can copy-paste the code and reproduce the problem. However it shouldn’t contain any unnecessary data, functions, …, for example gates and functions that can be removed to simplify the code.

3. The full error traceback.

If you’re not sure what these mean then make sure to check out this video.

1 Like

Thanks. Here are my code and other information.

0.00s - Debugger warning: It seems that frozen modules are being used, which may
0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
0.00s - to python to disable frozen modules.
0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.
Name: PennyLane
Version: 0.35.0
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:
Location: /home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane_Lightning

Platform info:           Linux-6.5.0-41-generic-x86_64-with-glibc2.35
Python version:          3.11.8
Numpy version:           1.26.4
Scipy version:           1.12.0
Installed devices:
- default.clifford (PennyLane-0.35.0)
- default.gaussian (PennyLane-0.35.0)
- default.mixed (PennyLane-0.35.0)
- default.qubit (PennyLane-0.35.0)
- default.qubit.jax (PennyLane-0.35.0)
- default.qubit.legacy (PennyLane-0.35.0)
- default.qubit.tf (PennyLane-0.35.0)
- default.qubit.torch (PennyLane-0.35.0)
- default.qutrit (PennyLane-0.35.0)
- null.qubit (PennyLane-0.35.0)
- lightning.qubit (PennyLane_Lightning-0.35.0)
None

• An example of my problem
import numpy as np
import pennylane as qml
import matplotlib.pyplot as plt
import time
import torch
from torch.optim.lr_scheduler import StepLR

def complexToRealMatrix(A):
import numpy as np
n = A.shape[0]
B = np.zeros((2*n, 2*n))
B[::2, ::2] = A.real
B[::2, 1::2] = -A.imag
B[1::2, ::2] = A.imag
B[1::2, 1::2] = A.real
return B

def realToComplexEigen(eigvecs):
import numpy as np
real = eigvecs[::2]
imaginary = eigvecs[1::2]
finalEigvec = real + 1j * imaginary
return finalEigvec

def qmlVQE(matrix, maxIter=800, rate=0.1, reps=60):
timeStart = time.time()

matrixReal = complexToRealMatrix(matrix)
qubits = round(np.log2(matrixReal.shape[0]))

dev = qml.device('default.qubit.torch', wires=qubits, torch_device="cuda:0")
base = torch.tensor(np.random.random(size=qubits * 2 * reps), device='cuda')

@qml.qnode(dev, interface='torch')
def ansatz(params, H):
cnt = 0
for index in range(reps):
for i in range(qubits):
qml.RY(params[cnt], wires=[i])
cnt += 1
for i in range(qubits):
qml.RZ(params[cnt], wires=[i])
cnt += 1
for i in range(qubits-1)[(index%2)::2]:
qml.CNOT(wires=[i, i+1]);
qml.Barrier(wires=range(qubits))
return qml.expval(H)

def ansatzState(params):
cnt = 0
for index in range(reps):
for i in range(qubits):
qml.RY(params[cnt], wires=[i])
cnt += 1
for i in range(qubits):
qml.RZ(params[cnt], wires=[i])
cnt += 1
for i in range(qubits-1)[(index%2)::2]:
qml.CNOT(wires=[i, i+1]);
qml.Barrier(wires=range(qubits))
return qml.state()

history = []
plt.figure()
def callBack(energy):
plt.clf()
plt.ion()
history.append(energy)
plt.title("Objective function value against iteration")
plt.xlabel("Iteration")
plt.ylabel("Objective function value")
plt.plot(range(len(history)), history)
plt.axhline(y=energy, color='black', linestyle='--')
plt.text(0.8,0.2, f'Latest : {energy:.4f}', color='black', ha='center', transform=plt.gcf().transFigure)
plt.draw()
plt.pause(0.15)

hermitian = qml.Hermitian(matrixReal, wires=range(qubits))
H = qml.Hamiltonian((1, ), (hermitian, ))

def train(params):
scheduler = StepLR(opt, step_size=10, gamma=0.99)

def closure():
loss = ansatz(params, H)
loss.backward()
return loss

for n in range(maxIter):
l = opt.step(closure)
timeEnd = time.time()
value = l.item()
callBack(value)
print(f"Step = {n},  Value = {value:.8f}, Time = {(timeEnd - timeStart):.2f}")
scheduler.step()

return params

params = train(base)
psiQuantum = ansatzState(params)
psi = realToComplexEigen(psiQuantum.cpu().detach().numpy().reshape(-1, 1))
plt.ioff()
return psi

n = 2 ** 10
A = np.random.rand(n, n) + 1j * np.random.rand(n, n)
matrix = (A + A.conj().T) / 2 # Assume H is a random Hermite matrix in numpy
psi = qmlVQE(matrix = matrix)
print(psi)

• Full error traceback
Traceback (most recent call last):
File "/home/zcjrony/桌面/PennnyLane/vqes.py", line 118, in <module>
psi = qmlVQE(matrix = H)
^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/桌面/PennnyLane/vqes.py", line 107, in qmlVQE
params = train(base)
^^^^^^^^^^^
File "/home/zcjrony/桌面/PennnyLane/vqes.py", line 98, in train
l = opt.step(closure)
^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/torch/optim/lr_scheduler.py", line 75, in wrapper
return wrapped(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/torch/optim/optimizer.py", line 391, in wrapper
out = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/torch/optim/optimizer.py", line 76, in _use_grad
ret = func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/torch/optim/adam.py", line 148, in step
loss = closure()
^^^^^^^^^
File "/home/zcjrony/桌面/PennnyLane/vqes.py", line 93, in closure
loss = ansatz(params, H)
^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/workflow/qnode.py", line 1048, in __call__
res = qml.execute(
^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/workflow/execution.py", line 684, in execute
results = inner_execute(tapes)
^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/workflow/execution.py", line 283, in inner_execute
return cached_device_execution(tapes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/workflow/execution.py", line 361, in wrapper
res = list(fn(tapes, **kwargs))
^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/contextlib.py", line 81, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/_qubit_device.py", line 459, in batch_execute
res = self.execute(circuit)
^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/devices/default_qubit_torch.py", line 245, in execute
return super().execute(circuit, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/_qubit_device.py", line 289, in execute
results = self.statistics(circuit)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/_qubit_device.py", line 630, in statistics
result = self.expval(obs, shot_range=shot_range, bin_size=bin_size)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/devices/default_qubit_legacy.py", line 632, in expval
coo = qml.operation.Tensor(op).sparse_matrix(wire_order=self.wires, format="coo")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zcjrony/anaconda3/envs/pennylane/lib/python3.11/site-packages/pennylane/operation.py", line 2474, in sparse_matrix
raise ValueError(
ValueError: Can only compute sparse representation for tensors whose operations act on consecutive wires; got Hermitian(array([[ 0.6530607 , -0.        ,  0.43956737, ..., -0.01520758,
0.58009441,  0.15327382],
[ 0.        ,  0.6530607 , -0.04909861, ...,  0.38300196,
-0.15327382,  0.58009441],
[ 0.43956737, -0.04909861,  0.51031064, ...,  0.11782081,
0.87449403, -0.01589164],
...,
[-0.01520758,  0.38300196,  0.11782081, ...,  0.03700643,
-0.38992576,  0.55237325],
[ 0.58009441, -0.15327382,  0.87449403, ..., -0.38992576,
0.97597393, -0.        ],
[ 0.15327382,  0.58009441, -0.01589164, ...,  0.55237325,
0.        ,  0.97597393]]), wires=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).

Hi @Chenjia ,

It looks like your error is due to the version of the packages that you’re using.

I’d recommend updating your version of PennyLane with python -m pip install pennylane --upgrade. Our latest stable version is v0.37.

I ran your code in Colab and got no issues up to the line: psi = realToComplexEigen(psiQuantum.cpu().detach().numpy().reshape(-1, 1))

Here you’ll get an error because psiQuantum is a state (‘StateMP’ object) so it has no attribute ‘cpu’.

I hope this helps you solve the issue you’re seeing!

It does work! Thanks for your assistance!