Skip to content

Commit 1fb1783

Browse files
authored
fix for wrong SIMD mul_left! #320 (#322)
1 parent 3ea5414 commit 1fb1783

File tree

5 files changed

+34
-3
lines changed

5 files changed

+34
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
# News
77

8+
## v0.9.7 - 2024-07-23
9+
10+
- **(fix `#320`)** Fix a serious correctness bug in the SIMD implementation of Pauli string multiplication (affects the correctness of canonicalization and traceout for tableaux bigger than ~500 qubits; does not affect symbolic gates or Pauli frame simulations of any scale)
811
## v0.9.6 - 2024-07-12
912

1013
- `inv` implementation for single-qubit "symbolic" Clifford operators (subtypes of `AbstractSingleQubitOperator`).

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "QuantumClifford"
22
uuid = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
33
authors = ["Stefan Krastanov <[email protected]> and QuantumSavory community members"]
4-
version = "0.9.6"
4+
version = "0.9.7"
55

66
[deps]
77
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"

src/mul_leftright.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ function mul_ordered!(r::AbstractVector{T}, l::AbstractVector{T}; phases::Val{B}
8989
r[i+len+lane] = newz1 = z1 z2
9090
x1z2 = x1 & z2
9191
anti_comm = (x2 & z1) x1z2
92-
cnt2 ⊻= (newx1 newz1 x1z2) & anti_comm
92+
cnt2 ⊻= (cnt1 newx1 newz1 x1z2) & anti_comm
9393
cnt1 ⊻= anti_comm
9494
end
9595
for i in 1:length(cnt1)

test/test_mul_leftright.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using Test
55

66
test_sizes = [1,2,10,63,64,65,127,128,129] # Including sizes that would test off-by-one errors in the bit encoding.
77

8-
@testset "Inner product between stabilizer states" begin
8+
@testset "Pauli string multiplication" begin
99
for n in test_sizes
1010
for _ in 1:20
1111
p1 = random_pauli(n)
@@ -22,3 +22,18 @@ test_sizes = [1,2,10,63,64,65,127,128,129] # Including sizes that would test off
2222
end
2323
end
2424
end
25+
26+
# test for #320
27+
@testset "verify SIMD implementation" begin
28+
for i in 1:10,
29+
n in 1:30,
30+
T in [UInt8, UInt16, UInt32, UInt64]
31+
a = rand(T, n)
32+
b = rand(T, n)
33+
c1,c2 = QuantumClifford.mul_ordered!(copy(a),copy(b))
34+
n1,n2 = QuantumClifford._mul_ordered_nonvec!(copy(a),copy(b))
35+
np = ((n1 (n2<<1))&0x3)
36+
cp = ((c1 (c2<<1))&0x3)
37+
@test np==cp
38+
end
39+
end

test/test_stabcanon.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,16 @@ test_sizes = [1,2,10,63,64,65,127,128,129] # Including sizes that would test off
7474
end
7575
end
7676
end
77+
78+
@testset "canonicalization invariants" begin
79+
s = random_stabilizer(40,100)
80+
ss = tensor_pow(s,20)
81+
sa1 = canonicalize!(canonicalize_rref!(copy(ss))[1])
82+
sa2 = canonicalize!(copy(ss))
83+
@test sa1 == sa2
84+
ms = MixedDestabilizer(s)
85+
mss = tensor_pow(ms, 20)
86+
msa1 = canonicalize!(canonicalize_rref!(copy(mss))[1])
87+
msa2 = canonicalize!(copy(mss))
88+
@test stabilizerview(msa1) == stabilizerview(msa2) == sa1
89+
end

0 commit comments

Comments
 (0)