Skip to content

Fix issues reported by JET #385

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

Merged
merged 14 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ LocalPreferences.toml
*/.*swp
scratch/
*.cov
.vscode
.vscode
test/.CondaPkg/
38 changes: 19 additions & 19 deletions src/QuantumClifford.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export
nqubits,
stabilizerview, destabilizerview, logicalxview, logicalzview, phases,
fastcolumn, fastrow,
bitview, quantumstate, tab,
bitview, quantumstate, tab, rank,
BadDataStructure,
affectedqubits, #TODO move to QuantumInterface?
# GF2
Expand Down Expand Up @@ -173,7 +173,7 @@ Tableau(xzs::AbstractMatrix{Bool}) = Tableau(zeros(UInt8, size(xzs,1)), xzs[:,1:

Tableau(t::Tableau) = t

function _T_str(a) # TODO this can be optimized by not creating intermediary PauliOperator objects
function _T_str(a::Union{String,SubString{String}}) # TODO this can be optimized by not creating intermediary PauliOperator objects
paulis = [_P_str(strip(s.match)) for s in eachmatch(r"[+-]?\h*[i]?\h*[XYZI_]+", a)]
Tableau(paulis)
end
Expand Down Expand Up @@ -229,18 +229,18 @@ end

Base.firstindex(tab::Tableau) = 1

Base.lastindex(tab::Tableau) = length(tab.phases)
Base.lastindex(tab::Tableau) = length(tab.phases)::Int
Base.lastindex(tab::Tableau, i) = size(tab)[i]

Base.eachindex(tab::Tableau) = Base.OneTo(lastindex(tab.phases))
Base.eachindex(tab::Tableau) = Base.OneTo(lastindex(tab.phases)::Int)

Base.axes(tab::Tableau) = (Base.OneTo(lastindex(tab)), Base.OneTo(nqubits(tab)))
Base.axes(tab::Tableau,i) = axes(tab)[i]

Base.size(tab::Tableau) = (length(tab.phases),nqubits(tab))
Base.size(tab::Tableau) = (length(tab.phases)::Int, nqubits(tab))
Base.size(tab::Tableau,i) = size(tab)[i]

Base.length(tab::Tableau) = length(tab.phases)
Base.length(tab::Tableau) = length(tab.phases)::Int

Base.:(==)(l::Tableau, r::Tableau) = r.nqubits==l.nqubits && r.phases==l.phases && r.xzs==l.xzs

Expand Down Expand Up @@ -378,7 +378,7 @@ macro S_str(a)
quote Stabilizer(_T_str($a)) end
end
Base.getindex(stab::Stabilizer, i::Int) = tab(stab)[i]
Base.getindex(stab::Stabilizer, i) = Stabilizer(tab(stab)[i])
Base.getindex(stab::Stabilizer, i) = Stabilizer(tab(stab)[i]::Tableau)
@inline Base.getindex(stab::Stabilizer, r::Int, c) = tab(stab)[r,c]
Base.getindex(stab::Stabilizer, r, c) = Stabilizer(tab(stab)[r,c])
Base.view(stab::Stabilizer, r) = Stabilizer(view(tab(stab),r))
Expand Down Expand Up @@ -497,11 +497,11 @@ function MixedStabilizer(s::Stabilizer{T}) where {T}
MixedStabilizer(spadded,zr)
end

MixedStabilizer(s::Stabilizer,rank::Int) = MixedStabilizer(tab(s),rank)
MixedStabilizer(s::Stabilizer,rank::Int) = MixedStabilizer(tab(s), rank)

Base.length(d::MixedStabilizer) = length(d.tab)
Base.length(d::MixedStabilizer) = length(tab(d))

Base.copy(ms::MixedStabilizer) = MixedStabilizer(copy(ms.tab),ms.rank)
Base.copy(ms::MixedStabilizer) = MixedStabilizer(copy(tab(ms)), rank(ms))

##############################
# Mixed Destabilizer states
Expand Down Expand Up @@ -580,15 +580,15 @@ function MixedDestabilizer(stab::Stabilizer{T}; undoperm=true, reportperm=false)
end

function MixedDestabilizer(d::Destabilizer, r::Int)
l,n = size(d.tab)
l,n = size(tab(d))
if l==2n
MixedDestabilizer(tab(d), r)
else
throw(DomainError("Only full-rank `Destabilizer` can be converted to `MixedDestabilizer` with specific rank. Try not specifying `r`."))
end
end
function MixedDestabilizer(d::Destabilizer)
l,n = size(d.tab)
l,n = size(tab(d))
if l==2n
MixedDestabilizer(d, nqubits(d))
else
Expand All @@ -599,9 +599,9 @@ end
MixedDestabilizer(d::MixedStabilizer) = MixedDestabilizer(stabilizerview(d))
MixedDestabilizer(d::MixedDestabilizer) = d

Base.length(d::MixedDestabilizer) = length(d.tab)÷2
Base.length(d::MixedDestabilizer) = length(tab(d))÷2

Base.copy(d::MixedDestabilizer) = MixedDestabilizer(copy(d.tab),d.rank)
Base.copy(d::MixedDestabilizer) = MixedDestabilizer(copy(tab(d)),rank(d))

##############################
# Subtableau views
Expand All @@ -610,17 +610,17 @@ Base.copy(d::MixedDestabilizer) = MixedDestabilizer(copy(d.tab),d.rank)
"""A view of the subtableau corresponding to the stabilizer. See also [`tab`](@ref), [`destabilizerview`](@ref), [`logicalxview`](@ref), [`logicalzview`](@ref)"""
@inline stabilizerview(s::Stabilizer) = s
@inline stabilizerview(s::Destabilizer) = Stabilizer(@view tab(s)[end÷2+1:end])
@inline stabilizerview(s::MixedStabilizer) = Stabilizer(@view tab(s)[1:s.rank])
@inline stabilizerview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[end÷2+1:end÷2+s.rank])
@inline stabilizerview(s::MixedStabilizer) = Stabilizer(@view tab(s)[1:rank(s)])
@inline stabilizerview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[end÷2+1:end÷2+rank(s)])

