Nan values received using lightning.qubit device

I’m running a machine learning algorithm in which as part of the loss function calculation I’m calling qml.jacobian(circuit)(xnorm, params). it works fine when running on qml.device("default.qubit", wires=nqubits) but if I change it to qml.device("lightning.qubit", wires=nqubits) I receive Nan values for some elements in the output.
I use the @qml.qnode decorator for the circuit:

@qml.qnode(dev)
def circuit(coll, params):
    qml.StatePrep(coll, wires=range(nqubits))
    dictparams=dict(zip(qc.parameters, params))
    ansatz(params=dictparams,wires=range(nqubits))
    prob=qml.probs(wires=range(nqubits))
    return prob

and the loss function (until the error) is: (pnp is: from pennylane import numpy as pnp)

def loss_fn(params, circuit=circuit):
    prob=circuit(xnorm, params)
    u=pnp.sqrt(prob)
    du2dx_jac,duda=qml.jacobian(circuit)(xnorm, params)
    ...

in runtime I receive those warnings which may help:

/envs/cuda-quantum/lib/python3.10/site-packages/autograd/numpy/numpy_vjps.py:85: RuntimeWarning: divide by zero encountered in divide
  defvjp(anp.arcsin, lambda ans, x : lambda g: g / anp.sqrt(1 - x**2))

/envs/cuda-quantum/lib/python3.10/site-packages/pennylane/numpy/tensor.py:155: RuntimeWarning: invalid value encountered in multiply
  res = super().__array_ufunc__(ufunc, method, *args, **kwargs)

/envs/cuda-quantum/lib/python3.10/site-packages/pennylane/numpy/tensor.py:155: RuntimeWarning: invalid value encountered in at
  res = super().__array_ufunc__(ufunc, method, *args, **kwargs)

and the du2dx_jac I get is:

[[        nan         nan -0.00908817 ... -0.02307965 -0.00254096
  -0.00768597]
 [        nan         nan -0.00607349 ... -0.0350922  -0.0102256
  -0.00871634]
 [        nan         nan -0.00342172 ...  0.02416978 -0.02432349
  -0.01001875]
 ...
 [        nan         nan  0.01431378 ...  0.00331552  0.05455701
  -0.02419741]
 [        nan         nan -0.00539168 ...  0.04763316  0.09883949
   0.03659902]
 [        nan         nan -0.00086362 ... -0.10641249 -0.05992528
   0.16751464]]

This behavior doesn’t happen when using default.qubit device.
how can I overcome this? I want to use the lightning devices in order to easily run on GPU later.

Hi @ZivChen,

Welcome to the forum!
I’m not seeing any issues with using qml.jacobian with lightning.qubit. You may be using an older version of PennyLane or maybe your issue lies somewhere else in your code. As you can see from the output in the code below, there is indeed a difference in numerical precision being used by the two devices but this shouldn’t affect your output.

import pennylane as qml
from pennylane import numpy as pnp

dq = qml.device("default.qubit", wires=2)
lq = qml.device("lightning.qubit", wires=2)

def circuit(data,params):
    qml.RX(data, wires=0)
    qml.Rot(params[0],params[1],params[2], wires=1)
    return qml.probs()

data = pnp.array(0.1, requires_grad=False)
params = pnp.array([0.1,0.2,0.3], requires_grad=True)

circuit_dq = qml.QNode(circuit,dq)
circuit_lq = qml.QNode(circuit,lq)

jac_dq = qml.jacobian(circuit_dq,argnum=1)(data, params)
jac_lq = qml.jacobian(circuit_lq,argnum=1)(data, params)

print('jac_dq \n',jac_dq)
print('jac_lq \n',jac_lq)

I hope this helps you to find the answer to your issue.
In case that you still need help please post the output of qml.about() as well as a minimal but self-contained example that shows the behaviour you’re seeing. Take a look at this video to learn more about minimal working examples and other tips that can help us help you better :grinning:.

Hi @CatalinaAlbornoz,

Thanks for the reply! I think that I managed to debug this by adding 1e-10 to xnorm (the parameter that the Jacobian applies to) and it resolved the nans. the xnorm has a lowest value of 0.
my question is: is possible to change the backend’s numerical precision on my end? for some reason the default.qubit manages to calculate it without problems while the lightning.qubit needs the addition…

Can you post a minimal non-working example we could use to replicate the issue?

Another potential source of issues could be the diff_method. If you are in analytic mode (shots=None) default qubit will use backprop, but lightning qubit will have to use parameter shift. It might be worth seeing if manually setting diff_method="parameter-shift" causes the same issue.

2 Likes

Hi @ZivChen ,

Regarding your question on numerical precision, my collegue Amintor has this answer for you:

By default we set Lightning precision to np.complex128, but you can change it with:
lq = qml.device("lightning.qubit", wires=2, c_dtype=np.complex64)
This actually would make calculations faster with some cost to precision.

We can’t set default.qubit precision manually, though.

As Christina said, it’s worth investigating if the issue actually comes from the differentiation method.

I hope this helps!

1 Like

Thanks for the reply!
I tried to manually set the diff_method='parameter-shift' in the lightning.qubit device but it still cause the same issue (if I don’t add 1e-10 to xnorm).

Hi @ZivChen ,

Thanks for sharing this insight. Is your current solution enough for now?

Yes, it’s working. Thanks!

That’s great to hear @ZivChen !

1 Like