PennyLaneAI / catalyst

A JIT compiler for hybrid quantum programs in PennyLane
https://docs.pennylane.ai/projects/catalyst
Apache License 2.0
142 stars 36 forks source link

Bug when applying a double ``qml.adjoint`` #1301

Closed KetpuntoG closed 1 week ago

KetpuntoG commented 2 weeks ago

Double adjoint does not work correctly. It seems that it simply applies one adjoint. In the following script we can compare the correct result in lightning with an incorrect result in catalyst.

device = qml.device("lightning.qubit", wires=1)
def circuit():
    qml.Hadamard(0)
    qml.adjoint(qml.adjoint(qml.S(0)))
    return qml.state()

interpreted_fn = qml.QNode(circuit, device)
jitted_fn = qjit(interpreted_fn)

print(np.round(interpreted_fn(), 2))
print(np.round(jitted_fn(), 2))
[0.71+0.j   0.  +0.71j]
 [0.71+0.j   0.  -0.71j]

It seems to be a recently introduced bug as it worked correctly before.

qml.about()


Platform info:           macOS-14.6.1-arm64-arm-64bit
Python version:          3.9.6
Numpy version:           1.26.4
Scipy version:           1.12.0
Installed devices:
- default.clifford (PennyLane-0.40.0.dev12)
- default.gaussian (PennyLane-0.40.0.dev12)
- default.mixed (PennyLane-0.40.0.dev12)
- default.qubit (PennyLane-0.40.0.dev12)
- default.qutrit (PennyLane-0.40.0.dev12)
- default.qutrit.mixed (PennyLane-0.40.0.dev12)
- default.tensor (PennyLane-0.40.0.dev12)
- null.qubit (PennyLane-0.40.0.dev12)
- reference.qubit (PennyLane-0.40.0.dev12)
- lightning.qubit (PennyLane-Lightning-0.38.0)
- nvidia.custatevec (PennyLane-Catalyst-0.8.1)
- nvidia.cutensornet (PennyLane-Catalyst-0.8.1)
- oqc.cloud (PennyLane-Catalyst-0.8.1)
- softwareq.qpp (PennyLane-Catalyst-0.8.1)
dime10 commented 2 weeks ago

Do you know when it was still working? I can confirm that nested adjoint operator instances (like Adjoint(Adjoint(S))) do not get captured correctly in Catalyst. It could be that before we relied on simplification of calls like qml.adjoint(qml.adjoint(*)) by PennyLane, but we will look into this!

josh146 commented 2 weeks ago

It must be related to this:

https://github.com/PennyLaneAI/catalyst/blob/697e4d1ff77bedbd31a8689a8939f2374d55cb92/frontend/test/pytest/test_adjoint.py#L1472-L1475

josh146 commented 2 weeks ago

Which came in from here, in June? https://github.com/PennyLaneAI/catalyst/pull/768

KetpuntoG commented 2 weeks ago

Do you know when it was still working? I can confirm that nested adjoint operator instances (like Adjoint(Adjoint(S))) do not get captured correctly in Catalyst. It could be that before we relied on simplification of calls like qml.adjoint(qml.adjoint(*)) by PennyLane, but we will look into this!

I am not sure because I updated but I would say the last time I installed catalyst was 3 months ago

dime10 commented 2 weeks ago

@josh146 That's a slightly different thing, it's merely that in the test case you link to the adjoint will not be an instance of PennyLane's Adjoint class, but instead an instance of Catalyst's HybridAdjoint class. Not a big deal, it's just that the original test as written does not pass (since it checks the object classes).

josh146 commented 2 weeks ago

Got it :+1:

dime10 commented 2 weeks ago

I think this should fix the issue, it would just need proper testing and polish: https://github.com/PennyLaneAI/catalyst/pull/1302

dime10 commented 1 week ago

Just found out that this broke starting with version 0.39 (so last release)