"""A view of the subtableau corresponding to the destabilizer. See also [`tab`](@ref), [`stabilizerview`](@ref), [`logicalxview`](@ref), [`logicalzview`](@ref)"""
@inline destabilizerview(s::Destabilizer) = Stabilizer(@view tab(s)[1:end÷2])
@inline destabilizerview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[1:s.rank])
@inline destabilizerview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[1:rank(s)])

"""A view of the subtableau corresponding to the logical X operators. See also [`tab`](@ref), [`stabilizerview`](@ref), [`destabilizerview`](@ref), [`logicalzview`](@ref)"""
@inline logicalxview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[s.rank+1:end÷2])
@inline logicalxview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[rank(s)+1:end÷2])
"""A view of the subtableau corresponding to the logical Z operators. See also [`tab`](@ref), [`stabilizerview`](@ref), [`destabilizerview`](@ref), [`logicalxview`](@ref)"""
@inline logicalzview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[end÷2+s.rank+1:end])
@inline logicalzview(s::MixedDestabilizer) = Stabilizer(@view tab(s)[end÷2+rank(s)+1:end])

"""The number of qubits of a given state."""
@inline nqubits(s::AbstractStabilizer) = nqubits(tab(s))
Expand Down
12 changes: 6 additions & 6 deletions src/dense_cliffords.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ CliffordOperator(op::CliffordOperator) = op
CliffordOperator(paulis::AbstractVector{<:PauliOperator}) = CliffordOperator(Tableau(paulis))
CliffordOperator(destab::Destabilizer) = CliffordOperator(tab(destab))

Base.:(==)(l::CliffordOperator, r::CliffordOperator) = l.tab == r.tab
Base.:(==)(l::CliffordOperator, r::CliffordOperator) = tab(l) == tab(r)
Base.hash(c::T, h::UInt) where {T<:CliffordOperator} = hash(T, hash(tab(c), h))

Base.getindex(c::CliffordOperator, args...) = getindex(tab(c), args...)
Expand All @@ -85,16 +85,16 @@ digits_subchars = collect("₀₁₂₃₄₅₆₇₈₉")
digits_substr(n::Int,nwidth::Int) = join(([digits_subchars[d+1] for d in reverse(digits(n, pad=nwidth))]))

