-
Notifications
You must be signed in to change notification settings - Fork 58
Inaccurate phase calculation for large qubit number #320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Maybe the error here at line 630: Checking whether it's true or not: QuantumClifford.jl/src/project_trace_reset.jl Lines 630 to 631 in 3ea5414
|
The default setting is phases=true and I purposely added this in the code, but this still doesn't work. s_original_traced = traceout!(copy(s_original), 1:51, phases=true) # 51 is chosen arbitrarily
s_appended_traced = traceout!(copy(s_appended), 1:51, phases=true) |
Further, I found this issue can be easily reproduced by a random mixed stabilizer with sufficient qubit numbers, such as: s_original = MixedDestabilizer(random_stabilizer(400,700)) |
Hi, @T-DHQian , thank you for reporting this, it is much appreciated. I further simplified your example a bit more -- it is definitely a bug in the library.
|
Here it is yet more simplified reproducer:
Happens only for pretty large number of qubits (>450)... |
The bug seems to be in the SIMD code in |
The final reproducer:
|
Thanks for your reply! Could you please explain a bit in detail on how to switch to a non-SIMD version? Should I just use _mul_ordered_nonvec! instead of mul_ordered! everywhere for now to get the correct answer? Meanwhile, does this issue have a prevalent impact on other operations since it is a basic operations appearing in many places, such as canonicalize!? |
Indeed, this issue seems to affect most phase calculations for expressions with roughly more than 500 qubits. It is rather disturbing that the test suite has not detected it (we have plenty of tests that run with large number of qubits). I will investigate when this started and how it was not detected after it is fixed. There is no straightforward way to switch to |
I'm not sure if the problem is possbly due to that SIMD may alter the order of computation, which may have detrimental impact on here: cnt2 ⊻= (newx1 ⊻ newz1 ⊻ x1z2) & anti_comm
cnt1 ⊻= anti_comm If I replace it to be something like: if packs>0
lane = SIMD.VecRange{veclen}(0)
@inbounds for i in 1:veclen:(len-veclen+1)
x1::VT, x2::VT, z1::VT, z2::VT = l[i+lane], r[i+lane], l[i+len+lane], r[i+len+lane]
r[i+lane] = newx1 = x1 ⊻ x2
r[i+len+lane] = newz1 = z1 ⊻ z2
x1z2 = x1 & z2
anti_comm = (x2 & z1) ⊻ x1z2
# Process each element in the vector to maintain order sensitivity
for j in 1:veclen
element_anti_comm = anti_comm[j]
rcnt2 ⊻= (rcnt1 ⊻ newx1[j] ⊻ newz1[j] ⊻ x1z2[j]) & element_anti_comm
rcnt1 ⊻= element_anti_comm
end
end
end the problem seems to be disappeared. However, the performance seems to be even worse than |
@T-DHQian , there is a really neat way to prove that the order does not matter without even touching the formulas: Imagine you have two large Pauli strings A and B and you calculate The bug was due to a missing term in the formula as you can see in the linked PR. This is a monumentally stupid mistake and I am very surprised it was not caught earlier. It is by far the worst bug we have ever had. Thank you for reporting it, it is greatly appreciated. |
Thank you so much! I believe the bug has now been fixed. I noticed the missing term and my previous testing might have been somewhat problematic, leading me to think that simply adding the missing term wasn't sufficient. This then made me consider whether the issue might be related to the order of computation. Your explanation is very clear and helpful. I will do more tests tomorrow, and I'll be sure to let you know if I encounter any other issues. |
Describe the bug 🐞
The traceout! function in QuantumClifford is producing unexpected results when applied to certain mixed stabilizer states. Specifically, the function's behavior doesn't align with theoretical expectations when comparing operations that should commute.
Expected behavior
Given a mixed stabilizer state, tracing out some qubits at the front should produce a reduced state on the remaining qubits.
Appending a single qubit in the |Z⟩ state at the end should not affect the reduced state of the original qubits, only adding a Z stabilizer on the new qubit.
In other words, these two operations should commute:
Operation A: Trace out front qubits, then append a |Z⟩ qubit
Operation B: Append a |Z⟩ qubit, then trace out front qubits
The resulting states from both operations should be identical.
Contrary to expectations, I've found that for some mixed stabilizer states, Operations A and B yield different results. This suggests that the traceout! function may not be correctly handling all cases.
Minimal Reproducible Example 👇
The output looks like:

Further examination on, for example, the second stabilzier:

One can see that the stabilizers differ in the sign, which makes them in two different orthogonal subspaces.
The state on which this issue occurs is quite tricky to get, and a certian one is in data.zip. It seems that this issue would only occur for larger system size.
The text was updated successfully, but these errors were encountered: