Skip to content

Commit

Permalink
use @valbooldispatch instead of constprop
Browse files Browse the repository at this point in the history
  • Loading branch information
Krastanov committed Sep 24, 2022
1 parent 7d72bb2 commit e2b5bee
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
matrix:
version:
- '1'
- '1.7'
- '1.6'
os:
- ubuntu-latest
threads:
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# News

## v0.6.3 - 2022-09-24

- Bring the v0.6.2 performance improvements to Julia 1.7 and 1.6. Switch from using `constprop` to explicit static dispatch with `@valbooldispatch`.
- Support Julia 1.6 again.

## v0.6.2 - 2022-09-22

- Performance improvements: fine tuning of `:constprop`, eliminating a handful of common causes of dynamic dispatch.
- Performance improvements: fine tuning of `constprop`, eliminating a handful of common causes of dynamic dispatch.
- Drop support for Julia 1.6.

## v0.6.1 - 2022-09-05
Expand Down
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "QuantumClifford"
uuid = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
authors = ["Stefan Krastanov <[email protected]>"]
version = "0.6.2"
version = "0.6.3"

[deps]
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
Expand All @@ -10,6 +10,7 @@ Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
HostCPUFeatures = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0"
ILog2 = "2cd5bd5f-40a1-5050-9e10-fc8cdb6109f5"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a"
Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Expand All @@ -22,8 +23,9 @@ DocStringExtensions = "0.8, 0.9"
Graphs = "1.4.1"
HostCPUFeatures = "0.1.6"
ILog2 = "0.2.3"
MacroTools = "0.5.9"
Nemo = "0.28, 0.29, 0.30, 0.31, 0.32"
Polyester = "0.6.14"
SIMD = "3.4.0"
SnoopPrecompile = "1"
julia = "1.7"
julia = "1.6"
14 changes: 8 additions & 6 deletions src/QuantumClifford.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ const _mi = 0x03
const phasedict = Dict(""=>_p,"+"=>_p,"i"=>_pi,"+i"=>_pi,"-"=>_m,"-i"=>_mi)
const toletter = Dict((false,false)=>"_",(true,false)=>"X",(false,true)=>"Z",(true,true)=>"Y")

include("macrotools.jl")

##############################
# Pauli Operators
##############################
Expand Down Expand Up @@ -1128,15 +1130,15 @@ Base.vcat(stabs::Stabilizer...) = Stabilizer(vcat((tab(s) for s in stabs)...))
# Unitary Clifford Operations
##############################

Base.@constprop :aggressive function Base.:(*)(p::AbstractCliffordOperator, s::AbstractStabilizer; phases::Bool=true)
function Base.:(*)(p::AbstractCliffordOperator, s::AbstractStabilizer; phases::Bool=true)
s = copy(s)
_apply!(s,p; phases=Val(phases))
@valbooldispatch _apply!(s,p; phases=Val(phases)) phases
end
Base.@constprop :aggressive function apply!(stab::AbstractStabilizer, op::AbstractCliffordOperator; phases::Bool=true)
_apply!(stab,op; phases=Val(phases))
function apply!(stab::AbstractStabilizer, op::AbstractCliffordOperator; phases::Bool=true)
@valbooldispatch _apply!(stab,op; phases=Val(phases)) phases
end
Base.@constprop :aggressive function apply!(stab::AbstractStabilizer, op::AbstractCliffordOperator, indices; phases::Bool=true)
_apply!(stab,op,indices; phases=Val(phases))
function apply!(stab::AbstractStabilizer, op::AbstractCliffordOperator, indices; phases::Bool=true)
@valbooldispatch _apply!(stab,op,indices; phases=Val(phases)) phases
end