function Base.copy(c::CliffordOperator)
CliffordOperator(copy(c.tab))
CliffordOperator(copy(tab(c)))
end

@inline nqubits(c::CliffordOperator) = nqubits(c.tab)
@inline nqubits(c::CliffordOperator) = nqubits(tab(c))

Base.zero(c::CliffordOperator) = CliffordOperator(zero(c.tab))
Base.zero(c::CliffordOperator) = CliffordOperator(zero(tab(c)))
Base.zero(::Type{<:CliffordOperator}, n) = CliffordOperator(zero(Tableau, 2n, n))

function Base.:(*)(l::AbstractCliffordOperator, r::CliffordOperator)
tab = copy(r.tab)
tab = copy(QuantumClifford.tab(r))
apply!(Stabilizer(tab),l) # TODO maybe not the most elegant way to perform apply!(::Tableau, gate)
CliffordOperator(tab)
end
Expand All @@ -106,7 +106,7 @@ end

# TODO create Base.permute! and getindex(..., permutation_array)
function permute(c::CliffordOperator,p) # TODO this is a slow stupid implementation
CliffordOperator(Tableau([c.tab[i][p] for i in 1:2*nqubits(c)][vcat(p,p.+nqubits(c))]))
CliffordOperator(Tableau([tab(c)[i][p] for i in 1:2*nqubits(c)][vcat(p,p.+nqubits(c))]))
end

