Skip to content

Commit

Permalink
Fix issues reported by JET (#385)
Browse files Browse the repository at this point in the history

---------

Co-authored-by: Stefan Krastanov <[email protected]>
Co-authored-by: Stefan Krastanov <[email protected]>
  • Loading branch information
3 people authored Oct 20, 2024
1 parent be50f9c commit 0ddc9e8
Show file tree
Hide file tree
Showing 18 changed files with 98 additions and 99 deletions.
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
6 changes: 0 additions & 6 deletions src/mul_leftright.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ function mul_ordered_lv!(r::AbstractVector{T}, l::AbstractVector{T}; phases::Val
end
=#

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
_mul_ordered_nonvec!(r,l; phases=B)
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
6 changes: 3 additions & 3 deletions src/randoms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function nemo_inv(a, n)::Matrix{UInt8}
end

"""Sample (h, S) from the distribution P_n(h, S) from Bravyi and Maslov Algorithm 1."""
function quantum_mallows(rng, n) # each one is benchmakred in benchmarks/quantum_mallows.jl
function quantum_mallows(rng::AbstractRNG, n::Int) # each one is benchmarked in benchmarks/quantum_mallows.jl
arr = collect(1:n)
hadamard = falses(n)
perm = zeros(Int64, n)
Expand All @@ -202,7 +202,7 @@ end

""" This function samples a number from 1 to `n` where `n >= 1`
probability of outputting `i` is proportional to `2^i`"""
function sample_geometric_2(rng, n::Integer)
function sample_geometric_2(rng::AbstractRNG, n::Integer)
n < 1 && throw(DomainError(n))
if n<30
k = rand(rng, 2:UInt(2)^n)
Expand All @@ -217,7 +217,7 @@ function sample_geometric_2(rng, n::Integer)
end

"""Assign (symmetric) random ints to off diagonals of matrix."""
function fill_tril(rng, matrix, n; symmetric::Bool=false)
function fill_tril(rng::AbstractRNG, matrix, n; symmetric::Bool=false)
# Add (symmetric) random ints to off diagonals
@inbounds for row in 1:n, col in 1:row-1
b = rand(rng, Bool)
Expand Down
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

0 comments on commit 0ddc9e8

Please sign in to comment.