# TODO no need to track phases outside of stabview
Expand Down
12 changes: 6 additions & 6 deletions src/canonicalization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ Based on [garcia2012efficient](@cite).
See also: [`canonicalize_rref!`](@ref), [`canonicalize_gott!`](@ref)
"""
Base.@constprop :aggressive function canonicalize!(state::AbstractStabilizer; phases::Bool=true, ranks::Bool=false)
_canonicalize!(state; phases=Val(phases), ranks=Val(ranks))
function canonicalize!(state::AbstractStabilizer; phases::Bool=true, ranks::Bool=false)
@valbooldispatch _canonicalize!(state; phases=Val(phases), ranks=Val(ranks)) phases ranks
end
function _canonicalize!(state::AbstractStabilizer; phases::Val{Bphases}=Val(true), ranks::Val{Branks}=Val(false)) where {Bphases,Branks}
tab = stabilizerview(state)
Expand Down Expand Up @@ -142,8 +142,8 @@ Based on [audenaert2005entanglement](@cite).
See also: [`canonicalize!`](@ref), [`canonicalize_gott!`](@ref)
"""
Base.@constprop :aggressive function canonicalize_rref!(state::AbstractStabilizer, colindices; phases::Bool=true)
_canonicalize_rref!(state, colindices; phases=Val(phases))
function canonicalize_rref!(state::AbstractStabilizer, colindices; phases::Bool=true)
@valbooldispatch _canonicalize_rref!(state, colindices; phases=Val(phases)) phases
end
function _canonicalize_rref!(state::AbstractStabilizer, colindices; phases::Val{B}=Val(true)) where B
tab = stabilizerview(state)
Expand Down Expand Up @@ -213,8 +213,8 @@ Based on [gottesman1997stabilizer](@cite).
See also: [`canonicalize!`](@ref), [`canonicalize_rref!`](@ref)
"""
Base.@constprop :aggressive function canonicalize_gott!(stabilizer::Stabilizer; phases::Bool=true)
_canonicalize_gott!(stabilizer; phases=Val(phases))
function canonicalize_gott!(stabilizer::Stabilizer; phases::Bool=true)
@valbooldispatch _canonicalize_gott!(stabilizer; phases=Val(phases)) phases
end
function _canonicalize_gott!(stabilizer::Stabilizer; phases::Val{B}=Val(true)) where {B}
xzs = tab(stabilizer).xzs
Expand Down
4 changes: 2 additions & 2 deletions src/dense_cliffords.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ function Base.:(*)(l::AbstractCliffordOperator, r::CliffordOperator)
CliffordOperator(tab)
end

Base.@constprop :aggressive function apply!(r::CliffordOperator, l::AbstractCliffordOperator; phases=false)
_apply!(Stabilizer(tab(r)),l;phases=Val(phases)) # TODO maybe not the most elegant way to perform apply!(::Tableau, gate)
function apply!(r::CliffordOperator, l::AbstractCliffordOperator; phases=false)
@valbooldispatch _apply!(Stabilizer(tab(r)),l;phases=Val(phases)) phases # TODO maybe not the most elegant way to perform apply!(::Tableau, gate)
r
end

Expand Down
4 changes: 2 additions & 2 deletions src/entanglement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Introduced in [nahum2017quantum](@cite), with a more detailed explanation of the
See also: [`canonicalize!`](@ref), [`canonicalize_rref!`](@ref), [`canonicalize_gott!`](@ref).
"""
Base.@constprop :aggressive function canonicalize_clip!(state::AbstractStabilizer; phases::Bool=true)
_canonicalize_clip!(state; phases=Val(phases))
function canonicalize_clip!(state::AbstractStabilizer; phases::Bool=true)
@valbooldispatch _canonicalize_clip!(state; phases=Val(phases)) phases
end
function _canonicalize_clip!(state::AbstractStabilizer; phases::Val{B}=Val(true)) where B
tab = stabilizerview(state)
Expand Down
19 changes: 19 additions & 0 deletions src/macrotools.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using MacroTools

"""Turns `f(Val(x))` into `x ? f(Val(true)) : f(Val(false))` in order to avoid dynamic dispatch
See [discourse discussion](https://discourse.julialang.org/t/allocations-due-to-boolean-keyword-arguments-how-to-avoid-them/87654)"""
macro valbooldispatch(expr, bools...)
for bool in bools
true_branch = MacroTools.postwalk(x->@capture(x, Val($bool)) ? :(Val(true )) : x, expr)
false_branch = MacroTools.postwalk(x->@capture(x, Val($bool)) ? :(Val(false)) : x, expr)
expr = quote
if $bool
$true_branch
else
$false_branch
end
end
end
esc(expr)
end
3 changes: 2 additions & 1 deletion src/precompiles.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ end

using SnoopPrecompile