"""Nonvectorized version of `apply!` used for unit tests."""
Expand Down
1 change: 1 addition & 0 deletions src/ecc/circuits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function perm_to_transpositions(perm)
for i in n:-1:1
if perm[i]!=i
j = findfirst(==(i), perm)
@assert !isnothing(j)
push!(transpositions, (i, j))
perm[j] = perm[i]
end
Expand Down
2 changes: 1 addition & 1 deletion src/ecc/decoder_pipeline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ function create_lookup_table(code::Stabilizer)
for bit_to_be_flipped in 1:qubits
for error_type in [single_x, single_y, single_z]
# Generate e⃗
error = error_type(qubits, bit_to_be_flipped)
error = error_type(qubits, bit_to_be_flipped)::PauliOperator{Array{UInt8, 0}, Vector{UInt}}
# Calculate s⃗
# (check which stabilizer rows do not commute with the Pauli error)
syndrome = comm(error, code)
Expand Down
16 changes: 8 additions & 8 deletions src/fastmemlayout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ fastrow(t::Tableau{Tₚᵥ,Tₘ}) where {Tₚᵥ, Tₘ<:Adjoint} = Tableau(t.pha
fastcolumn(t::Tableau{Tₚᵥ,Tₘ}) where {Tₚᵥ, Tₘ} = Tableau(t.phases, t.nqubits, collect(t.xzs')')
fastcolumn(t::Tableau{Tₚᵥ,Tₘ}) where {Tₚᵥ, Tₘ<:Adjoint} = t

fastrow(s::Stabilizer) = Stabilizer(fastrow(s.tab))
fastcolumn(s::Stabilizer) = Stabilizer(fastcolumn(s.tab))
fastrow(s::Stabilizer) = Stabilizer(fastrow(tab(s)))
fastcolumn(s::Stabilizer) = Stabilizer(fastcolumn(tab(s)))

fastrow(s::Destabilizer) = Destabilizer(fastrow(s.tab))
fastcolumn(s::Destabilizer) = Destabilizer(fastcolumn(s.tab))
fastrow(s::Destabilizer) = Destabilizer(fastrow(tab(s)))
fastcolumn(s::Destabilizer) = Destabilizer(fastcolumn(tab(s)))

fastrow(s::MixedStabilizer) = MixedStabilizer(fastrow(s.tab), s.rank)
fastcolumn(s::MixedStabilizer) = MixedStabilizer(fastcolumn(s.tab), s.rank)
fastrow(s::MixedStabilizer) = MixedStabilizer(fastrow(tab(s)), rank(s))
fastcolumn(s::MixedStabilizer) = MixedStabilizer(fastcolumn(tab(s)), rank(s))

fastrow(s::MixedDestabilizer) = MixedDestabilizer(fastrow(s.tab), s.rank)
fastcolumn(s::MixedDestabilizer) = MixedDestabilizer(fastcolumn(s.tab), s.rank)
fastrow(s::MixedDestabilizer) = MixedDestabilizer(fastrow(tab(s)), rank(s))
fastcolumn(s::MixedDestabilizer) = MixedDestabilizer(fastcolumn(tab(s)), rank(s))
2 changes: 1 addition & 1 deletion src/linalg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ function tensor(ops::CliffordOperator...) # TODO implement \otimes for Destabili
last_zrow = ntot
last_xrow = 0
for op in ops
t = op.tab
t = QuantumClifford.tab(op)
_, last_zrow, _ = puttableau!(tab, (@view t[end÷2+1:end]), last_zrow, last_xrow)
_, last_xrow, _ = puttableau!(tab, (@view t[1:end÷2]), last_xrow, last_xrow)
end
Expand Down
3 changes: 3 additions & 0 deletions src/mul_leftright.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,14 @@ function mul_ordered_lv!(r::AbstractVector{T}, l::AbstractVector{T}; phases::Val
end
=#

# This method is already covered by the identical but less specific one right below. (And JET does not like it)
#=
function mul_ordered!(r::SubArray{T,1,P,I1,L1}, l::SubArray{T,1,P,I2,L2}; phases::Val{B}=Val(true)) where {T<:Unsigned, B, I1, I2, L1, L2, P<:Adjoint}
# This method exists because SIMD.jl does not play well with Adjoint
# Delete it and try `QuantumClifford.mul_left!(fastcolumn(random_stabilizer(194)), 2, 1)` # works fine for 192
_mul_ordered_nonvec!(r,l; phases=B)
end
=#

function mul_ordered!(r::SubArray{T,1,P,I2,L2}, l::AbstractVector{T}; phases::Val{B}=Val(true)) where {T<:Unsigned, B, I2, L2, P<:Adjoint}
# This method exists because SIMD.jl does not play well with Adjoint
Expand Down
7 changes: 4 additions & 3 deletions src/pauli_operator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function zbit(p::PauliOperator)
[(word>>s)&one==one for word in zview(p) for s in 0:size-1][begin:p.nqubits]
end

function _P_str(a)
function _P_str(a::Union{String,SubString{String}})
letters = filter(x->occursin(x,"_IZXY"),a)
phase = phasedict[strip(filter(x->!occursin(x,"_IZXY"),a))]
PauliOperator(phase, [l=='X'||l=='Y' for l in letters], [l=='Z'||l=='Y' for l in letters])
Expand All @@ -87,7 +87,7 @@ macro P_str(a)
quote _P_str($a) end
end

Base.getindex(p::PauliOperator{Tₚ,Tᵥ}, i::Int) where {Tₚ, Tᵥₑ<:Unsigned, Tᵥ<:AbstractVector{Tᵥₑ}} = (p.xz[_div(Tᵥₑ, i-1)+1] & Tᵥₑ(0x1)<<_mod(Tᵥₑ,i-1))!=0x0, (p.xz[end÷2+_div(Tᵥₑ,i-1)+1] & Tᵥₑ(0x1)<<_mod(Tᵥₑ,i-1))!=0x0
Base.getindex(p::PauliOperator{Tₚ,Tᵥ}, i::Int) where {Tₚ, Tᵥₑ<:Unsigned, Tᵥ<:AbstractVector{Tᵥₑ}} = ((p.xz[_div(Tᵥₑ, i-1)+1] & Tᵥₑ(0x1)<<_mod(Tᵥₑ,i-1))!=0x0)::Bool, ((p.xz[end÷2+_div(Tᵥₑ,i-1)+1] & Tᵥₑ(0x1)<<_mod(Tᵥₑ,i-1))!=0x0)::Bool
Base.getindex(p::PauliOperator{Tₚ,Tᵥ}, r) where {Tₚ, Tᵥₑ<:Unsigned, Tᵥ<:AbstractVector{Tᵥₑ}} = PauliOperator(p.phase[], xbit(p)[r], zbit(p)[r])

function Base.setindex!(p::PauliOperator{Tₚ,Tᵥ}, (x,z)::Tuple{Bool,Bool}, i) where {Tₚ, Tᵥₑ, Tᵥ<:AbstractVector{Tᵥₑ}}
Expand Down Expand Up @@ -176,7 +176,8 @@ end
function embed(n::Int, indices, p::PauliOperator)
if nqubits(p) == length(indices)
pout = zero(typeof(p), n)
@inbounds @simd for i in eachindex(indices)
@inbounds @simd for i_ in eachindex(indices)
i = i_::Int
pout[indices[i]] = p[i]
end
pout.phase[] = p.phase[]
Expand Down
10 changes: 5 additions & 5 deletions src/project_trace_reset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ end

function _project!(d::Destabilizer,pauli::PauliOperator;keep_result::Val{Bkr}=Val(true),phases::Val{Bp}=Val(true)) where {Bkr, Bp} # repetition between Destabilizer and MixedDestabilizer, but the redundancy makes the two codes slightly simpler and easier to infer
anticommutes = 0
tab = d.tab
tab = QuantumClifford.tab(d)
stabilizer = stabilizerview(d)
destabilizer = destabilizerview(d)
r = trusted_rank(d)
Expand Down Expand Up @@ -377,7 +377,7 @@ end

function _project!(d::MixedDestabilizer,pauli::PauliOperator;keep_result::Val{Bkr}=Val(true),phases::Val{Bp}=Val(true)) where {Bkr, Bp} # repetition between Destabilizer and MixedDestabilizer, but the redundancy makes the two codes slightly simpler and easier to infer
anticommutes = 0
tab = d.tab
tab = QuantumClifford.tab(d)
stabilizer = stabilizerview(d)
destabilizer = destabilizerview(d)
r = trusted_rank(d)
Expand Down Expand Up @@ -497,7 +497,7 @@ end
"""Internal method used to implement [`projectX!`](@ref), [`projectZ!`](@ref), and [`projectY!`](@ref)."""
function project_cond!(d::MixedDestabilizer,qubit::Int,cond::Val{IS},reset::Val{RESET};keep_result::Bool=true,phases::Val{PHASES}=Val(true)) where {IS,RESET,PHASES}
anticommutes = 0
tab = d.tab
tab = QuantumClifford.tab(d)
stabilizer = stabilizerview(d)
destabilizer = destabilizerview(d)
r = d.rank
Expand Down Expand Up @@ -647,7 +647,7 @@ function traceout!(s::Union{MixedStabilizer, MixedDestabilizer}, qubits; phases=
if rank return (s, i) else return s end
end

function _expand_pauli(pauli,qubits,n) # TODO rename and make public
function _expand_pauli(pauli::PauliOperator,qubits,n) # TODO rename and make public
expanded = zero(PauliOperator,n)
for (ii, i) in enumerate(qubits)
expanded[i] = pauli[ii]
Expand Down Expand Up @@ -886,4 +886,4 @@ See also: [`traceout!`](@ref)
"""
function delete_columns(𝒮::Stabilizer, subset)
return 𝒮[:, setdiff(1:nqubits(𝒮), subset)]
end
end
2 changes: 1 addition & 1 deletion src/symbolic_cliffords.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ SingleQubitOperator(p::sInvSQRTY) = SingleQubitOperator(p.q, false, tr
SingleQubitOperator(o::SingleQubitOperator) = o
function SingleQubitOperator(op::CliffordOperator, qubit)
nqubits(op)==1 || throw(DimensionMismatch("You are trying to convert a multiqubit `CliffordOperator` into a symbolic `SingleQubitOperator`."))
SingleQubitOperator(qubit,op.tab[1,1]...,op.tab[2,1]...,(~).(iszero.(op.tab.phases))...)
SingleQubitOperator(qubit,tab(op)[1,1]...,tab(op)[2,1]...,(~).(iszero.(tab(op).phases))...)
end
SingleQubitOperator(op::CliffordOperator) = SingleQubitOperator(op, 1)

Expand Down
Loading
Loading