@precompile_setup begin
# precompilation causes allocation performance bugs for <v1.8 https://github.com/JuliaLang/julia/issues/35972
VERSION > v"1.8" && @precompile_setup begin
# Putting some things in `setup` can reduce the size of the
# precompile file and potentially make loading faster.
@precompile_all_calls begin
Expand Down
31 changes: 13 additions & 18 deletions src/project_trace_reset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ julia> generate!(P"XII",canonicalize!(S"XII")) === nothing
false
```
"""
Base.@constprop :aggressive function generate!(pauli::PauliOperator, stabilizer::Stabilizer; phases::Bool=true, saveindices::Bool=true)
_phases = Val(phases)
_saveindices = Val(saveindices)
_generate!(pauli, stabilizer; phases=_phases, saveindices=_saveindices)
function generate!(pauli::PauliOperator, stabilizer::Stabilizer; phases::Bool=true, saveindices::Bool=true)
@valbooldispatch _generate!(pauli, stabilizer; phases=Val(phases), saveindices=Val(saveindices)) phases saveindices
end

function _generate!(pauli::PauliOperator{Tz,Tv}, stabilizer::Stabilizer{Tableau{Tzv,Tm}}; phases::Val{PHASES}=Val(true), saveindices::Val{SAVEIDX}=Val(true)) where {Tz<:AbstractArray{UInt8,0}, Tzv<:AbstractVector{UInt8}, Tme<:Unsigned, Tv<:AbstractVector{Tme}, Tm<:AbstractMatrix{Tme}, PHASES, SAVEIDX} # TODO there is stuff that can be abstracted away here and in canonicalize!
Expand Down Expand Up @@ -231,8 +229,8 @@ See the "Datastructure Choice" section in the documentation for more details.
See also: [`projectX!`](@ref), [`projectY!`](@ref), [`projectZ!`](@ref), [`projectrand!`](@ref)
"""
Base.@constprop :aggressive function project!(state,pauli::PauliOperator;keep_result::Bool=true,phases::Bool=true)
return _project!(state,pauli;keep_result=Val(keep_result),phases=Val(phases))
function project!(state,pauli::PauliOperator;keep_result::Bool=true,phases::Bool=true)
@valbooldispatch _project!(state,pauli;keep_result=Val(keep_result),phases=Val(phases)) keep_result phases
end

# TODO maybe just add keep_result to it, for consistency
Expand Down Expand Up @@ -273,8 +271,8 @@ See the "Datastructure Choice" section in the documentation for more details.
See also: [`projectX!`](@ref), [`projectY!`](@ref), [`projectZ!`](@ref).
"""
Base.@constprop :aggressive function project!(state::MixedStabilizer,pauli::PauliOperator;phases::Bool=true)
return _project!(state,pauli;phases=Val(phases))
function project!(state::MixedStabilizer,pauli::PauliOperator;phases::Bool=true)
@valbooldispatch _project!(state,pauli;phases=Val(phases)) phases
end

function _project!(stabilizer::Stabilizer,pauli::PauliOperator;keep_result::Val{Bkr}=Val(true),phases::Val{Bp}=Val(true)) where {Bkr,Bp}
Expand Down Expand Up @@ -448,9 +446,8 @@ A faster special-case version of [`project!`](@ref).
See also: [`project!`](@ref), [`projectXrand!`](@ref), [`projectY!`](@ref), [`projectZ!`](@ref).
"""
Base.@constprop :aggressive function projectX!(d::MixedDestabilizer,qubit::Int;keep_result::Bool=true,phases::Bool=true)
_phases = Val(phases)
project_cond!(d,qubit,Val(isZ),Val((true,false));keep_result,phases=_phases)
function projectX!(d::MixedDestabilizer,qubit::Int;keep_result::Bool=true,phases::Bool=true)
@valbooldispatch project_cond!(d,qubit,Val(isZ),Val((true,false));keep_result,phases=Val(phases)) phases
end

"""
Expand All @@ -459,9 +456,8 @@ A faster special-case version of [`project!`](@ref).
See also: [`project!`](@ref), [`projectZrand!`](@ref), [`projectY!`](@ref), [`projectX!`](@ref).
"""
Base.@constprop :aggressive function projectZ!(d::MixedDestabilizer,qubit::Int;keep_result::Bool=true,phases::Bool=true)
_phases = Val(phases)
project_cond!(d,qubit,Val(isX),Val((false,true));keep_result,phases=_phases)
function projectZ!(d::MixedDestabilizer,qubit::Int;keep_result::Bool=true,phases::Bool=true)
@valbooldispatch project_cond!(d,qubit,Val(isX),Val((false,true));keep_result,phases=Val(phases))
end

"""
Expand All @@ -470,9 +466,8 @@ A faster special-case version of [`project!`](@ref).
See also: [`project!`](@ref), [`projectYrand!`](@ref), [`projectX!`](@ref), [`projectZ!`](@ref).
"""
Base.@constprop :aggressive function projectY!(d::MixedDestabilizer,qubit::Int;keep_result::Bool=true,phases::Bool=true)
_phases = Val(phases)
project_cond!(d,qubit,Val(isXorZ),Val((true,true));keep_result,phases=_phases)
function projectY!(d::MixedDestabilizer,qubit::Int;keep_result::Bool=true,phases::Bool=true)
@valbooldispatch project_cond!(d,qubit,Val(isXorZ),Val((true,true));keep_result,phases=Val(phases))
end

@inline isX(tab,row,col) = tab[row,col][1]
Expand Down Expand Up @@ -699,7 +694,7 @@ end
"""
$TYPEDSIGNATURES
"""
Base.@constprop :aggressive function reset_qubits!(s::MixedDestabilizer, newstate::AbstractStabilizer, qubits; phases=true) # TODO this is really inefficient
function reset_qubits!(s::MixedDestabilizer, newstate::AbstractStabilizer, qubits; phases=true) # TODO this is really inefficient
_phases = Val(phases)
nqubits(newstate)==length(qubits) || throw(DimensionMismatch("`qubits` and `newstate` have to be of consistent size"))
length(qubits) <= nqubits(s) || throw(DimensionMismatch("the stabilizer is not big enough to contain the new state"))
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREA
@doset "hash"
@doset "entanglement"
@doset "enumerate"
VERSION >= v"1.8" && @doset "allocations"
VERSION >= v"1.7" && @doset "allocations"
VERSION == v"1.8" && @doset "doctests"
get(ENV,"QUANTUMCLIFFORD_JET_TEST","")=="true" && @doset "jet"

Expand Down

0 comments on commit e2b5bee

Please sign in to comment.