From a9fa609a41e3e0b44076c9a2e10764e9e1934466 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Fri, 2 Aug 2024 14:19:54 +0200 Subject: [PATCH 01/23] Runtests use TestItemsRunner --- test/runtests.jl | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 942565ec..452cdb77 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,6 @@ -using SafeTestsets using QuantumSavory +using TestItems +using TestItemRunner function doset(descr) if length(ARGS) == 0 @@ -23,28 +24,7 @@ end println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREADS = $(Sys.CPU_THREADS)`...") -@doset "quantumchannel" -@doset "register_interface" -@doset "project_traceout" -@doset "observable" -@doset "noninstant_and_backgrounds_qubit" -@doset "noninstant_and_backgrounds_qumode" -@doset "messagebuffer" -@doset "tags_and_queries" - -@doset "protocolzoo_entanglement_tracker" -@doset "protocolzoo_entanglement_consumer" -@doset "protocolzoo_entanglement_tracker_grid" -@doset "protocolzoo_switch" -@doset "protocolzoo_throws" -@doset "protocolzoo_cutoffprot" - -@doset "circuitzoo_api" -@doset "circuitzoo_ent_swap" -@doset "circuitzoo_purification" -@doset "circuitzoo_superdense" - -@doset "stateszoo_api" +@run_package_tests filter=ti->doset(ti.name) if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" using Pkg @@ -56,4 +36,4 @@ get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" && @doset "plotting_gl" get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" && VERSION >= v"1.9" && @doset "doctests" get(ENV,"JET_TEST","")=="true" && @doset "jet" -@doset "aqua" \ No newline at end of file +@doset "aqua" From e5209de7ff752fc56ef74f54d6a5cd5da5bc1d0e Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Fri, 2 Aug 2024 17:08:41 +0200 Subject: [PATCH 02/23] Update test/Project.toml --- test/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index a00a13b6..193d45d1 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -28,7 +28,6 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184" Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" SumTypes = "8e1ec7a9-0e02-4297-b0fe-6433085c89f2" @@ -36,5 +35,6 @@ SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a" ThreadTools = "dbf13d8f-d36e-4350-8970-f3a99faba1a8" WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b" From 0da3bed958c61a09b047b8dac3da7c23836f9112 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Fri, 2 Aug 2024 17:14:31 +0200 Subject: [PATCH 03/23] Convert most files to testitem format --- test/runtests.jl | 34 +- test/test_aqua.jl | 26 +- test/test_circuitzoo_api.jl | 24 +- test/test_circuitzoo_ent_swap.jl | 98 ++--- test/test_circuitzoo_purification.jl | 60 +-- test/test_circuitzoo_superdense.jl | 34 +- test/test_doctests.jl | 4 +- test/test_examples.jl | 12 +- test/test_jet.jl | 7 +- test/test_messagebuffer.jl | 76 ++-- test/test_noninstant_and_backgrounds_qubit.jl | 100 ++--- .../test_noninstant_and_backgrounds_qumode.jl | 22 +- test/test_observable.jl | 28 +- test/test_plotting_cairo.jl | 17 +- test/test_plotting_gl.jl | 17 +- test/test_project_traceout.jl | 56 +-- .../test_protocolzoo_entanglement_consumer.jl | 44 ++- test/test_protocolzoo_entanglement_tracker.jl | 186 +++++---- ...t_protocolzoo_entanglement_tracker_grid.jl | 359 ++++++++++-------- test/test_protocolzoo_switch.jl | 27 +- test/test_protocolzoo_throws.jl | 14 +- test/test_quantumchannel.jl | 220 +++++------ test/test_register_interface.jl | 142 +++---- test/test_registernet_interface.jl | 28 +- test/test_stateszoo_api.jl | 72 ++-- test/test_tags_and_queries.jl | 314 +++++++-------- 26 files changed, 1041 insertions(+), 980 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 452cdb77..2f041463 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,38 +2,38 @@ using QuantumSavory using TestItems using TestItemRunner -function doset(descr) +function doset(tag) if length(ARGS) == 0 return true end for a in ARGS - if occursin(lowercase(a), lowercase(descr)) + if occursin(lowercase(a), lowercase(String(tag))) return true end end - return false -end - -macro doset(descr) - quote - if doset($descr) - @safetestset $descr begin include("test_"*$descr*".jl") end + if get(ENV,"JET_TEST","")=="true" && tag == :jet + return true + end + if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" + if tag in [:plotting_gl, :plotting_cairo] + return true end + if VERSION >= v"1.9" && tag == :doctests + return true + end + end + if tag in [:examples, :aqua] + return true end + + return false end println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREADS = $(Sys.CPU_THREADS)`...") -@run_package_tests filter=ti->doset(ti.name) - if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" using Pkg Pkg.add("GLMakie") end -@doset "examples" -get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" && @doset "plotting_cairo" -get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" && @doset "plotting_gl" -get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" && VERSION >= v"1.9" && @doset "doctests" -get(ENV,"JET_TEST","")=="true" && @doset "jet" -@doset "aqua" +@run_package_tests filter=ti->any([doset(tag) for tag in ti.tags]) diff --git a/test/test_aqua.jl b/test/test_aqua.jl index e873294c..f0dc98a3 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -1,18 +1,18 @@ -using Aqua -using QuantumSavory +@testitem "Aqua" tags=[:aqua] begin + using Aqua -if get(ENV,"JET_TEST","")=="true" -# JET generates new methods with ambiguities -else + if get(ENV,"JET_TEST","")=="true" + # JET generates new methods with ambiguities + else -@test Test.detect_ambiguities(QuantumSavory) == Tuple{Method, Method}[] + @test Test.detect_ambiguities(QuantumSavory) == Tuple{Method, Method}[] -Aqua.test_all(QuantumSavory, - ambiguities=(QuantumSavory; recursive=false), - piracies=(; treat_as_own=[QuantumSavory.Symbolic]), - stale_deps=(; ignore=[:NetworkLayout]) # needed by package extension but not a condition of its loading -) + Aqua.test_all(QuantumSavory, + ambiguities=(QuantumSavory; recursive=false), + piracies=(; treat_as_own=[QuantumSavory.Symbolic]), + stale_deps=(; ignore=[:NetworkLayout]) # needed by package extension but not a condition of its loading + ) -@test length(Aqua.Piracy.hunt(QuantumSavory)) == 6 + @test length(Aqua.Piracy.hunt(QuantumSavory)) == 6 -end \ No newline at end of file +end diff --git a/test/test_circuitzoo_api.jl b/test/test_circuitzoo_api.jl index ff993421..407453bf 100644 --- a/test/test_circuitzoo_api.jl +++ b/test/test_circuitzoo_api.jl @@ -1,15 +1,15 @@ -using QuantumSavory -using QuantumSavory.CircuitZoo -using Test -using QuantumSavory.CircuitZoo: AbstractCircuit, inputqubits -using InteractiveUtils +@testitem "Circuit Zoo API" tags=[:circuitzoo_api] begin + using QuantumSavory.CircuitZoo + using QuantumSavory.CircuitZoo: AbstractCircuit, inputqubits + using InteractiveUtils -for T in subtypes(AbstractCircuit) - circ = T() - ms = methods(circ) - @test length(ms) == 1 # this can be relaxed one day, but for now it can check we are not doing weird stuff - m = first(ms) - if hasmethod(inputqubits, Tuple{T}) # TODO should all of them have this method? - @test m.isva || inputqubits(circ) == m.nargs-1 + for T in subtypes(AbstractCircuit) + circ = T() + ms = methods(circ) + @test length(ms) == 1 # this can be relaxed one day, but for now it can check we are not doing weird stuff + m = first(ms) + if hasmethod(inputqubits, Tuple{T}) # TODO should all of them have this method? + @test m.isva || inputqubits(circ) == m.nargs-1 + end end end diff --git a/test/test_circuitzoo_ent_swap.jl b/test/test_circuitzoo_ent_swap.jl index 26b165c7..58b45042 100644 --- a/test/test_circuitzoo_ent_swap.jl +++ b/test/test_circuitzoo_ent_swap.jl @@ -1,57 +1,57 @@ -using QuantumSavory -using QuantumSavory.CircuitZoo -using Test -using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap +@testitem "Circuit Zoo Entanglement Swap" tags=[:circuitzoo_ent_swap] begin + using QuantumSavory.CircuitZoo + using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap -const perfect_pair_stab = StabilizerState("XX ZZ") -const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) + const perfect_pair_stab = StabilizerState("XX ZZ") + const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) -for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 - net = RegisterNet([Register(1), Register(2), Register(1)]) - initialize!((net[1][1], net[2][1]), pair) - initialize!((net[3][1], net[2][2]), pair) - EntanglementSwap()(net[2][1], net[1][1], net[2][2], net[3][1]) - @test !isassigned(net[2][1]) && !isassigned(net[2][2]) - @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 -end - -for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 - net = RegisterNet([Register(1), Register(2), Register(1)]) - initialize!((net[1][1], net[2][1]), pair) - initialize!((net[3][1], net[2][2]), pair) - mx, mz = LocalEntanglementSwap()(net[2][1], net[2][2]) - mx == 2 && apply!(net[1][1], Z) - mz == 2 && apply!(net[3][1], X) - @test !isassigned(net[2][1]) && !isassigned(net[2][2]) - @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 -end - -for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 - net = RegisterNet([Register(2) for i in 1:n]) - for i in 1:n-1 - initialize!((net[i][1], net[i+1][2]), pair) + for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 + net = RegisterNet([Register(1), Register(2), Register(1)]) + initialize!((net[1][1], net[2][1]), pair) + initialize!((net[3][1], net[2][2]), pair) + EntanglementSwap()(net[2][1], net[1][1], net[2][2], net[3][1]) + @test !isassigned(net[2][1]) && !isassigned(net[2][2]) + @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 end - for i in 2:n-1 - EntanglementSwap()(net[i][2], net[1][1], net[i][1], net[i+1][2]) + + for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 + net = RegisterNet([Register(1), Register(2), Register(1)]) + initialize!((net[1][1], net[2][1]), pair) + initialize!((net[3][1], net[2][2]), pair) + mx, mz = LocalEntanglementSwap()(net[2][1], net[2][2]) + mx == 2 && apply!(net[1][1], Z) + mz == 2 && apply!(net[3][1], X) + @test !isassigned(net[2][1]) && !isassigned(net[2][2]) + @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 end - @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) - @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 -end -for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 - net = RegisterNet([Register(2) for i in 1:n]) - for i in 1:n-1 - initialize!((net[i][1], net[i+1][2]), pair) + for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 + net = RegisterNet([Register(2) for i in 1:n]) + for i in 1:n-1 + initialize!((net[i][1], net[i+1][2]), pair) + end + for i in 2:n-1 + EntanglementSwap()(net[i][2], net[1][1], net[i][1], net[i+1][2]) + end + @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) + @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 end - for i in 2:n-1 - mx, mz = LocalEntanglementSwap()(net[i][2], net[i][1]) - mx == 2 && apply!(net[1][1], Z) - mz == 2 && apply!(net[i+1][2], X) + + for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 + net = RegisterNet([Register(2) for i in 1:n]) + for i in 1:n-1 + initialize!((net[i][1], net[i+1][2]), pair) + end + for i in 2:n-1 + mx, mz = LocalEntanglementSwap()(net[i][2], net[i][1]) + mx == 2 && apply!(net[1][1], Z) + mz == 2 && apply!(net[i+1][2], X) + end + @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) + @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 end - @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) - @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 end diff --git a/test/test_circuitzoo_purification.jl b/test/test_circuitzoo_purification.jl index c283a910..f11e58f6 100644 --- a/test/test_circuitzoo_purification.jl +++ b/test/test_circuitzoo_purification.jl @@ -1,42 +1,42 @@ -using QuantumSavory -using QuantumSavory.CircuitZoo -using Test -using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient +@testitem "Circuit Zoo Purification" tags=[:circuitzoo_purification] begin + using QuantumSavory.CircuitZoo + using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient -const bell = StabilizerState("XX ZZ") -# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, -# however converting to stabilizer state for Clifford simulations -# is not implemented (and can not be done efficiently). + const bell = StabilizerState("XX ZZ") + # or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, + # however converting to stabilizer state for Clifford simulations + # is not implemented (and can not be done efficiently). -# QOptics repr -const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) -const perfect_pair_dm = SProjector(perfect_pair) -const mixed_dm = MixedState(perfect_pair_dm) -noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper + # QOptics repr + const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) + const perfect_pair_dm = SProjector(perfect_pair) + const mixed_dm = MixedState(perfect_pair_dm) + noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper -# Qclifford repr -const stab_perfect_pair = StabilizerState("XX ZZ") -const stab_perfect_pair_dm = SProjector(stab_perfect_pair) -const stab_mixed_dm = MixedState(stab_perfect_pair_dm) -stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm + # Qclifford repr + const stab_perfect_pair = StabilizerState("XX ZZ") + const stab_perfect_pair_dm = SProjector(stab_perfect_pair) + const stab_mixed_dm = MixedState(stab_perfect_pair_dm) + stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm -@test_throws ArgumentError Purify2to1(:lalala) -@test_throws ArgumentError Purify3to1(:lalala, :X) -@test_throws ArgumentError Purify2to1Node(:lalala) -@test_throws ArgumentError Purify3to1Node(:X, :lalala) -@test_throws ArgumentError StringentHead(:lalala) -@test_throws ArgumentError StringentBody(:lalala) +@testset "throws" begin + @test_throws ArgumentError Purify2to1(:lalala) + @test_throws ArgumentError Purify3to1(:lalala, :X) + @test_throws ArgumentError Purify2to1Node(:lalala) + @test_throws ArgumentError Purify3to1Node(:X, :lalala) + @test_throws ArgumentError StringentHead(:lalala) + @test_throws ArgumentError StringentBody(:lalala) -r = Register(30) -for i in 1:30 - initialize!(r[i], X1) + r = Register(30) + for i in 1:30 + initialize!(r[i], X1) + end + @test_throws ArgumentError PurifyExpedient()(r[1], r[2], r[3:2:21]...) + @test_throws ArgumentError PurifyStringent()(r[1], r[2], r[3:2:21]...) end -@test_throws ArgumentError PurifyExpedient()(r[1], r[2], r[3:2:21]...) -@test_throws ArgumentError PurifyStringent()(r[1], r[2], r[3:2:21]...) - @testset "2to1" begin for rep in [QuantumOpticsRepr, CliffordRepr] diff --git a/test/test_circuitzoo_superdense.jl b/test/test_circuitzoo_superdense.jl index 7f79bcab..13e0d3df 100644 --- a/test/test_circuitzoo_superdense.jl +++ b/test/test_circuitzoo_superdense.jl @@ -1,24 +1,24 @@ -using QuantumSavory -using QuantumSavory.CircuitZoo: SDEncode, SDDecode -using Test +@testitem "Circuit Zoo Super Dense" tags=[:circuitzoo_superdense] begin + using QuantumSavory.CircuitZoo: SDEncode, SDDecode -for i in 1:8 - ## Set up an entangled bell pair - ra = Register(1) - rb = Register(1) + for i in 1:8 + ## Set up an entangled bell pair + ra = Register(1) + rb = Register(1) - initialize!(ra[1], Z1) - initialize!(rb[1], Z1) + initialize!(ra[1], Z1) + initialize!(rb[1], Z1) - apply!(ra[1], H) - apply!((ra[1], rb[1]), CNOT) + apply!(ra[1], H) + apply!((ra[1], rb[1]), CNOT) - # Random 2 bit classical message - message = Tuple(rand(0:1, 2)) + # Random 2 bit classical message + message = Tuple(rand(0:1, 2)) - # Use the circuits to encode and decode the message - SDEncode()(ra[1], message) - rec = SDDecode()(ra[1], rb[1]) + # Use the circuits to encode and decode the message + SDEncode()(ra[1], message) + rec = SDDecode()(ra[1], rb[1]) - @test message == rec + @test message == rec + end end diff --git a/test/test_doctests.jl b/test/test_doctests.jl index 3f1ee2f3..497db386 100644 --- a/test/test_doctests.jl +++ b/test/test_doctests.jl @@ -1,9 +1,7 @@ -using Test using Documenter -using QuantumSavory function doctests() - @testset "Doctests" begin + @testitem "Doc tests" tags=[:doctests] begin DocMeta.setdocmeta!(QuantumSavory, :DocTestSetup, :(using QuantumSavory; using QuantumSavory.CircuitZoo; using QuantumSavory.ProtocolZoo; using QuantumSavory.StatesZoo; using Graphs); recursive=true) doctest(QuantumSavory; #fix=true diff --git a/test/test_examples.jl b/test/test_examples.jl index d504af10..ce550a4f 100644 --- a/test/test_examples.jl +++ b/test/test_examples.jl @@ -1,17 +1,17 @@ -@safetestset "colorcentermodularcluster" begin +@testitem "Examples - colorcentermodularcluster" tags=[:examples] begin include("../examples/colorcentermodularcluster/1_time_to_connected.jl") if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" include("../examples/colorcentermodularcluster/2_real_time_visualization.jl") end end -@safetestset "congestionchain" begin +@testitem "Examples - congestionchain" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" include("../examples/congestionchain/1_visualization.jl") end end -@safetestset "firstgenrepeater" begin +@testitem "Examples - firstgenrepeater" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" include("../examples/firstgenrepeater/1_entangler_example.jl") include("../examples/firstgenrepeater/2_swapper_example.jl") @@ -23,14 +23,14 @@ end include("../examples/firstgenrepeater/6.1_compare_formalisms_noplot.jl") end -@safetestset "firstgenrepeater_v2" begin +@testitem "Examples - firstgenrepeater_v2" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" include("../examples/firstgenrepeater_v2/1_entangler_example.jl") include("../examples/firstgenrepeater_v2/2_swapper_example.jl") end end -@safetestset "simpleswitch" begin +@testitem "Examples - simpleswitch" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" # TODO-MATCHING due to the dependence on BlossomV.jl this has trouble installing. See https://github.com/JuliaGraphs/GraphsMatching.jl/issues/14 #include("../examples/simpleswitch/1_interactive_visualization.jl") @@ -47,4 +47,4 @@ end if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" import GLMakie GLMakie.closeall() # to avoid errors when running headless -end \ No newline at end of file +end diff --git a/test/test_jet.jl b/test/test_jet.jl index 80f17f4c..5096375e 100644 --- a/test/test_jet.jl +++ b/test/test_jet.jl @@ -1,6 +1,6 @@ -using Test -using QuantumSavory, JET -using DiffEqBase, Graphs, JumpProcesses, Makie, ResumableFunctions, ConcurrentSim, QuantumOptics, QuantumOpticsBase, QuantumClifford, Symbolics, WignerSymbols, GraphsMatching, JuMP, SumTypes +@testitem "JET" tags=[:jet] begin + using JET + using DiffEqBase, Graphs, JumpProcesses, Makie, ResumableFunctions, ConcurrentSim, QuantumOptics, QuantumOpticsBase, QuantumClifford, Symbolics, WignerSymbols rep = report_package("QuantumSavory"; ignored_modules=( @@ -26,3 +26,4 @@ rep = report_package("QuantumSavory"; @test length(JET.get_reports(rep)) <= 33 @test_broken length(JET.get_reports(rep)) == 0 +end diff --git a/test/test_messagebuffer.jl b/test/test_messagebuffer.jl index b46dd5d2..4680ab9f 100644 --- a/test/test_messagebuffer.jl +++ b/test/test_messagebuffer.jl @@ -1,44 +1,44 @@ -using QuantumSavory -using QuantumSavory: tag_types -using QuantumSavory.ProtocolZoo -using ResumableFunctions, ConcurrentSim -using Test +@testitem "Message Buffer" tags=[:messagebuffer] begin + using QuantumSavory: tag_types + using QuantumSavory.ProtocolZoo + using ResumableFunctions, ConcurrentSim -net = RegisterNet([Register(3), Register(2), Register(3)]) -env = get_time_tracker(net); -@resumable function receive_tags(env) - while true - mb = messagebuffer(net, 2) - @yield wait(mb) - msg = querydelete!(mb, :second_tag, ❓, ❓) - if isnothing(msg) - # println("nothing") - else - #println("$(msg.tag) received from node $(msg.src)") + net = RegisterNet([Register(3), Register(2), Register(3)]) + env = get_time_tracker(net); + @resumable function receive_tags(env) + while true + mb = messagebuffer(net, 2) + @yield wait(mb) + msg = querydelete!(mb, :second_tag, ❓, ❓) + if isnothing(msg) + # println("nothing") + else + #println("$(msg.tag) received from node $(msg.src)") + end end end -end -@resumable function send_tags(env) - @yield timeout(env, 1.0) - put!(channel(net, 1=>2), Tag(:my_tag)) - @yield timeout(env, 2.0) - put!(channel(net, 3=>2), Tag(:second_tag, 123, 456)) -end -@process send_tags(env); -@process receive_tags(env); -run(env, 10) + @resumable function send_tags(env) + @yield timeout(env, 1.0) + put!(channel(net, 1=>2), Tag(:my_tag)) + @yield timeout(env, 2.0) + put!(channel(net, 3=>2), Tag(:second_tag, 123, 456)) + end + @process send_tags(env); + @process receive_tags(env); + run(env, 10) -@test query(messagebuffer(net, 2), :second_tag, ❓, ❓) === nothing -@test query(messagebuffer(net, 2), :my_tag).tag == Tag(:my_tag) + @test query(messagebuffer(net, 2), :second_tag, ❓, ❓) === nothing + @test query(messagebuffer(net, 2), :my_tag).tag == Tag(:my_tag) -## + ## -net = RegisterNet([Register(4), Register(4)]) -sim = get_time_tracker(net) -proc1 = put!(channel(net, 2=>1), SwitchRequest(2,3)) -proc2 = put!(channel(net, 2=>1), Tag(SwitchRequest(2,3))) -proc3 = put!(messagebuffer(net[1]), Tag(SwitchRequest(2,3))) -proc4 = put!(messagebuffer(net[1]), SwitchRequest(2,3)) -run(sim, 10) -@test QuantumSavory.peektags(messagebuffer(net,1)) == [Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3))] -@test_throws "does not support `tag!`" tag!(messagebuffer(net, 1), EntanglementCounterpart, 1, 10) + net = RegisterNet([Register(4), Register(4)]) + sim = get_time_tracker(net) + proc1 = put!(channel(net, 2=>1), SwitchRequest(2,3)) + proc2 = put!(channel(net, 2=>1), Tag(SwitchRequest(2,3))) + proc3 = put!(messagebuffer(net[1]), Tag(SwitchRequest(2,3))) + proc4 = put!(messagebuffer(net[1]), SwitchRequest(2,3)) + run(sim, 10) + @test QuantumSavory.peektags(messagebuffer(net,1)) == [Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3))] + @test_throws "does not support `tag!`" tag!(messagebuffer(net, 1), EntanglementCounterpart, 1, 10) +end diff --git a/test/test_noninstant_and_backgrounds_qubit.jl b/test/test_noninstant_and_backgrounds_qubit.jl index 6c38b620..94bfdf08 100644 --- a/test/test_noninstant_and_backgrounds_qubit.jl +++ b/test/test_noninstant_and_backgrounds_qubit.jl @@ -1,56 +1,56 @@ -using Test -using QuantumSavory -using QuantumSavory: NonInstantGate +@testitem "Noninstant and Backgrounds Qubit" tags=[:noninstant_and_backgrounds_qubit] begin + using QuantumSavory: NonInstantGate -## -# Time of application and gate durations -reg = Register([Qubit(),Qubit()]) -initialize!(reg[1]) -initialize!(reg[2]) -uptotime!(reg[1],0.2) -uptotime!(reg[1],0.2) -@test_throws ErrorException uptotime!(reg[1],0.1) -apply!(reg[1], H; time=0.3) -apply!(reg[1], NonInstantGate(H,0.1); time=0.4) -apply!([reg[1],reg[2]], NonInstantGate(CNOT, 0.1)) -@test_throws ErrorException uptotime!(reg[1],0.55) -@test_throws ErrorException apply!(reg[1], H; time=0.55) - -## -# Kraus vs Lindblad -function kraus_lindblad_test(background,initstate) - reg = Register([Qubit(),Qubit()],[background, background]) - initialize!(reg[1], initstate) - initialize!(reg[2], initstate) + ## + # Time of application and gate durations + reg = Register([Qubit(),Qubit()]) + initialize!(reg[1]) + initialize!(reg[2]) + uptotime!(reg[1],0.2) uptotime!(reg[1],0.2) - uptotime!(reg[2],0.1) - uptotime!(reg[2],0.2) - # Test that Kraus weights are calculated correctly - @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] + @test_throws ErrorException uptotime!(reg[1],0.1) + apply!(reg[1], H; time=0.3) + apply!(reg[1], NonInstantGate(H,0.1); time=0.4) + apply!([reg[1],reg[2]], NonInstantGate(CNOT, 0.1)) + @test_throws ErrorException uptotime!(reg[1],0.55) + @test_throws ErrorException apply!(reg[1], H; time=0.55) - regb = Register([Qubit(),Qubit()],[background, background]) - initialize!(regb[1], initstate) - initialize!(regb[2], initstate) - subsystemcompose(regb[1],regb[2]) - uptotime!(regb[1],0.2) - uptotime!(regb[2],0.1) - uptotime!(regb[2],0.2) - @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] + ## + # Kraus vs Lindblad + function kraus_lindblad_test(background,initstate) + reg = Register([Qubit(),Qubit()],[background, background]) + initialize!(reg[1], initstate) + initialize!(reg[2], initstate) + uptotime!(reg[1],0.2) + uptotime!(reg[2],0.1) + uptotime!(reg[2],0.2) + # Test that Kraus weights are calculated correctly + @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] - apply!(reg[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) - uptotime!(reg[2],0.4) - @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] + regb = Register([Qubit(),Qubit()],[background, background]) + initialize!(regb[1], initstate) + initialize!(regb[2], initstate) + subsystemcompose(regb[1],regb[2]) + uptotime!(regb[1],0.2) + uptotime!(regb[2],0.1) + uptotime!(regb[2],0.2) + @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] - apply!(regb[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) - uptotime!(regb[2],0.4) - @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] -end + apply!(reg[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) + uptotime!(reg[2],0.4) + @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] -kraus_lindblad_test(T1Decay(1.0),Z1) -kraus_lindblad_test(T1Decay(1.0),Z2) -kraus_lindblad_test(T1Decay(1.0),X1) -kraus_lindblad_test(T1Decay(1.0),X2) -kraus_lindblad_test(T2Dephasing(1.0),Z1) -kraus_lindblad_test(T2Dephasing(1.0),Z2) -kraus_lindblad_test(T2Dephasing(1.0),X1) -kraus_lindblad_test(T2Dephasing(1.0),X2) + apply!(regb[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) + uptotime!(regb[2],0.4) + @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] + end + + kraus_lindblad_test(T1Decay(1.0),Z1) + kraus_lindblad_test(T1Decay(1.0),Z2) + kraus_lindblad_test(T1Decay(1.0),X1) + kraus_lindblad_test(T1Decay(1.0),X2) + kraus_lindblad_test(T2Dephasing(1.0),Z1) + kraus_lindblad_test(T2Dephasing(1.0),Z2) + kraus_lindblad_test(T2Dephasing(1.0),X1) + kraus_lindblad_test(T2Dephasing(1.0),X2) +end diff --git a/test/test_noninstant_and_backgrounds_qumode.jl b/test/test_noninstant_and_backgrounds_qumode.jl index feea6b5a..99b2c120 100644 --- a/test/test_noninstant_and_backgrounds_qumode.jl +++ b/test/test_noninstant_and_backgrounds_qumode.jl @@ -1,12 +1,12 @@ -using Test -using QuantumSavory +@testitem "Noninstant and Backgrounds Qumode" tags=[:noninstant_and_backgrounds_qumode] begin -## -# Time of application and gate durations -reg = Register([Qumode(),Qubit(),Qumode()],[AmplitudeDamping(1.0),nothing,nothing]) -initialize!(reg[1],F1) -initialize!(reg[2]) -initialize!(reg[3],F1) -uptotime!(reg[1],0.2) -uptotime!(reg[1],0.2) -@test_throws ErrorException uptotime!(reg[1],0.1) + ## + # Time of application and gate durations + reg = Register([Qumode(),Qubit(),Qumode()],[AmplitudeDamping(1.0),nothing,nothing]) + initialize!(reg[1],F1) + initialize!(reg[2]) + initialize!(reg[3],F1) + uptotime!(reg[1],0.2) + uptotime!(reg[1],0.2) + @test_throws ErrorException uptotime!(reg[1],0.1) +end diff --git a/test/test_observable.jl b/test/test_observable.jl index 393c0d2b..4a783e0d 100644 --- a/test/test_observable.jl +++ b/test/test_observable.jl @@ -1,17 +1,17 @@ -using Test -using QuantumSavory +@testitem "Observable" tags=[:observable] begin -const bell = StabilizerState("XX ZZ") -# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, -# however converting to stabilizer state for Clifford simulations -# is not implemented (and can not be done efficiently). + const bell = StabilizerState("XX ZZ") + # or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, + # however converting to stabilizer state for Clifford simulations + # is not implemented (and can not be done efficiently). -for rep in [QuantumOpticsRepr(), CliffordRepr()] - a = Register(2,rep) - initialize!(a[1:2], bell) - @test observable(a[1:2], SProjector(bell)) ≈ 1.0 - @test observable(a[1:2], σˣ⊗σˣ) ≈ 1.0 - apply!(a[1], σʸ) - @test observable(a[1:2], SProjector(bell)) ≈ 0.0 - @test observable(a[1:2], σˣ⊗σˣ) ≈ -1.0 + for rep in [QuantumOpticsRepr(), CliffordRepr()] + a = Register(2,rep) + initialize!(a[1:2], bell) + @test observable(a[1:2], SProjector(bell)) ≈ 1.0 + @test observable(a[1:2], σˣ⊗σˣ) ≈ 1.0 + apply!(a[1], σʸ) + @test observable(a[1:2], SProjector(bell)) ≈ 0.0 + @test observable(a[1:2], σˣ⊗σˣ) ≈ -1.0 + end end diff --git a/test/test_plotting_cairo.jl b/test/test_plotting_cairo.jl index cb038064..6bd74ecb 100644 --- a/test/test_plotting_cairo.jl +++ b/test/test_plotting_cairo.jl @@ -1,10 +1,11 @@ -using Test -using CairoMakie -CairoMakie.activate!() +@testitem "Plotting Cairo" tags=[:plotting_cairo] begin + using CairoMakie + CairoMakie.activate!() -@testset "register coordinates" begin - include("test_plotting_1_regcoords.jl") -end -@testset "arguments and observables and tags" begin - include("test_plotting_2_tags_observables.jl") + @testset "register coordinates" begin + include("test_plotting_1_regcoords.jl") + end + @testset "arguments and observables and tags" begin + include("test_plotting_2_tags_observables.jl") + end end diff --git a/test/test_plotting_gl.jl b/test/test_plotting_gl.jl index b1683348..ea4fcfe8 100644 --- a/test/test_plotting_gl.jl +++ b/test/test_plotting_gl.jl @@ -1,12 +1,13 @@ -using Test -using GLMakie -GLMakie.activate!() +@testitem "Plotting GL" tags=[:plotting_gl] begin + using GLMakie + GLMakie.activate!() -@testset "register coordinates" begin - include("test_plotting_1_regcoords.jl") -end -@testset "arguments and observables and tags" begin - include("test_plotting_2_tags_observables.jl") + @testset "register coordinates" begin + include("test_plotting_1_regcoords.jl") + end + @testset "arguments and observables and tags" begin + include("test_plotting_2_tags_observables.jl") + end end using QuantumSavory diff --git a/test/test_project_traceout.jl b/test/test_project_traceout.jl index 2d361221..223dae36 100644 --- a/test/test_project_traceout.jl +++ b/test/test_project_traceout.jl @@ -1,33 +1,33 @@ -using Test -using QuantumSavory +@testitem "Project Traceout" tags=[:project_traceout] begin -const bell = StabilizerState("XX ZZ") -# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, -# however converting to stabilizer state for Clifford simulations -# is not implemented (and can not be done efficiently). + const bell = StabilizerState("XX ZZ") + # or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, + # however converting to stabilizer state for Clifford simulations + # is not implemented (and can not be done efficiently). -for rep in [QuantumOpticsRepr(), CliffordRepr()] - a = Register(2,rep) - initialize!(a[1:2], bell) - m1 = project_traceout!(a[1], σʸ) - m2 = project_traceout!(a[2], σʸ) - @test m1!=m2 + for rep in [QuantumOpticsRepr(), CliffordRepr()] + a = Register(2,rep) + initialize!(a[1:2], bell) + m1 = project_traceout!(a[1], σʸ) + m2 = project_traceout!(a[2], σʸ) + @test m1!=m2 - a = Register(4,rep) - @test_throws "Attempting to initialize a set of registers with a state that does not have the correct number of subsystems." initialize!(a[1:2], bell⊗bell) - initialize!(a[1:4], bell⊗bell) - m1 = project_traceout!(a[1], σʸ) - m2 = project_traceout!(a[2], σʸ) - m3 = project_traceout!(a[3], σʸ) - m4 = project_traceout!(a[4], σʸ) - @test m1!=m2 - @test m3!=m4 + a = Register(4,rep) + @test_throws "Attempting to initialize a set of registers with a state that does not have the correct number of subsystems." initialize!(a[1:2], bell⊗bell) + initialize!(a[1:4], bell⊗bell) + m1 = project_traceout!(a[1], σʸ) + m2 = project_traceout!(a[2], σʸ) + m3 = project_traceout!(a[3], σʸ) + m4 = project_traceout!(a[4], σʸ) + @test m1!=m2 + @test m3!=m4 - a = Register(2,rep) - initialize!(a[1], X1) - @test project_traceout!(a[1], σˣ) == 1 -end + a = Register(2,rep) + initialize!(a[1], X1) + @test project_traceout!(a[1], σˣ) == 1 + end -r = Register(1) -initialize!(r[1], Z) -@test_throws "State not normalized. Could be due to passing wrong state to `initialize!`" project_traceout!(r[1], (L0, L1)) + r = Register(1) + initialize!(r[1], Z) + @test_throws "State not normalized. Could be due to passing wrong state to `initialize!`" project_traceout!(r[1], (L0, L1)) +end diff --git a/test/test_protocolzoo_entanglement_consumer.jl b/test/test_protocolzoo_entanglement_consumer.jl index bc3878f4..7cb2ade7 100644 --- a/test/test_protocolzoo_entanglement_consumer.jl +++ b/test/test_protocolzoo_entanglement_consumer.jl @@ -1,8 +1,7 @@ -using QuantumSavory -using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer -using Graphs -using ConcurrentSim -using Test +@testitem "ProtocolZoo Entanglement Consumer" tags=[:protocolzoo_entanglement_consumer] begin + using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer + using Graphs + using ConcurrentSim if isinteractive() using Logging @@ -22,15 +21,10 @@ for n in 3:30 @process eprot() end - for v in 2:n-1 - sprot = SwapperProt(sim, net, v; nodeL = <(v), nodeH = >(v), chooseL = argmin, chooseH = argmax, rounds = -1) - @process sprot() - end - for v in vertices(net) - etracker = EntanglementTracker(sim, net, v) - @process etracker() - end + for n in 3:30 + net = RegisterNet([Register(10) for j in 1:n]) + sim = get_time_tracker(net) econ = EntanglementConsumer(sim, net, 1, n; period=1.0) @process econ() @@ -43,4 +37,28 @@ for n in 3:30 @test econ.log[i][3] ≈ 1.0 end + for v in 2:n-1 + sprot = SwapperProt(sim, net, v; nodeL = <(v), nodeH = >(v), chooseL = argmin, chooseH = argmax, rounds = -1) + @process sprot() + end + + for v in vertices(net) + etracker = EntanglementTracker(sim, net, v) + @process etracker() + end + + econ = EntanglementConsumer(sim, net, 1, n; period=1.0) + @process econ() + + run(sim, 100) + + + for i in 1:length(econ.log) + if !isnothing(econ.log[i][2]) + @test econ.log[i][2] ≈ 1.0 + @test econ.log[i][3] ≈ 1.0 + end + end + + end end diff --git a/test/test_protocolzoo_entanglement_tracker.jl b/test/test_protocolzoo_entanglement_tracker.jl index 6656d35a..602232ac 100644 --- a/test/test_protocolzoo_entanglement_tracker.jl +++ b/test/test_protocolzoo_entanglement_tracker.jl @@ -1,114 +1,112 @@ -using Revise -using QuantumSavory -using ResumableFunctions -using ConcurrentSim -using QuantumSavory.ProtocolZoo -using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ -using Graphs -using Test - -if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") -end - -## - -# without an entanglement tracker - -for i in 1:10 - - net = RegisterNet([Register(3), Register(4), Register(2), Register(3)]) - sim = get_time_tracker(net) +@testitem "ProtocolZoo Entanglement Tracker" tags=[:protocolzoo_entanglement_tracker] begin + using Revise + using ResumableFunctions + using ConcurrentSim + using QuantumSavory.ProtocolZoo + using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ + using Graphs + + if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") + end + ## - entangler1 = EntanglerProt(sim, net, 1, 2; rounds=1) - @process entangler1() - run(sim, 20) + # without an entanglement tracker - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + for i in 1:10 - entangler2 = EntanglerProt(sim, net, 2, 3; rounds=1) - @process entangler2() - run(sim, 40) - entangler3 = EntanglerProt(sim, net, 4, 3; rounds=1) - @process entangler3() - run(sim, 60) + net = RegisterNet([Register(3), Register(4), Register(2), Register(3)]) + sim = get_time_tracker(net) - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] - @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] - @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] - @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + entangler1 = EntanglerProt(sim, net, 1, 2; rounds=1) + @process entangler1() + run(sim, 20) + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] - swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), chooseL = argmin, chooseH = argmax, rounds = 1) - swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), chooseL = argmin, chooseH = argmax, rounds = 1) - @process swapper2() - @process swapper3() - run(sim, 80) + entangler2 = EntanglerProt(sim, net, 2, 3; rounds=1) + @process entangler2() + run(sim, 40) + entangler3 = EntanglerProt(sim, net, 4, 3; rounds=1) + @process entangler3() + run(sim, 60) - # In the absence of an entanglement tracker the tags will not all be updated - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] - @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] - @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementHistory, 2, 2, 4, 1, 2), Tag(EntanglementHistory, 4, 1, 2, 2, 1)] - @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] + @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] + @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] - @test isassigned(net[1][1]) && isassigned(net[4][1]) - @test !isassigned(net[2][1]) && !isassigned(net[3][1]) - @test !isassigned(net[2][2]) && !isassigned(net[3][2]) + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false -end + swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), chooseL = argmin, chooseH = argmax, rounds = 1) + swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), chooseL = argmin, chooseH = argmax, rounds = 1) + @process swapper2() + @process swapper3() + run(sim, 80) -## - -using Revise -using QuantumSavory -using ResumableFunctions -using ConcurrentSim -using QuantumSavory.ProtocolZoo -using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ -using Graphs -using Test -using Random - -if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Warn; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") -end + # In the absence of an entanglement tracker the tags will not all be updated + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] + @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementHistory, 2, 2, 4, 1, 2), Tag(EntanglementHistory, 4, 1, 2, 2, 1)] + @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] -## + @test isassigned(net[1][1]) && isassigned(net[4][1]) + @test !isassigned(net[2][1]) && !isassigned(net[3][1]) + @test !isassigned(net[2][2]) && !isassigned(net[3][2]) -# same but this time with an entanglement tracker + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false -for i in 1:30, n in 2:30 - net = RegisterNet([Register(j+3) for j in 1:n]) - sim = get_time_tracker(net) - for j in vertices(net) - tracker = EntanglementTracker(sim, net, j) - @process tracker() end - for e in edges(net) - eprot = EntanglerProt(sim, net, e.src, e.dst; rounds=1, randomize=true) - @process eprot() + + ## + + using Revise + using ResumableFunctions + using ConcurrentSim + using QuantumSavory.ProtocolZoo + using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ + using Graphs + using Random + + if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Warn; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") end - for j in 2:n-1 - swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) - @process swapper() + + ## + + # same but this time with an entanglement tracker + + for i in 1:30, n in 2:30 + net = RegisterNet([Register(j+3) for j in 1:n]) + sim = get_time_tracker(net) + for j in vertices(net) + tracker = EntanglementTracker(sim, net, j) + @process tracker() + end + for e in edges(net) + eprot = EntanglerProt(sim, net, e.src, e.dst; rounds=1, randomize=true) + @process eprot() + end + for j in 2:n-1 + swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) + @process swapper() + end + run(sim, 200) + + q1 = query(net[1], EntanglementCounterpart, n, ❓) + q2 = query(net[n], EntanglementCounterpart, 1, ❓) + @test q1.tag[2] == n + @test q2.tag[2] == 1 + @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 + @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 end - run(sim, 200) - - q1 = query(net[1], EntanglementCounterpart, n, ❓) - q2 = query(net[n], EntanglementCounterpart, 1, ❓) - @test q1.tag[2] == n - @test q2.tag[2] == 1 - @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 - @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 end diff --git a/test/test_protocolzoo_entanglement_tracker_grid.jl b/test/test_protocolzoo_entanglement_tracker_grid.jl index 9fbee78d..b3d1f16c 100644 --- a/test/test_protocolzoo_entanglement_tracker_grid.jl +++ b/test/test_protocolzoo_entanglement_tracker_grid.jl @@ -1,187 +1,234 @@ -using Revise -using QuantumSavory -using ResumableFunctions -using ConcurrentSim -using QuantumSavory.ProtocolZoo -using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ -using Graphs -using Test - -if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") -end +@testitem "ProtocolZoo Entanglement Tracker Grid" tags=[:protocolzoo_entanglement_tracker_grid] begin + using Revise + using ResumableFunctions + using ConcurrentSim + using QuantumSavory.ProtocolZoo + using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ + using Graphs + + if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") + end -## + ## -# This set of tests ensures that the combination of entanglement genererator, tracker, and swapper works on what is basically a 1D chain of nodes that happen to be otherwise located in a grid. -# This set of tests DOES NOT test anything related to 2D grid structure of a network. -# It is little more than a copy of `test_entanglement_tracker` but with more complicated predicates for choosing who to swap in swapper protocol. + # This set of tests ensures that the combination of entanglement genererator, tracker, and swapper works on what is basically a 1D chain of nodes that happen to be otherwise located in a grid. + # This set of tests DOES NOT test anything related to 2D grid structure of a network. + # It is little more than a copy of `test_entanglement_tracker` but with more complicated predicates for choosing who to swap in swapper protocol. -# Custom Predicates + # Custom Predicates -#Choose any nodes that have a positive manhattan distance for "low nodes" and any nodes that have a negative manhattan distance for the "high nodes" case -function check_nodes(net, c_node, node; low=true) - n = Int(sqrt(size(net.graph)[1])) # grid size - c_x = c_node%n == 0 ? c_node ÷ n : (c_node ÷ n) + 1 - c_y = c_node - n*(c_x-1) - x = node%n == 0 ? node ÷ n : (node ÷ n) + 1 - y = node - n*(x-1) - return low ? (c_x - x) >= 0 && (c_y - y) >= 0 : (c_x - x) <= 0 && (c_y - y) <= 0 -end + #Choose any nodes that have a positive manhattan distance for "low nodes" and any nodes that have a negative manhattan distance for the "high nodes" case + function check_nodes(net, c_node, node; low=true) + n = Int(sqrt(size(net.graph)[1])) # grid size + c_x = c_node%n == 0 ? c_node ÷ n : (c_node ÷ n) + 1 + c_y = c_node - n*(c_x-1) + x = node%n == 0 ? node ÷ n : (node ÷ n) + 1 + y = node - n*(x-1) + return low ? (c_x - x) >= 0 && (c_y - y) >= 0 : (c_x - x) <= 0 && (c_y - y) <= 0 + end -# predicate for picking the furthest node -function distance(n, a, b) - x1 = a%n == 0 ? a ÷ n : (a ÷ n) + 1 - x2 = b%n == 0 ? b ÷ n : (b ÷ n) + 1 - y1 = a - n*(x1-1) - y2 = b - n*(x2-1) + # predicate for picking the furthest node + function distance(n, a, b) + x1 = a%n == 0 ? a ÷ n : (a ÷ n) + 1 + x2 = b%n == 0 ? b ÷ n : (b ÷ n) + 1 + y1 = a - n*(x1-1) + y2 = b - n*(x2-1) - return x1 - x2 + y1 - y2 -end + return x1 - x2 + y1 - y2 + end -# filter for picking the furthest node -function choose_node(net, node, arr; low=true) - grid_size = Int(sqrt(size(net.graph)[1])) - return low ? argmax((distance.(grid_size, node, arr))) : argmin((distance.(grid_size, node, arr))) -end + # filter for picking the furthest node + function choose_node(net, node, arr; low=true) + grid_size = Int(sqrt(size(net.graph)[1])) + return low ? argmax((distance.(grid_size, node, arr))) : argmin((distance.(grid_size, node, arr))) + end -## + ## + + # Here we run a bunch of low-level correctness tests for EntanglementProt and SwapperProt + # but we do not run a complete simulation that includes EntanglementTracker. + # Some arbitrary possible 1D chains embedded in the 2D grid + paths = [ + [2, 3, 4, 8, 12], + [2, 6, 7, 11, 15], + [5, 9, 13, 14, 15], + [2, 6, 10, 14, 15], + [5, 6, 7, 8, 12], + [5, 6, 10, 11, 12], + [2, 3, 7, 11, 12] + ] # for 4x4 grid setup + for path in paths + graph = grid([4, 4]) + + net = RegisterNet(graph, [Register(3) for i in 1:16]) + sim = get_time_tracker(net) + + + entangler1 = EntanglerProt(sim, net, 1, path[1]; rounds=1) + @process entangler1() + run(sim, 20) + + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + + + # For no particular reason we are starting the entangler protocols at different times + # and we run them for only one round + entangler2 = EntanglerProt(sim, net, path[1], path[2]; rounds=1) + @process entangler2() + run(sim, 40) + entangler3 = EntanglerProt(sim, net, path[2], path[3]; rounds=1) + @process entangler3() + run(sim, 60) + entangler4 = EntanglerProt(sim, net, path[3], path[4]; rounds=1) + @process entangler4() + run(sim, 80) + entangler5 = EntanglerProt(sim, net, path[4], path[5];rounds=1) + @process entangler5() + run(sim, 100) + entangler6 = EntanglerProt(sim, net, path[5], 16; rounds=1) + @process entangler6() + run(sim, 120) + + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] + @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementCounterpart, path[1], 2), Tag(EntanglementCounterpart, path[3], 1)] + @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] + @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementCounterpart, path[3], 2), Tag(EntanglementCounterpart, path[5], 1)] + @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementCounterpart, path[4], 2), Tag(EntanglementCounterpart, 16, 1)] + @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + + for i in 1:5 + l = x->check_nodes(net, path[i], x) + h = x->check_nodes(net, path[i], x; low=false) + cL = arr->choose_node(net, path[i], arr) + cH = arr->choose_node(net, path[i], arr; low=false) + swapper = SwapperProt(sim, net, path[i]; nodeL=l, nodeH=h, chooseL=cL, chooseH=cH, rounds=1) + @process swapper() + end + run(sim, 200) + + # In the absence of an entanglement tracker the tags will not all be updated + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] + @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] + @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementHistory, path[2], 2, path[4], 1, 2), Tag(EntanglementHistory, path[4], 1, path[2], 2, 1)] + @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementHistory, path[3], 2, path[5], 1, 2), Tag(EntanglementHistory, path[5], 1, path[3], 2, 1)] + @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementHistory, path[4], 2, 16, 1, 2), Tag(EntanglementHistory, 16, 1, path[4], 2, 1)] + @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] + + @test isassigned(net[1][1]) && isassigned(net[16][1]) + @test !isassigned(net[path[1]][1]) && !isassigned(net[path[2]][1]) + @test !isassigned(net[path[1]][2]) && !isassigned(net[path[2]][2]) + @test !isassigned(net[path[3]][1]) && !isassigned(net[path[4]][1]) + @test !isassigned(net[path[3]][2]) && !isassigned(net[path[4]][2]) + @test !isassigned(net[path[5]][1]) && !isassigned(net[path[5]][2]) + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + end -# Here we run a bunch of low-level correctness tests for EntanglementProt and SwapperProt -# but we do not run a complete simulation that includes EntanglementTracker. -# Some arbitrary possible 1D chains embedded in the 2D grid -paths = [ - [2, 3, 4, 8, 12], - [2, 6, 7, 11, 15], - [5, 9, 13, 14, 15], - [2, 6, 10, 14, 15], - [5, 6, 7, 8, 12], - [5, 6, 10, 11, 12], - [2, 3, 7, 11, 12] -] # for 4x4 grid setup -for path in paths - graph = grid([4, 4]) - - net = RegisterNet(graph, [Register(3) for i in 1:16]) - sim = get_time_tracker(net) + ## + # Finally, we run the complete simulation, with EntanglerProt, SwapperProt, and EntanglementTracker, + # and we actually use a 2D grid of nodes. + # In these tests, we still use only a finite number of rounds. - entangler1 = EntanglerProt(sim, net, 1, path[1]; rounds=1) - @process entangler1() - run(sim, 20) + # For this one, we have a square grid of nodes, and we add diagonal channels to the grid. + for n in 4:10 + graph = grid([n,n]) - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + for i in 1:(n^2 - n + 1) # add diagonal channels + if !iszero(i%n) # no diagonal channel from last node in a row + add_edge!(graph, i, i + n + 1) + end + end + net = RegisterNet(graph, [Register(8) for i in 1:n^2]) - # For no particular reason we are starting the entangler protocols at different times - # and we run them for only one round - entangler2 = EntanglerProt(sim, net, path[1], path[2]; rounds=1) - @process entangler2() - run(sim, 40) - entangler3 = EntanglerProt(sim, net, path[2], path[3]; rounds=1) - @process entangler3() - run(sim, 60) - entangler4 = EntanglerProt(sim, net, path[3], path[4]; rounds=1) - @process entangler4() - run(sim, 80) - entangler5 = EntanglerProt(sim, net, path[4], path[5];rounds=1) - @process entangler5() - run(sim, 100) - entangler6 = EntanglerProt(sim, net, path[5], 16; rounds=1) - @process entangler6() - run(sim, 120) - - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] - @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] - @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementCounterpart, path[1], 2), Tag(EntanglementCounterpart, path[3], 1)] - @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] - @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementCounterpart, path[3], 2), Tag(EntanglementCounterpart, path[5], 1)] - @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementCounterpart, path[4], 2), Tag(EntanglementCounterpart, 16, 1)] - @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] - - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - - for i in 1:5 - l = x->check_nodes(net, path[i], x) - h = x->check_nodes(net, path[i], x; low=false) - cL = arr->choose_node(net, path[i], arr) - cH = arr->choose_node(net, path[i], arr; low=false) - swapper = SwapperProt(sim, net, path[i]; nodeL=l, nodeH=h, chooseL=cL, chooseH=cH, rounds=1) - @process swapper() + sim = get_time_tracker(net) + + for (;src, dst) in edges(net) + eprot = EntanglerProt(sim, net, src, dst; rounds=5, randomize=true) # A single round doesn't always get the ends entangled, when number of nodes is high + @process eprot() + end + + for i in 2:(size(graph)[1] - 1) + l(x) = check_nodes(net, i, x) + h(x) = check_nodes(net, i, x; low=false) + cL(arr) = choose_node(net, i, arr) + cH(arr) = choose_node(net, i, arr; low=false) + swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds = 5) # A single round doesn't always get the ends entangled, when number of nodes is high + @process swapper() + end + + for v in vertices(net) + tracker = EntanglementTracker(sim, net, v) + @process tracker() + end + + run(sim, 200) + + # has a small chance of failing due to the randomization of the entanglement protocols + q1 = query(net[1], EntanglementCounterpart, size(graph)[1], ❓) + q2 = query(net[size(graph)[1]], EntanglementCounterpart, 1, q1.slot.idx) + + @test q1.tag[2] == size(graph)[1] + @test q2.tag[2] == 1 + @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1.0 + @test observable((q1.slot, q2.slot), X⊗X) ≈ 1.0 end - run(sim, 200) - - # In the absence of an entanglement tracker the tags will not all be updated - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] - @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] - @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] - @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementHistory, path[2], 2, path[4], 1, 2), Tag(EntanglementHistory, path[4], 1, path[2], 2, 1)] - @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementHistory, path[3], 2, path[5], 1, 2), Tag(EntanglementHistory, path[5], 1, path[3], 2, 1)] - @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementHistory, path[4], 2, 16, 1, 2), Tag(EntanglementHistory, 16, 1, path[4], 2, 1)] - @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] - - @test isassigned(net[1][1]) && isassigned(net[16][1]) - @test !isassigned(net[path[1]][1]) && !isassigned(net[path[2]][1]) - @test !isassigned(net[path[1]][2]) && !isassigned(net[path[2]][2]) - @test !isassigned(net[path[3]][1]) && !isassigned(net[path[4]][1]) - @test !isassigned(net[path[3]][2]) && !isassigned(net[path[4]][2]) - @test !isassigned(net[path[5]][1]) && !isassigned(net[path[5]][2]) - - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false -end -## + # and here we test for a simple 2d rectangular grid + for n in 4:10 + graph = grid([n,n]) -# Finally, we run the complete simulation, with EntanglerProt, SwapperProt, and EntanglementTracker, -# and we actually use a 2D grid of nodes. -# In these tests, we still use only a finite number of rounds. + net = RegisterNet(graph, [Register(8) for i in 1:n^2]) -# For this one, we have a square grid of nodes, and we add diagonal channels to the grid. -for n in 4:10 - graph = grid([n,n]) + sim = get_time_tracker(net) - for i in 1:(n^2 - n + 1) # add diagonal channels - if !iszero(i%n) # no diagonal channel from last node in a row - add_edge!(graph, i, i + n + 1) + for (;src, dst) in edges(net) + eprot = EntanglerProt(sim, net, src, dst; rounds=5, randomize=true) # A single round doesn't always get the ends entangled, when number of nodes is high + @process eprot() end - end - net = RegisterNet(graph, [Register(8) for i in 1:n^2]) + for i in 2:(size(graph)[1] - 1) + l(x) = check_nodes(net, i, x) + h(x) = check_nodes(net, i, x; low=false) + cL(arr) = choose_node(net, i, arr) + cH(arr) = choose_node(net, i, arr; low=false) + swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds = 5) # A single round doesn't always get the ends entangled, when number of nodes is high + @process swapper() + end - sim = get_time_tracker(net) + for v in vertices(net) + tracker = EntanglementTracker(sim, net, v) + @process tracker() + end - for (;src, dst) in edges(net) - eprot = EntanglerProt(sim, net, src, dst; rounds=5, randomize=true) # A single round doesn't always get the ends entangled, when number of nodes is high - @process eprot() - end + run(sim, 100) - for i in 2:(size(graph)[1] - 1) - l(x) = check_nodes(net, i, x) - h(x) = check_nodes(net, i, x; low=false) - cL(arr) = choose_node(net, i, arr) - cH(arr) = choose_node(net, i, arr; low=false) - swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds = 5) # A single round doesn't always get the ends entangled, when number of nodes is high - @process swapper() - end + q1 = query(net[1], EntanglementCounterpart, size(graph)[1], ❓) + q2 = query(net[size(graph)[1]], EntanglementCounterpart, 1, q1.slot.idx) - for v in vertices(net) - tracker = EntanglementTracker(sim, net, v) - @process tracker() + @test q1.tag[2] == size(graph)[1] + @test q2.tag[2] == 1 + @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1.0 + @test observable((q1.slot, q2.slot), X⊗X) ≈ 1.0 end - run(sim, 200) - # has a small chance of failing due to the randomization of the entanglement protocols - q1 = query(net[1], EntanglementCounterpart, size(graph)[1], ❓) - q2 = query(net[size(graph)[1]], EntanglementCounterpart, 1, q1.slot.idx) + ## - @test q1.tag[2] == size(graph)[1] - @test q2.tag[2] == 1 - @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1.0 - @test observable((q1.slot, q2.slot), X⊗X) ≈ 1.0 + # More tests of 2D rectangular grids with the full stack of protocols, + # but also now with an unlimited number of rounds and an entanglement consumer. + + #TODO + @test_broken false end # and here we test for a simple 2d rectangular grid @@ -273,4 +320,4 @@ run(sim, 400) for i in 1:length(consumer.log) @test consumer.log[i][2] ≈ 1.0 @test consumer.log[i][3] ≈ 1.0 -end \ No newline at end of file +end diff --git a/test/test_protocolzoo_switch.jl b/test/test_protocolzoo_switch.jl index 1970e50f..bd3b64fd 100644 --- a/test/test_protocolzoo_switch.jl +++ b/test/test_protocolzoo_switch.jl @@ -1,19 +1,17 @@ -using Revise -using QuantumSavory -using ResumableFunctions -using ConcurrentSim -using QuantumSavory.ProtocolZoo -using Graphs -using Test +@testitem "ProtocolZoo Switch - SimpleSwitchDiscreteProt" tags=[:protocolzoo_switch] begin + using Revise + using ResumableFunctions + using ConcurrentSim + using QuantumSavory.ProtocolZoo + using Graphs -if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") -end + if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") + end -@testset "SimpleSwitchDiscreteProt" begin n = 5 # number of clients m = n-2 # memory slots in switch graph = star_graph(n+1) # index 1 corresponds to the switch @@ -44,3 +42,4 @@ end #@test abs(observable([res.slot, net[3][res.tag[3]]], X⊗X)) ≈ 1.0 # we are not running an EntanglementTracker so Pauli corrections are not applied #@test abs(observable([res.slot, net[3][res.tag[3]]], Z⊗Z)) ≈ 1.0 # we are not running an EntanglementTracker so Pauli corrections are not applied end +end diff --git a/test/test_protocolzoo_throws.jl b/test/test_protocolzoo_throws.jl index c017ab24..c6dd4a42 100644 --- a/test/test_protocolzoo_throws.jl +++ b/test/test_protocolzoo_throws.jl @@ -1,12 +1,10 @@ -using Revise -using QuantumSavory -using ResumableFunctions -using ConcurrentSim -using QuantumSavory.ProtocolZoo -using Graphs -using Test +@testitem "ProtocolZoo Throws - SimpleSwitchDiscreteProt" tags=[:protocolzoo_throws] begin + using Revise + using ResumableFunctions + using ConcurrentSim + using QuantumSavory.ProtocolZoo + using Graphs -@testset "SimpleSwitchDiscreteProt" begin net = RegisterNet([Register(2), Register(3), Register(4)]) @test_throws "`clientnodes` must be unique" SimpleSwitchDiscreteProt(net, 1, [2,2,3], fill(0.5, 3)) @test_throws "`clientnodes` must be directly connected to the `switchnode`" SimpleSwitchDiscreteProt(net, 1, 2:4, fill(0.5, 3)) diff --git a/test/test_quantumchannel.jl b/test/test_quantumchannel.jl index 84df3895..16a3c979 100644 --- a/test/test_quantumchannel.jl +++ b/test/test_quantumchannel.jl @@ -1,111 +1,111 @@ -using QuantumSavory -using ResumableFunctions -using ConcurrentSim -using Test - -bell = (Z1⊗Z1 + Z2⊗Z2)/sqrt(2.0) - -## Manually construct a QuantumChannel and test a simple put/take - -sim = Simulation() -regA = Register(1) -regB = Register(2) -initialize!((regA[1], regB[2]), bell) -# Delay queue for quantum channel -queue = DelayQueue{Register}(sim, 10.0) -qc = QuantumChannel(queue) - -@resumable function alice_node(env, qc) - put!(qc, regA[1]) -end - -@resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) +@testitem "Quantum Channel" tags=[:quantumchannel] begin + using ResumableFunctions + using ConcurrentSim + + bell = (Z1⊗Z1 + Z2⊗Z2)/sqrt(2.0) + + ## Manually construct a QuantumChannel and test a simple put/take + + sim = Simulation() + regA = Register(1) + regB = Register(2) + initialize!((regA[1], regB[2]), bell) + # Delay queue for quantum channel + queue = DelayQueue{Register}(sim, 10.0) + qc = QuantumChannel(queue) + + @resumable function alice_node(env, qc) + put!(qc, regA[1]) + end + + @resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) + end + + @process alice_node(sim, qc) + @process bob_node(sim, qc) + + run(sim) + + # the above code puts both the qubits of the state in the same register + sref = regB.staterefs[1] + @test sref.registers[1] == sref.registers[2] + @test !isassigned(regA, 1) + + ## Test with the second constructor + + regA = Register(1) + regB = Register(2) + initialize!((regA[1], regB[2]), bell) + sim = Simulation() + qc = QuantumChannel(sim, 10.0) + @resumable function alice_node(env, qc) + put!(qc, regA[1]) + end + @resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) + end + @process alice_node(sim, qc) + @process bob_node(sim, qc) + run(sim) + sref = regB.staterefs[1] + @test sref.registers[1] == sref.registers[2] + @test !isassigned(regA, 1) + + ## Test with T1Decay + + regA = Register(1) + regB = Register(2) + initialize!((regA[1], regB[2]), bell) + sim = Simulation() + qc = QuantumChannel(sim, 10.0, T1Decay(0.1)) + @resumable function alice_node(env, qc) + put!(qc, regA[1]) + end + @resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) + end + @process alice_node(sim, qc) + @process bob_node(sim, qc) + run(sim) + + # compare against a stationary qubit experiencing the same T1 decay + reg = Register([Qubit(), Qubit()], [T1Decay(0.1), nothing]) + initialize!(reg[1:2], bell) + uptotime!(reg[1], 10.0) + + @test observable(reg[1:2], projector(bell)) ≈ observable(regB[1:2], projector(bell)) + + ## Test with T2Dephasing + + regA = Register(2) + regB = Register(2) + initialize!((regA[1], regB[2]), bell) + sim = Simulation() + qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) + @resumable function alice_node(env, qc) + put!(qc, regA[1]) + end + @resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) + end + @process alice_node(sim, qc) + @process bob_node(sim, qc) + run(sim) + + reg = Register([Qubit(), Qubit()], [T2Dephasing(0.1), nothing]) + initialize!(reg[1:2], bell) + uptotime!(reg[1], 10.0) + + @test observable(reg[1:2], projector(bell)) == observable(regB[1:2], projector(bell)) + + ## Test for slot availability + + sim = Simulation() + qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) + regC = Register(1) + initialize!(regC[1], Z1) + put!(qc, regC[1]) + take!(qc, regB[1]) + @test_throws "A take! operation is being performed on a QuantumChannel in order to swap the state into a Register, but the target register slot is not empty (it is already initialized)." run(sim) end - -@process alice_node(sim, qc) -@process bob_node(sim, qc) - -run(sim) - -# the above code puts both the qubits of the state in the same register -sref = regB.staterefs[1] -@test sref.registers[1] == sref.registers[2] -@test !isassigned(regA, 1) - -## Test with the second constructor - -regA = Register(1) -regB = Register(2) -initialize!((regA[1], regB[2]), bell) -sim = Simulation() -qc = QuantumChannel(sim, 10.0) -@resumable function alice_node(env, qc) - put!(qc, regA[1]) -end -@resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) -end -@process alice_node(sim, qc) -@process bob_node(sim, qc) -run(sim) -sref = regB.staterefs[1] -@test sref.registers[1] == sref.registers[2] -@test !isassigned(regA, 1) - -## Test with T1Decay - -regA = Register(1) -regB = Register(2) -initialize!((regA[1], regB[2]), bell) -sim = Simulation() -qc = QuantumChannel(sim, 10.0, T1Decay(0.1)) -@resumable function alice_node(env, qc) - put!(qc, regA[1]) -end -@resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) -end -@process alice_node(sim, qc) -@process bob_node(sim, qc) -run(sim) - -# compare against a stationary qubit experiencing the same T1 decay -reg = Register([Qubit(), Qubit()], [T1Decay(0.1), nothing]) -initialize!(reg[1:2], bell) -uptotime!(reg[1], 10.0) - -@test observable(reg[1:2], projector(bell)) ≈ observable(regB[1:2], projector(bell)) - -## Test with T2Dephasing - -regA = Register(2) -regB = Register(2) -initialize!((regA[1], regB[2]), bell) -sim = Simulation() -qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) -@resumable function alice_node(env, qc) - put!(qc, regA[1]) -end -@resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) -end -@process alice_node(sim, qc) -@process bob_node(sim, qc) -run(sim) - -reg = Register([Qubit(), Qubit()], [T2Dephasing(0.1), nothing]) -initialize!(reg[1:2], bell) -uptotime!(reg[1], 10.0) - -@test observable(reg[1:2], projector(bell)) == observable(regB[1:2], projector(bell)) - -## Test for slot availability - -sim = Simulation() -qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) -regC = Register(1) -initialize!(regC[1], Z1) -put!(qc, regC[1]) -take!(qc, regB[1]) -@test_throws "A take! operation is being performed on a QuantumChannel in order to swap the state into a Register, but the target register slot is not empty (it is already initialized)." run(sim) diff --git a/test/test_register_interface.jl b/test/test_register_interface.jl index c2650292..b1d2f2e1 100644 --- a/test/test_register_interface.jl +++ b/test/test_register_interface.jl @@ -1,79 +1,79 @@ -using Test -using QuantumSavory -using QuantumOpticsBase: Ket, Operator -using QuantumClifford: MixedDestabilizer +@testitem "Register Interface" tags=[:register_interface] begin + using QuantumOpticsBase: Ket, Operator + using QuantumClifford: MixedDestabilizer -## -# no backgrounds -traits = [Qubit(), Qubit(), Qubit()] -reg1 = Register(traits) -qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] -reg2 = Register(traits, qc_repr) -qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] -reg3 = Register(traits, qmc_repr) -net = RegisterNet([reg1, reg2, reg3]) + ## + # no backgrounds + traits = [Qubit(), Qubit(), Qubit()] + reg1 = Register(traits) + qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] + reg2 = Register(traits, qc_repr) + qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] + reg3 = Register(traits, qmc_repr) + net = RegisterNet([reg1, reg2, reg3]) -i = 1 -initialize!(net[i,2]) -@test nsubsystems(net[i].staterefs[2]) == 1 -initialize!(net[i,3],X1) -@test nsubsystems(net[i].staterefs[2]) == 1 -apply!([net[i,2], net[i,3]], CNOT) -@test net[i].staterefs[2].state[] isa Ket -@test nsubsystems(net[i].staterefs[2]) == 2 + i = 1 + initialize!(net[i,2]) + @test nsubsystems(net[i].staterefs[2]) == 1 + initialize!(net[i,3],X1) + @test nsubsystems(net[i].staterefs[2]) == 1 + apply!([net[i,2], net[i,3]], CNOT) + @test net[i].staterefs[2].state[] isa Ket + @test nsubsystems(net[i].staterefs[2]) == 2 -i = 2 -initialize!(net[i,2]) -@test nsubsystems(net[i].staterefs[2]) == 1 -initialize!(net[i,3],X1) -@test nsubsystems(net[i].staterefs[2]) == 1 -apply!([net[i,2], net[i,3]], CNOT) -@test net[i].staterefs[2].state[] isa MixedDestabilizer -@test nsubsystems(net[i].staterefs[2]) == 2 + i = 2 + initialize!(net[i,2]) + @test nsubsystems(net[i].staterefs[2]) == 1 + initialize!(net[i,3],X1) + @test nsubsystems(net[i].staterefs[2]) == 1 + apply!([net[i,2], net[i,3]], CNOT) + @test net[i].staterefs[2].state[] isa MixedDestabilizer + @test nsubsystems(net[i].staterefs[2]) == 2 -i = 3 -initialize!(net[i,2]) -@test nsubsystems(net[i].staterefs[2]) == 1 -initialize!(net[i,3],X1) -@test nsubsystems(net[i].staterefs[2]) == 1 -apply!([net[i,2], net[i,3]], CNOT) -@test net[i].staterefs[2].state[] isa Ket -@test nsubsystems(net[i].staterefs[2]) == 2 + i = 3 + initialize!(net[i,2]) + @test nsubsystems(net[i].staterefs[2]) == 1 + initialize!(net[i,3],X1) + @test nsubsystems(net[i].staterefs[2]) == 1 + apply!([net[i,2], net[i,3]], CNOT) + @test net[i].staterefs[2].state[] isa Ket + @test nsubsystems(net[i].staterefs[2]) == 2 -## -# with backgrounds -traits = [Qubit(), Qubit(), Qubit()] -backgrounds = [T2Dephasing(1.0),T2Dephasing(1.0),T2Dephasing(1.0)] -reg1 = Register(traits, backgrounds) -qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] -reg2 = Register(traits, qc_repr, backgrounds) -qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] -reg3 = Register(traits, qmc_repr, backgrounds) -net = RegisterNet([reg1, reg2, reg3]) + ## + # with backgrounds + traits = [Qubit(), Qubit(), Qubit()] + backgrounds = [T2Dephasing(1.0),T2Dephasing(1.0),T2Dephasing(1.0)] + reg1 = Register(traits, backgrounds) + qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] + reg2 = Register(traits, qc_repr, backgrounds) + qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] + reg3 = Register(traits, qmc_repr, backgrounds) + net = RegisterNet([reg1, reg2, reg3]) -i = 1 -initialize!(net[i,2], time=1.0) -@test nsubsystems(net[i].staterefs[2]) == 1 -initialize!(net[i,3],X1, time=2.0) -@test nsubsystems(net[i].staterefs[2]) == 1 -apply!([net[i,2], net[i,3]], CNOT, time=3.0) -@test net[i].staterefs[2].state[] isa Operator -@test nsubsystems(net[i].staterefs[2]) == 2 + i = 1 + initialize!(net[i,2], time=1.0) + @test nsubsystems(net[i].staterefs[2]) == 1 + initialize!(net[i,3],X1, time=2.0) + @test nsubsystems(net[i].staterefs[2]) == 1 + apply!([net[i,2], net[i,3]], CNOT, time=3.0) + @test net[i].staterefs[2].state[] isa Operator + @test nsubsystems(net[i].staterefs[2]) == 2 -i = 2 -initialize!(net[i,2], time=1.0) -@test nsubsystems(net[i].staterefs[2]) == 1 -initialize!(net[i,3],X1, time=2.0) -@test nsubsystems(net[i].staterefs[2]) == 1 -apply!([net[i,2], net[i,3]], CNOT, time=3.0) -@test net[i].staterefs[2].state[] isa MixedDestabilizer -@test nsubsystems(net[i].staterefs[2]) == 2 + i = 2 + initialize!(net[i,2], time=1.0) + @test nsubsystems(net[i].staterefs[2]) == 1 + initialize!(net[i,3],X1, time=2.0) + @test nsubsystems(net[i].staterefs[2]) == 1 + apply!([net[i,2], net[i,3]], CNOT, time=3.0) + @test net[i].staterefs[2].state[] isa MixedDestabilizer + @test nsubsystems(net[i].staterefs[2]) == 2 -i = 3 -initialize!(net[i,2], time=1.0) -@test nsubsystems(net[i].staterefs[2]) == 1 -initialize!(net[i,3],X1, time=2.0) -@test nsubsystems(net[i].staterefs[2]) == 1 -apply!([net[i,2], net[i,3]], CNOT, time=3.0) -@test_broken net[i].staterefs[2].state[] isa Ket -@test nsubsystems(net[i].staterefs[2]) == 2 + i = 3 + initialize!(net[i,2], time=1.0) + @test nsubsystems(net[i].staterefs[2]) == 1 + initialize!(net[i,3],X1, time=2.0) + @test nsubsystems(net[i].staterefs[2]) == 1 + apply!([net[i,2], net[i,3]], CNOT, time=3.0) + @test_broken net[i].staterefs[2].state[] isa Ket + @test nsubsystems(net[i].staterefs[2]) == 2 +end diff --git a/test/test_registernet_interface.jl b/test/test_registernet_interface.jl index 1104b2bf..78d7359e 100644 --- a/test/test_registernet_interface.jl +++ b/test/test_registernet_interface.jl @@ -1,19 +1,19 @@ -using Test -using Graphs -using QuantumSavory -using QuantumOpticsBase: Ket, Operator -using QuantumClifford: MixedDestabilizer +@testitem "RegisterNet Interface" tags=[:registernet_interface] begin + using Graphs + using QuantumOpticsBase: Ket, Operator + using QuantumClifford: MixedDestabilizer -## + ## -r1 = Register(3) -r2 = Register(4) -r3 = Register(5) + r1 = Register(3) + r2 = Register(4) + r3 = Register(5) -net = RegisterNet([r1, r2, r3]) + net = RegisterNet([r1, r2, r3]) -@test net[1,2] == r1[2] -@test net[2,3] == r2[3] + @test net[1,2] == r1[2] + @test net[2,3] == r2[3] -net[1,:label] = "lala" -@test net[1,:label] == "lala" + net[1,:label] = "lala" + @test net[1,:label] == "lala" +end diff --git a/test/test_stateszoo_api.jl b/test/test_stateszoo_api.jl index cc2423bd..cac472c7 100644 --- a/test/test_stateszoo_api.jl +++ b/test/test_stateszoo_api.jl @@ -1,41 +1,41 @@ -using QuantumSavory -using QuantumSavory.StatesZoo: ZALMSpinPairW, ZALMSpinPair, SingleRailMidSwapBellW, SingleRailMidSwapBell, DualRailMidSwapBellW, DualRailMidSwapBell -using QuantumOpticsBase -using Test - -zalmW = ZALMSpinPairW(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) -zalm = ZALMSpinPair(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) -srmsW = SingleRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) -srms = SingleRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) -drmsW = DualRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) -drms = DualRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) - -r_zalmW = Register(2) -initialize!(r_zalmW[1:2], zalmW) -@test ! iszero(observable(r_zalmW[1:2], Z⊗Z)) - -r_zalm = Register(2) -initialize!(r_zalm[1:2], zalm) -@test ! iszero(observable(r_zalm[1:2], Z⊗Z)) - -r_srmsW = Register(2) -initialize!(r_srmsW[1:2], srmsW) -@test ! iszero(observable(r_srmsW[1:2], Z⊗Z)) - -r_srms = Register(2) -initialize!(r_srms[1:2], srms) -@test ! iszero(observable(r_srms[1:2], Z⊗Z)) - -r_drmsW = Register(2) -initialize!(r_drmsW[1:2], drmsW) -@test ! iszero(observable(r_drmsW[1:2], Z⊗Z)) - -r_drms = Register(2) -initialize!(r_drms[1:2], drms) -@test ! iszero(observable(r_drms[1:2], Z⊗Z)) +@testitem "StatesZoo API" tags=[:stateszoo_api] begin + using QuantumSavory.StatesZoo: ZALMSpinPairW, ZALMSpinPair, SingleRailMidSwapBellW, SingleRailMidSwapBell, DualRailMidSwapBellW, DualRailMidSwapBell + using QuantumOpticsBase + + zalmW = ZALMSpinPairW(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) + zalm = ZALMSpinPair(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) + srmsW = SingleRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) + srms = SingleRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) + drmsW = DualRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) + drms = DualRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) + + r_zalmW = Register(2) + initialize!(r_zalmW[1:2], zalmW) + @test ! iszero(observable(r_zalmW[1:2], Z⊗Z)) + + r_zalm = Register(2) + initialize!(r_zalm[1:2], zalm) + @test ! iszero(observable(r_zalm[1:2], Z⊗Z)) + + r_srmsW = Register(2) + initialize!(r_srmsW[1:2], srmsW) + @test ! iszero(observable(r_srmsW[1:2], Z⊗Z)) + + r_srms = Register(2) + initialize!(r_srms[1:2], srms) + @test ! iszero(observable(r_srms[1:2], Z⊗Z)) + + r_drmsW = Register(2) + initialize!(r_drmsW[1:2], drmsW) + @test ! iszero(observable(r_drmsW[1:2], Z⊗Z)) + + r_drms = Register(2) + initialize!(r_drms[1:2], drms) + @test ! iszero(observable(r_drms[1:2], Z⊗Z)) @test tr(zalm) ≈ tr(express(zalm)) @test tr(srms) ≈ tr(express(srms)) -@test tr(drms) ≈ tr(express(drms)) \ No newline at end of file +@test tr(drms) ≈ tr(express(drms)) +end diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index 4d64d8c1..74f11fb9 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -1,158 +1,158 @@ -using QuantumSavory -using QuantumSavory: tag_types -using QuantumSavory.ProtocolZoo: EntanglementCounterpart -using Test - -function strip_id(query_result) - return (;slot=query_result.slot, tag=query_result.tag) -end - -strip_id(::Nothing) = nothing - -function f() - -## -@test tag_types.SymbolIntInt(:symbol1, 4, 5) == Tag(:symbol1, 4, 5) - -r = Register(10) -tag!(r[1], :symbol1, 2, 3) -tag!(r[2], :symbol1, 4, 5) -tag!(r[3], :symbol1, 4, 1) -tag!(r[5], Int, 4, 5) - -@test Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3) -@test strip_id(query(r, :symbol1, 4, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) -@test strip_id(query(r, :symbol1, 4, 5)) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) -@test strip_id(query(r, :symbol1, ❓, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order -@test query(r, :symbol2, ❓, ❓) == nothing -@test strip_id(query(r, Int, 4, 5)) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) -@test query(r, Float32, 4, 5) == nothing -@test query(r, Int, 4, >(5)) == nothing -@test strip_id(query(r, Int, 4, <(6))) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) - -@test strip_id.(queryall(r, :symbol1, ❓, ❓)) == [(slot=r[3], tag=Tag(:symbol1, 4, 1)), (slot=r[2], tag=Tag(:symbol1, 4, 5)), (slot=r[1], tag=Tag(:symbol1, 2, 3))] # filo by default -@test isempty(queryall(r, :symbol2, ❓, ❓)) - -@test strip_id(query(r[2], Tag(:symbol1, 4, 5))) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) -@test strip_id.(queryall(r[2], Tag(:symbol1, 4, 5))) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] -@test strip_id(query(r[2], :symbol1, 4, 5)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) -@test strip_id.(queryall(r[2], :symbol1, 4, 5)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] - -@test strip_id(query(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) -@test strip_id.(queryall(r[2], :symbol1, 4, ❓)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] - -@test strip_id(querydelete!(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) -@test querydelete!(r[2], :symbol1, 4, ❓) === nothing -@test strip_id(querydelete!(r[3], :symbol1, 4, ❓)) == (slot=r[3], tag=Tag(:symbol1, 4, 1)) - -## -# tests for fifo and filo order queries (default is filo) -# for RegRefs - -reg = Register(5) -tag!(reg[3], EntanglementCounterpart, 1, 10) -tag!(reg[3], EntanglementCounterpart, 2, 21) -tag!(reg[3], EntanglementCounterpart, 3, 30) -tag!(reg[3], EntanglementCounterpart, 2, 22) -tag!(reg[3], EntanglementCounterpart, 1, 10) -tag!(reg[3], EntanglementCounterpart, 6, 60) -tag!(reg[3], EntanglementCounterpart, 2, 23) -tag!(reg[3], EntanglementCounterpart, 1, 10) - -@test query(reg[3], EntanglementCounterpart, 1, 11) === nothing -@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) -@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) -@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) -@test query(reg[3], EntanglementCounterpart, 1, 10; filo=true).id > query(reg[3], EntanglementCounterpart, 1, 10; filo=false).id -@test query(reg[3], EntanglementCounterpart, 2, ❓; filo=true).tag[3] == 23 -@test query(reg[3], EntanglementCounterpart, 2, ❓; filo=false).tag[3] == 21 - -@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) -@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,21)) -@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) - -@test queryall(reg, EntanglementCounterpart, 1, 11) == [] -default_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10)] -@test default_ids == sort(default_ids, rev=true) -fifo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false)] -@test fifo_ids == sort(fifo_ids) -filo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true)] -@test filo_ids == default_ids - -## -# tests for fifo and filo order queries (default is filo) -# for Register - -reg = Register(5) -for i in 2:4 - tag!(reg[i], EntanglementCounterpart, 1, 10+i) - tag!(reg[i], EntanglementCounterpart, 2, 20+i) - tag!(reg[i], EntanglementCounterpart, 3, 30+i) - tag!(reg[i], EntanglementCounterpart, 2, 120+i) - tag!(reg[i], EntanglementCounterpart, 1, 110+i) - tag!(reg[i], EntanglementCounterpart, 6, 60+i) - tag!(reg[i], EntanglementCounterpart, 2, 20+i) - tag!(reg[i], EntanglementCounterpart, 1, 310+i) +@testitem "Tags and Queries" tags=[:tags_and_queries] begin + using QuantumSavory: tag_types + using QuantumSavory.ProtocolZoo: EntanglementCounterpart + + function strip_id(query_result) + return (;slot=query_result.slot, tag=query_result.tag) + end + + strip_id(::Nothing) = nothing + + function f() + + ## + @test tag_types.SymbolIntInt(:symbol1, 4, 5) == Tag(:symbol1, 4, 5) + + r = Register(10) + tag!(r[1], :symbol1, 2, 3) + tag!(r[2], :symbol1, 4, 5) + tag!(r[3], :symbol1, 4, 1) + tag!(r[5], Int, 4, 5) + + @test Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3) + @test strip_id(query(r, :symbol1, 4, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) + @test strip_id(query(r, :symbol1, 4, 5)) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) + @test strip_id(query(r, :symbol1, ❓, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order + @test query(r, :symbol2, ❓, ❓) == nothing + @test strip_id(query(r, Int, 4, 5)) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) + @test query(r, Float32, 4, 5) == nothing + @test query(r, Int, 4, >(5)) == nothing + @test strip_id(query(r, Int, 4, <(6))) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) + + @test strip_id.(queryall(r, :symbol1, ❓, ❓)) == [(slot=r[3], tag=Tag(:symbol1, 4, 1)), (slot=r[2], tag=Tag(:symbol1, 4, 5)), (slot=r[1], tag=Tag(:symbol1, 2, 3))] # filo by default + @test isempty(queryall(r, :symbol2, ❓, ❓)) + + @test strip_id(query(r[2], Tag(:symbol1, 4, 5))) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) + @test strip_id.(queryall(r[2], Tag(:symbol1, 4, 5))) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] + @test strip_id(query(r[2], :symbol1, 4, 5)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) + @test strip_id.(queryall(r[2], :symbol1, 4, 5)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] + + @test strip_id(query(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) + @test strip_id.(queryall(r[2], :symbol1, 4, ❓)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] + + @test strip_id(querydelete!(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) + @test querydelete!(r[2], :symbol1, 4, ❓) === nothing + @test strip_id(querydelete!(r[3], :symbol1, 4, ❓)) == (slot=r[3], tag=Tag(:symbol1, 4, 1)) + + ## + # tests for fifo and filo order queries (default is filo) + # for RegRefs + + reg = Register(5) + tag!(reg[3], EntanglementCounterpart, 1, 10) + tag!(reg[3], EntanglementCounterpart, 2, 21) + tag!(reg[3], EntanglementCounterpart, 3, 30) + tag!(reg[3], EntanglementCounterpart, 2, 22) + tag!(reg[3], EntanglementCounterpart, 1, 10) + tag!(reg[3], EntanglementCounterpart, 6, 60) + tag!(reg[3], EntanglementCounterpart, 2, 23) + tag!(reg[3], EntanglementCounterpart, 1, 10) + + @test query(reg[3], EntanglementCounterpart, 1, 11) === nothing + @test strip_id(query(reg[3], EntanglementCounterpart, 1, 10)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) + @test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) + @test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) + @test query(reg[3], EntanglementCounterpart, 1, 10; filo=true).id > query(reg[3], EntanglementCounterpart, 1, 10; filo=false).id + @test query(reg[3], EntanglementCounterpart, 2, ❓; filo=true).tag[3] == 23 + @test query(reg[3], EntanglementCounterpart, 2, ❓; filo=false).tag[3] == 21 + + @test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) + @test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,21)) + @test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) + + @test queryall(reg, EntanglementCounterpart, 1, 11) == [] + default_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10)] + @test default_ids == sort(default_ids, rev=true) + fifo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false)] + @test fifo_ids == sort(fifo_ids) + filo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true)] + @test filo_ids == default_ids + + ## + # tests for fifo and filo order queries (default is filo) + # for Register + + reg = Register(5) + for i in 2:4 + tag!(reg[i], EntanglementCounterpart, 1, 10+i) + tag!(reg[i], EntanglementCounterpart, 2, 20+i) + tag!(reg[i], EntanglementCounterpart, 3, 30+i) + tag!(reg[i], EntanglementCounterpart, 2, 120+i) + tag!(reg[i], EntanglementCounterpart, 1, 110+i) + tag!(reg[i], EntanglementCounterpart, 6, 60+i) + tag!(reg[i], EntanglementCounterpart, 2, 20+i) + tag!(reg[i], EntanglementCounterpart, 1, 310+i) + end + + @test query(reg, EntanglementCounterpart, 1, 10) === nothing + @test strip_id(query(reg, EntanglementCounterpart, 1, 12)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) + @test query(reg, EntanglementCounterpart, 1, 12) == query(reg, EntanglementCounterpart, ==(1), ==(12)) + @test query(reg, Tag(EntanglementCounterpart, 1, 10)) === nothing + @test strip_id(query(reg, Tag(EntanglementCounterpart, 1, 12))) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) + @test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) + @test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=true)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) + @test query(reg, EntanglementCounterpart, 1, 12; filo=false) == query(reg, EntanglementCounterpart, 1, ==(12); filo=false) + @test query(reg, EntanglementCounterpart, 1, 12; filo=true) == query(reg, EntanglementCounterpart, 1, ==(12); filo=true) + @test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) + @test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=true)) == (slot = reg[4], tag = Tag(EntanglementCounterpart,1,314)) + + default_res = queryall(reg, EntanglementCounterpart, 1, ❓) + default_res_id = [r.id for r in default_res] + @test strip_id.(default_res) == reverse([(slot = reg[i], tag = Tag(EntanglementCounterpart, 1, j+i)) for i in 2:4 for j in (10,110,310)]) + @test default_res_id == reverse(sort(default_res_id)) + filo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) + filo_res_id = [r.id for r in filo_res] + @test strip_id.(filo_res) == strip_id.(default_res) + @test filo_res_id == default_res_id + fifo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) + fifo_res_id = [r.id for r in fifo_res] + @test strip_id.(fifo_res) == reverse(strip_id.(default_res)) + @test fifo_res_id == sort(fifo_res_id) + + @test strip_id.(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] + @test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] + @test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) + @test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] + @test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) + + reg = Register(4) + tag!(reg[1], EntanglementCounterpart, 4, 9) + tag!(reg[1], EntanglementCounterpart, 5, 2) + tag!(reg[1], EntanglementCounterpart, 7, 7) + tag!(reg[1], EntanglementCounterpart, 4, 9) + tag!(reg[1], EntanglementCounterpart, 2, 3) + tag!(reg[1], EntanglementCounterpart, 4, 9) + + @test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3), Tag(EntanglementCounterpart, 4, 9)] + querydelete!(reg[1], EntanglementCounterpart, 4, 9) + @test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] + querydelete!(reg[1], EntanglementCounterpart, 4, 9;filo=false) + @test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] + + ## + # untagging tests + + reg = Register(5) + id1 = tag!(reg[1], :symA, 1, 2) + id2 = tag!(reg[2], :symB, 2, 3) + id3 = tag!(reg[3], :symB, 3, 4) + id3 = tag!(reg[4], :symB, 4, 5) + @test untag!(reg[1], id1).tag == Tag(:symA, 1, 2) + @test untag!(reg, id2).tag == Tag(:symB, 2, 3) + @test_throws "Attempted to delete a nonexistent" untag!(reg, -1) + end + + f() + #using BenchmarkTools + #@benchmark f() end - -@test query(reg, EntanglementCounterpart, 1, 10) === nothing -@test strip_id(query(reg, EntanglementCounterpart, 1, 12)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, 12) == query(reg, EntanglementCounterpart, ==(1), ==(12)) -@test query(reg, Tag(EntanglementCounterpart, 1, 10)) === nothing -@test strip_id(query(reg, Tag(EntanglementCounterpart, 1, 12))) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) -@test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) -@test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=true)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, 12; filo=false) == query(reg, EntanglementCounterpart, 1, ==(12); filo=false) -@test query(reg, EntanglementCounterpart, 1, 12; filo=true) == query(reg, EntanglementCounterpart, 1, ==(12); filo=true) -@test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) -@test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=true)) == (slot = reg[4], tag = Tag(EntanglementCounterpart,1,314)) - -default_res = queryall(reg, EntanglementCounterpart, 1, ❓) -default_res_id = [r.id for r in default_res] -@test strip_id.(default_res) == reverse([(slot = reg[i], tag = Tag(EntanglementCounterpart, 1, j+i)) for i in 2:4 for j in (10,110,310)]) -@test default_res_id == reverse(sort(default_res_id)) -filo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) -filo_res_id = [r.id for r in filo_res] -@test strip_id.(filo_res) == strip_id.(default_res) -@test filo_res_id == default_res_id -fifo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) -fifo_res_id = [r.id for r in fifo_res] -@test strip_id.(fifo_res) == reverse(strip_id.(default_res)) -@test fifo_res_id == sort(fifo_res_id) - -@test strip_id.(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] -@test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] -@test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) -@test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] -@test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) - -reg = Register(4) -tag!(reg[1], EntanglementCounterpart, 4, 9) -tag!(reg[1], EntanglementCounterpart, 5, 2) -tag!(reg[1], EntanglementCounterpart, 7, 7) -tag!(reg[1], EntanglementCounterpart, 4, 9) -tag!(reg[1], EntanglementCounterpart, 2, 3) -tag!(reg[1], EntanglementCounterpart, 4, 9) - -@test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3), Tag(EntanglementCounterpart, 4, 9)] -querydelete!(reg[1], EntanglementCounterpart, 4, 9) -@test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] -querydelete!(reg[1], EntanglementCounterpart, 4, 9;filo=false) -@test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] - -## -# untagging tests - -reg = Register(5) -id1 = tag!(reg[1], :symA, 1, 2) -id2 = tag!(reg[2], :symB, 2, 3) -id3 = tag!(reg[3], :symB, 3, 4) -id3 = tag!(reg[4], :symB, 4, 5) -@test untag!(reg[1], id1).tag == Tag(:symA, 1, 2) -@test untag!(reg, id2).tag == Tag(:symB, 2, 3) -@test_throws "Attempted to delete a nonexistent" untag!(reg, -1) -end - -f() -#using BenchmarkTools -#@benchmark f() From 65bc2cef7a8ee89e1bedf7226ae504ab2728e872 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sat, 3 Aug 2024 18:39:23 +0200 Subject: [PATCH 04/23] Remove unneeded TestItems using (TestItemRunner suffices) --- test/runtests.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 2f041463..2989e4c8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,4 @@ using QuantumSavory -using TestItems using TestItemRunner function doset(tag) From 56f361686b684fed506143bfbf66f1b00feda408 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sat, 3 Aug 2024 18:39:49 +0200 Subject: [PATCH 05/23] Refactor test_circuitzoo_purification to share setup code --- test/setup_circuitzoo_purification.jl | 22 ++++++++ test/test_circuitzoo_purification.jl | 81 +++++++++++++++------------ 2 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 test/setup_circuitzoo_purification.jl diff --git a/test/setup_circuitzoo_purification.jl b/test/setup_circuitzoo_purification.jl new file mode 100644 index 00000000..eed46a42 --- /dev/null +++ b/test/setup_circuitzoo_purification.jl @@ -0,0 +1,22 @@ +using QuantumSavory.CircuitZoo +using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient + +const bell = StabilizerState("XX ZZ") +export bell; +# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, +# however converting to stabilizer state for Clifford simulations +# is not implemented (and can not be done efficiently). + + +# QOptics repr +const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) +const perfect_pair_dm = SProjector(perfect_pair) +const mixed_dm = MixedState(perfect_pair_dm) +noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper + + +# Qclifford repr +const stab_perfect_pair = StabilizerState("XX ZZ") +const stab_perfect_pair_dm = SProjector(stab_perfect_pair) +const stab_mixed_dm = MixedState(stab_perfect_pair_dm) +stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm \ No newline at end of file diff --git a/test/test_circuitzoo_purification.jl b/test/test_circuitzoo_purification.jl index f11e58f6..5cc34318 100644 --- a/test/test_circuitzoo_purification.jl +++ b/test/test_circuitzoo_purification.jl @@ -1,28 +1,7 @@ -@testitem "Circuit Zoo Purification" tags=[:circuitzoo_purification] begin +@testitem "Circuit Zoo Purification - throws" tags=[:circuitzoo_purification] begin using QuantumSavory.CircuitZoo using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient - - const bell = StabilizerState("XX ZZ") - # or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, - # however converting to stabilizer state for Clifford simulations - # is not implemented (and can not be done efficiently). - - - # QOptics repr - const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) - const perfect_pair_dm = SProjector(perfect_pair) - const mixed_dm = MixedState(perfect_pair_dm) - noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper - - - # Qclifford repr - const stab_perfect_pair = StabilizerState("XX ZZ") - const stab_perfect_pair_dm = SProjector(stab_perfect_pair) - const stab_mixed_dm = MixedState(stab_perfect_pair_dm) - stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm - -@testset "throws" begin @test_throws ArgumentError Purify2to1(:lalala) @test_throws ArgumentError Purify3to1(:lalala, :X) @test_throws ArgumentError Purify2to1Node(:lalala) @@ -38,7 +17,9 @@ @test_throws ArgumentError PurifyStringent()(r[1], r[2], r[3:2:21]...) end -@testset "2to1" begin +@testitem "Circuit Zoo Purification - 2to1" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr, CliffordRepr] for leaveout in [:X, :Y, :Z] # test that pure state gets mapped to pure state @@ -64,7 +45,9 @@ end end end -@testset "2to1 - Node" begin +@testitem "Circuit Zoo Purification - 2to1 - Node" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr, CliffordRepr] for leaveout in [:X, :Y, :Z] # test that pure state gets mapped to pure state @@ -95,7 +78,9 @@ end end end -@testset "3to1" begin +@testitem "Circuit Zoo Purification - 3to1" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr, CliffordRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -134,7 +119,9 @@ end end end -@testset "3to1 - Fidelity - QuantumOpticsRepr" begin +@testitem "Circuit Zoo Purification - 3to1 -- Fidelity - QuantumOpticsRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -154,7 +141,9 @@ end end end -@testset "3to1 - Fidelity - CliffordRepr" begin +@testitem "Circuit Zoo Purification - 3to1 -- Fidelity - CliffordRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [CliffordRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -174,7 +163,9 @@ end end -@testset "3to1 - Node" begin +@testitem "Circuit Zoo Purification - 3to1 -- Node" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr, CliffordRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -223,7 +214,9 @@ end end end -@testset "3to1 - Node - Fidelity - QuantumOpticsRepr" begin +@testitem "Circuit Zoo Purification - 3to1 -- Node - Fidelity - QuantumOpticsRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -245,7 +238,9 @@ end end end -@testset "3to1 - Node - Fidelity - CliffordRepr" begin +@testitem "Circuit Zoo Purification - 3to1 -- Node - Fidelity - CliffordRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [CliffordRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -266,7 +261,9 @@ end end end -@testset "Stringent" begin +@testitem "Circuit Zoo Purification - Stringent" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [CliffordRepr, QuantumOpticsRepr] r = Register(26, rep()) for i in 1:13 @@ -277,7 +274,9 @@ end end end -@testset "Stringent - Fidelity - QuantumOpticsRepr" begin +@testitem "Circuit Zoo Purification - Stringent - Fidelity - QuantumOpticsRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr] r = Register(26, rep()) rnd = rand() / 4 + 0.5 @@ -291,7 +290,9 @@ end end end -@testset "Stringent - Fidelity - CliffordRepr" begin +@testitem "Circuit Zoo Purification - Stringent - Fidelity - CliffordRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [CliffordRepr] r = Register(26, rep()) noisy_pair = stab_noisy_pair_func(0) @@ -304,7 +305,9 @@ end end end -@testset "Expedient" begin +@testitem "Circuit Zoo Purification - Expedient" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [CliffordRepr, QuantumOpticsRepr] r = Register(22, rep()) for i in 1:11 @@ -315,7 +318,9 @@ end end end -@testset "Expedient - Fidelity - QuantumOpticsRepr" begin +@testitem "Circuit Zoo Purification - Expedient - Fidelity - QuantumOpticsRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [QuantumOpticsRepr] r = Register(22, rep()) rnd = rand() / 4 + 0.5 @@ -329,7 +334,9 @@ end end end -@testset "Expedient - Fidelity - CliffordRepr" begin +@testitem "Circuit Zoo Purification - Expedient - Fidelity - CliffordRepr" tags=[:circuitzoo_purification] begin + include("setup_circuitzoo_purification.jl") + for rep in [CliffordRepr] r = Register(22, rep()) noisy_pair = stab_noisy_pair_func(0) @@ -340,4 +347,4 @@ end @test_broken observable(r[1:2], projector(bell)) ≈ 0.0 # This is a probabilistic test. It has a small chance of triggering end end -end +end \ No newline at end of file From e5d895ef2421dc490c9f8b9a8951064163998c55 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Tue, 6 Aug 2024 18:06:41 +0200 Subject: [PATCH 06/23] Try to fix plotting tests with GLMakie --- test/Project.toml | 1 + test/runtests.jl | 5 ----- test/test_plotting_1_regcoords.jl | 2 -- test/test_plotting_2_tags_observables.jl | 1 - test/test_plotting_cairo.jl | 1 + 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/test/Project.toml b/test/Project.toml index 193d45d1..f1b25a83 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -7,6 +7,7 @@ DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" GraphsMatching = "c3af3a8c-b79e-4b01-bf44-c718d7e0e0d6" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" diff --git a/test/runtests.jl b/test/runtests.jl index 2989e4c8..d1671316 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -30,9 +30,4 @@ end println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREADS = $(Sys.CPU_THREADS)`...") -if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" - using Pkg - Pkg.add("GLMakie") -end - @run_package_tests filter=ti->any([doset(tag) for tag in ti.tags]) diff --git a/test/test_plotting_1_regcoords.jl b/test/test_plotting_1_regcoords.jl index 528a1f04..032e823f 100644 --- a/test/test_plotting_1_regcoords.jl +++ b/test/test_plotting_1_regcoords.jl @@ -1,8 +1,6 @@ -using Test #using CairoMakie #using GLMakie using FileIO -using QuantumSavory sizes = [2,3,2,5,6,2,3] registers = Register[] diff --git a/test/test_plotting_2_tags_observables.jl b/test/test_plotting_2_tags_observables.jl index 659e9507..3abac2ab 100644 --- a/test/test_plotting_2_tags_observables.jl +++ b/test/test_plotting_2_tags_observables.jl @@ -1,4 +1,3 @@ -using QuantumSavory #using CairoMakie #using GLMakie using Graphs diff --git a/test/test_plotting_cairo.jl b/test/test_plotting_cairo.jl index 6bd74ecb..a374f82b 100644 --- a/test/test_plotting_cairo.jl +++ b/test/test_plotting_cairo.jl @@ -1,4 +1,5 @@ @testitem "Plotting Cairo" tags=[:plotting_cairo] begin + using GLMakie using CairoMakie CairoMakie.activate!() From a222013ff7189efae0679e8a1f3ba6c86cb7c123 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Tue, 6 Aug 2024 19:26:21 +0200 Subject: [PATCH 07/23] Revert addition of GLMakie to test/Project.toml. --- test/Project.toml | 1 - test/setup_plotting.jl | 2 ++ test/test_plotting_cairo.jl | 2 +- test/test_plotting_gl.jl | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 test/setup_plotting.jl diff --git a/test/Project.toml b/test/Project.toml index f1b25a83..193d45d1 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -7,7 +7,6 @@ DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" GraphsMatching = "c3af3a8c-b79e-4b01-bf44-c718d7e0e0d6" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" diff --git a/test/setup_plotting.jl b/test/setup_plotting.jl new file mode 100644 index 00000000..2414d8fa --- /dev/null +++ b/test/setup_plotting.jl @@ -0,0 +1,2 @@ +using Pkg +Pkg.add("GLMakie") diff --git a/test/test_plotting_cairo.jl b/test/test_plotting_cairo.jl index a374f82b..1e07a9e4 100644 --- a/test/test_plotting_cairo.jl +++ b/test/test_plotting_cairo.jl @@ -1,5 +1,5 @@ @testitem "Plotting Cairo" tags=[:plotting_cairo] begin - using GLMakie + include("setup_plotting.jl") using CairoMakie CairoMakie.activate!() diff --git a/test/test_plotting_gl.jl b/test/test_plotting_gl.jl index ea4fcfe8..748ab973 100644 --- a/test/test_plotting_gl.jl +++ b/test/test_plotting_gl.jl @@ -1,4 +1,5 @@ @testitem "Plotting GL" tags=[:plotting_gl] begin + include("setup_plotting.jl") using GLMakie GLMakie.activate!() From fa3fe7fd26764b4756e15678704d801d118c2aab Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Wed, 7 Aug 2024 12:31:07 +0200 Subject: [PATCH 08/23] Fix test filter logic - format more like QuantumClifford PR --- test/runtests.jl | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index d1671316..ad598b72 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,33 +1,22 @@ using QuantumSavory using TestItemRunner -function doset(tag) - if length(ARGS) == 0 - return true - end - for a in ARGS - if occursin(lowercase(a), lowercase(String(tag))) - return true - end - end - if get(ENV,"JET_TEST","")=="true" && tag == :jet - return true - end - if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" - if tag in [:plotting_gl, :plotting_cairo] - return true - end - if VERSION >= v"1.9" && tag == :doctests - return true +function testfilter(tags) + exclude = Symbol[] + # Only do the plotting tests if the ENV variable `QUANTUMSAVORY_PLOT_TEST` is set + if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")!="true" + push!(exclude, :plotting_cairo) + push!(exclude, :plotting_gl) + if VERSION >= v"1.9" + push!(exclude, :doctests) end end - if tag in [:examples, :aqua] - return true + if get(ENV,"JET_TEST","")!="true" + push!(exclude, :jet) end - - return false + return all(!in(exclude), tags) end println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREADS = $(Sys.CPU_THREADS)`...") -@run_package_tests filter=ti->any([doset(tag) for tag in ti.tags]) +@run_package_tests filter=ti->testfilter(ti.tags) \ No newline at end of file From 8bbf4ea8d9596b3405265dd1ef5eace66eac859d Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 11:24:43 +0200 Subject: [PATCH 09/23] Clean merge - and remove indentation, the diff was very difficult to inspect --- test/setup_circuitzoo_purification.jl | 22 -- test/setup_plotting.jl | 2 - test/test_aqua.jl | 23 +- test/test_circuitzoo_api.jl | 22 +- test/test_circuitzoo_ent_swap.jl | 96 ++--- test/test_circuitzoo_purification.jl | 61 +-- test/test_circuitzoo_superdense.jl | 32 +- test/test_jet.jl | 4 +- test/test_messagebuffer.jl | 72 ++-- test/test_noninstant_and_backgrounds_qubit.jl | 96 ++--- .../test_noninstant_and_backgrounds_qumode.jl | 18 +- test/test_observable.jl | 26 +- test/test_plotting_cairo.jl | 18 +- test/test_plotting_gl.jl | 14 +- test/test_project_traceout.jl | 52 +-- .../test_protocolzoo_entanglement_consumer.jl | 42 +-- test/test_protocolzoo_entanglement_tracker.jl | 182 ++++----- ...t_protocolzoo_entanglement_tracker_grid.jl | 355 ++++++++---------- test/test_quantumchannel.jl | 218 +++++------ test/test_register_interface.jl | 138 +++---- test/test_registernet_interface.jl | 24 +- test/test_stateszoo_api.jl | 66 ++-- test/test_tags_and_queries.jl | 306 +++++++-------- 23 files changed, 908 insertions(+), 981 deletions(-) delete mode 100644 test/setup_circuitzoo_purification.jl delete mode 100644 test/setup_plotting.jl diff --git a/test/setup_circuitzoo_purification.jl b/test/setup_circuitzoo_purification.jl deleted file mode 100644 index eed46a42..00000000 --- a/test/setup_circuitzoo_purification.jl +++ /dev/null @@ -1,22 +0,0 @@ -using QuantumSavory.CircuitZoo -using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient - -const bell = StabilizerState("XX ZZ") -export bell; -# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, -# however converting to stabilizer state for Clifford simulations -# is not implemented (and can not be done efficiently). - - -# QOptics repr -const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) -const perfect_pair_dm = SProjector(perfect_pair) -const mixed_dm = MixedState(perfect_pair_dm) -noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper - - -# Qclifford repr -const stab_perfect_pair = StabilizerState("XX ZZ") -const stab_perfect_pair_dm = SProjector(stab_perfect_pair) -const stab_mixed_dm = MixedState(stab_perfect_pair_dm) -stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm \ No newline at end of file diff --git a/test/setup_plotting.jl b/test/setup_plotting.jl deleted file mode 100644 index 2414d8fa..00000000 --- a/test/setup_plotting.jl +++ /dev/null @@ -1,2 +0,0 @@ -using Pkg -Pkg.add("GLMakie") diff --git a/test/test_aqua.jl b/test/test_aqua.jl index f0dc98a3..cdcd426c 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -1,18 +1,17 @@ @testitem "Aqua" tags=[:aqua] begin - using Aqua +using Aqua - if get(ENV,"JET_TEST","")=="true" - # JET generates new methods with ambiguities - else +if get(ENV,"JET_TEST","")=="true" +# JET generates new methods with ambiguities +else - @test Test.detect_ambiguities(QuantumSavory) == Tuple{Method, Method}[] +@test Test.detect_ambiguities(QuantumSavory) == Tuple{Method, Method}[] - Aqua.test_all(QuantumSavory, - ambiguities=(QuantumSavory; recursive=false), - piracies=(; treat_as_own=[QuantumSavory.Symbolic]), - stale_deps=(; ignore=[:NetworkLayout]) # needed by package extension but not a condition of its loading - ) - - @test length(Aqua.Piracy.hunt(QuantumSavory)) == 6 +Aqua.test_all(QuantumSavory, + ambiguities=(QuantumSavory; recursive=false), + piracies=(; treat_as_own=[QuantumSavory.Symbolic]), + stale_deps=(; ignore=[:NetworkLayout]) # needed by package extension but not a condition of its loading +) +@test length(Aqua.Piracy.hunt(QuantumSavory)) == 6 end diff --git a/test/test_circuitzoo_api.jl b/test/test_circuitzoo_api.jl index 407453bf..bc2d631d 100644 --- a/test/test_circuitzoo_api.jl +++ b/test/test_circuitzoo_api.jl @@ -1,15 +1,15 @@ @testitem "Circuit Zoo API" tags=[:circuitzoo_api] begin - using QuantumSavory.CircuitZoo - using QuantumSavory.CircuitZoo: AbstractCircuit, inputqubits - using InteractiveUtils +using QuantumSavory.CircuitZoo +using QuantumSavory.CircuitZoo: AbstractCircuit, inputqubits +using InteractiveUtils - for T in subtypes(AbstractCircuit) - circ = T() - ms = methods(circ) - @test length(ms) == 1 # this can be relaxed one day, but for now it can check we are not doing weird stuff - m = first(ms) - if hasmethod(inputqubits, Tuple{T}) # TODO should all of them have this method? - @test m.isva || inputqubits(circ) == m.nargs-1 - end +for T in subtypes(AbstractCircuit) + circ = T() + ms = methods(circ) + @test length(ms) == 1 # this can be relaxed one day, but for now it can check we are not doing weird stuff + m = first(ms) + if hasmethod(inputqubits, Tuple{T}) # TODO should all of them have this method? + @test m.isva || inputqubits(circ) == m.nargs-1 end end +end diff --git a/test/test_circuitzoo_ent_swap.jl b/test/test_circuitzoo_ent_swap.jl index 58b45042..b92a9e8d 100644 --- a/test/test_circuitzoo_ent_swap.jl +++ b/test/test_circuitzoo_ent_swap.jl @@ -1,57 +1,57 @@ @testitem "Circuit Zoo Entanglement Swap" tags=[:circuitzoo_ent_swap] begin - using QuantumSavory.CircuitZoo - using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap +using QuantumSavory.CircuitZoo +using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwapusing QuantumSavory - const perfect_pair_stab = StabilizerState("XX ZZ") - const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) +const perfect_pair_stab = StabilizerState("XX ZZ") +const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) - for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 - net = RegisterNet([Register(1), Register(2), Register(1)]) - initialize!((net[1][1], net[2][1]), pair) - initialize!((net[3][1], net[2][2]), pair) - EntanglementSwap()(net[2][1], net[1][1], net[2][2], net[3][1]) - @test !isassigned(net[2][1]) && !isassigned(net[2][2]) - @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 - end +for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 + net = RegisterNet([Register(1), Register(2), Register(1)]) + initialize!((net[1][1], net[2][1]), pair) + initialize!((net[3][1], net[2][2]), pair) + EntanglementSwap()(net[2][1], net[1][1], net[2][2], net[3][1]) + @test !isassigned(net[2][1]) && !isassigned(net[2][2]) + @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 +end - for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 - net = RegisterNet([Register(1), Register(2), Register(1)]) - initialize!((net[1][1], net[2][1]), pair) - initialize!((net[3][1], net[2][2]), pair) - mx, mz = LocalEntanglementSwap()(net[2][1], net[2][2]) - mx == 2 && apply!(net[1][1], Z) - mz == 2 && apply!(net[3][1], X) - @test !isassigned(net[2][1]) && !isassigned(net[2][2]) - @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 - end +for pair in (perfect_pair, perfect_pair_stab), rep in 1:10 + net = RegisterNet([Register(1), Register(2), Register(1)]) + initialize!((net[1][1], net[2][1]), pair) + initialize!((net[3][1], net[2][2]), pair) + mx, mz = LocalEntanglementSwap()(net[2][1], net[2][2]) + mx == 2 && apply!(net[1][1], Z) + mz == 2 && apply!(net[3][1], X) + @test !isassigned(net[2][1]) && !isassigned(net[2][2]) + @test observable((net[1][1], net[3][1]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[3][1]), X⊗X) ≈ 1 +end - for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 - net = RegisterNet([Register(2) for i in 1:n]) - for i in 1:n-1 - initialize!((net[i][1], net[i+1][2]), pair) - end - for i in 2:n-1 - EntanglementSwap()(net[i][2], net[1][1], net[i][1], net[i+1][2]) - end - @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) - @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 +for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 + net = RegisterNet([Register(2) for i in 1:n]) + for i in 1:n-1 + initialize!((net[i][1], net[i+1][2]), pair) end + for i in 2:n-1 + EntanglementSwap()(net[i][2], net[1][1], net[i][1], net[i+1][2]) + end + @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) + @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 +end - for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 - net = RegisterNet([Register(2) for i in 1:n]) - for i in 1:n-1 - initialize!((net[i][1], net[i+1][2]), pair) - end - for i in 2:n-1 - mx, mz = LocalEntanglementSwap()(net[i][2], net[i][1]) - mx == 2 && apply!(net[1][1], Z) - mz == 2 && apply!(net[i+1][2], X) - end - @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) - @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 - @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 +for pair in (perfect_pair, perfect_pair_stab), n in 3:10, rep in 1:10 + net = RegisterNet([Register(2) for i in 1:n]) + for i in 1:n-1 + initialize!((net[i][1], net[i+1][2]), pair) end + for i in 2:n-1 + mx, mz = LocalEntanglementSwap()(net[i][2], net[i][1]) + mx == 2 && apply!(net[1][1], Z) + mz == 2 && apply!(net[i+1][2], X) + end + @test all(!isassigned(net[i][1]) & !isassigned(net[i][2]) for i in 2:n-1) + @test observable((net[1][1], net[n][2]), Z⊗Z) ≈ 1 + @test observable((net[1][1], net[n][2]), X⊗X) ≈ 1 +end end diff --git a/test/test_circuitzoo_purification.jl b/test/test_circuitzoo_purification.jl index 5cc34318..1d4288b7 100644 --- a/test/test_circuitzoo_purification.jl +++ b/test/test_circuitzoo_purification.jl @@ -1,25 +1,44 @@ @testitem "Circuit Zoo Purification - throws" tags=[:circuitzoo_purification] begin - using QuantumSavory.CircuitZoo - using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient - - @test_throws ArgumentError Purify2to1(:lalala) - @test_throws ArgumentError Purify3to1(:lalala, :X) - @test_throws ArgumentError Purify2to1Node(:lalala) - @test_throws ArgumentError Purify3to1Node(:X, :lalala) - @test_throws ArgumentError StringentHead(:lalala) - @test_throws ArgumentError StringentBody(:lalala) - - r = Register(30) - for i in 1:30 - initialize!(r[i], X1) - end - @test_throws ArgumentError PurifyExpedient()(r[1], r[2], r[3:2:21]...) - @test_throws ArgumentError PurifyStringent()(r[1], r[2], r[3:2:21]...) +using QuantumSavory.CircuitZoo +using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient + +const bell = StabilizerState("XX ZZ") +# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, +# however converting to stabilizer state for Clifford simulations +# is not implemented (and can not be done efficiently). + + +# QOptics repr +const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) +const perfect_pair_dm = SProjector(perfect_pair) +const mixed_dm = MixedState(perfect_pair_dm) +noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper + + +# Qclifford repr +const stab_perfect_pair = StabilizerState("XX ZZ") +const stab_perfect_pair_dm = SProjector(stab_perfect_pair) +const stab_mixed_dm = MixedState(stab_perfect_pair_dm) +stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm + +@test_throws ArgumentError Purify2to1(:lalala) +@test_throws ArgumentError Purify3to1(:lalala, :X) +@test_throws ArgumentError Purify2to1Node(:lalala) +@test_throws ArgumentError Purify3to1Node(:X, :lalala) +@test_throws ArgumentError StringentHead(:lalala) +@test_throws ArgumentError StringentBody(:lalala) + +r = Register(30) +for i in 1:30 + initialize!(r[i], X1) +end +@test_throws ArgumentError PurifyExpedient()(r[1], r[2], r[3:2:21]...) +@test_throws ArgumentError PurifyStringent()(r[1], r[2], r[3:2:21]...) end @testitem "Circuit Zoo Purification - 2to1" tags=[:circuitzoo_purification] begin include("setup_circuitzoo_purification.jl") - + for rep in [QuantumOpticsRepr, CliffordRepr] for leaveout in [:X, :Y, :Z] # test that pure state gets mapped to pure state @@ -80,7 +99,7 @@ end @testitem "Circuit Zoo Purification - 3to1" tags=[:circuitzoo_purification] begin include("setup_circuitzoo_purification.jl") - + for rep in [QuantumOpticsRepr, CliffordRepr] for leaveout1 in [:X, :Y, :Z] for leaveout2 in [:X, :Y, :Z] @@ -272,9 +291,9 @@ end @test PurifyStringent()(r[1], r[2], r[3:2:25]..., r[4:2:26]...) == true @test observable(r[1:2], projector(bell)) ≈ 1.0 end -end + end -@testitem "Circuit Zoo Purification - Stringent - Fidelity - QuantumOpticsRepr" tags=[:circuitzoo_purification] begin + @testitem "Circuit Zoo Purification - Stringent - Fidelity - QuantumOpticsRepr" tags=[:circuitzoo_purification] begin include("setup_circuitzoo_purification.jl") for rep in [QuantumOpticsRepr] @@ -347,4 +366,4 @@ end @test_broken observable(r[1:2], projector(bell)) ≈ 0.0 # This is a probabilistic test. It has a small chance of triggering end end -end \ No newline at end of file +end diff --git a/test/test_circuitzoo_superdense.jl b/test/test_circuitzoo_superdense.jl index 13e0d3df..7cd8eabf 100644 --- a/test/test_circuitzoo_superdense.jl +++ b/test/test_circuitzoo_superdense.jl @@ -1,24 +1,24 @@ @testitem "Circuit Zoo Super Dense" tags=[:circuitzoo_superdense] begin - using QuantumSavory.CircuitZoo: SDEncode, SDDecode +using QuantumSavory.CircuitZoo: SDEncode, SDDecode - for i in 1:8 - ## Set up an entangled bell pair - ra = Register(1) - rb = Register(1) +for i in 1:8 + ## Set up an entangled bell pair + ra = Register(1) + rb = Register(1) - initialize!(ra[1], Z1) - initialize!(rb[1], Z1) + initialize!(ra[1], Z1) + initialize!(rb[1], Z1) - apply!(ra[1], H) - apply!((ra[1], rb[1]), CNOT) + apply!(ra[1], H) + apply!((ra[1], rb[1]), CNOT) - # Random 2 bit classical message - message = Tuple(rand(0:1, 2)) + # Random 2 bit classical message + message = Tuple(rand(0:1, 2)) - # Use the circuits to encode and decode the message - SDEncode()(ra[1], message) - rec = SDDecode()(ra[1], rb[1]) + # Use the circuits to encode and decode the message + SDEncode()(ra[1], message) + rec = SDDecode()(ra[1], rb[1]) - @test message == rec - end + @test message == rec +end end diff --git a/test/test_jet.jl b/test/test_jet.jl index 5096375e..27a0088a 100644 --- a/test/test_jet.jl +++ b/test/test_jet.jl @@ -1,6 +1,6 @@ @testitem "JET" tags=[:jet] begin - using JET - using DiffEqBase, Graphs, JumpProcesses, Makie, ResumableFunctions, ConcurrentSim, QuantumOptics, QuantumOpticsBase, QuantumClifford, Symbolics, WignerSymbols +using JET +using DiffEqBase, Graphs, JumpProcesses, Makie, ResumableFunctions, ConcurrentSim, QuantumOptics, QuantumOpticsBase, QuantumClifford, Symbolics, WignerSymbols rep = report_package("QuantumSavory"; ignored_modules=( diff --git a/test/test_messagebuffer.jl b/test/test_messagebuffer.jl index 4680ab9f..fd40c48e 100644 --- a/test/test_messagebuffer.jl +++ b/test/test_messagebuffer.jl @@ -1,44 +1,44 @@ @testitem "Message Buffer" tags=[:messagebuffer] begin - using QuantumSavory: tag_types - using QuantumSavory.ProtocolZoo - using ResumableFunctions, ConcurrentSim +using QuantumSavory: tag_types +using QuantumSavory.ProtocolZoo +using ResumableFunctions, ConcurrentSim - net = RegisterNet([Register(3), Register(2), Register(3)]) - env = get_time_tracker(net); - @resumable function receive_tags(env) - while true - mb = messagebuffer(net, 2) - @yield wait(mb) - msg = querydelete!(mb, :second_tag, ❓, ❓) - if isnothing(msg) - # println("nothing") - else - #println("$(msg.tag) received from node $(msg.src)") - end +net = RegisterNet([Register(3), Register(2), Register(3)]) +env = get_time_tracker(net); +@resumable function receive_tags(env) + while true + mb = messagebuffer(net, 2) + @yield wait(mb) + msg = querydelete!(mb, :second_tag, ❓, ❓) + if isnothing(msg) + # println("nothing") + else + #println("$(msg.tag) received from node $(msg.src)") end end - @resumable function send_tags(env) - @yield timeout(env, 1.0) - put!(channel(net, 1=>2), Tag(:my_tag)) - @yield timeout(env, 2.0) - put!(channel(net, 3=>2), Tag(:second_tag, 123, 456)) - end - @process send_tags(env); - @process receive_tags(env); - run(env, 10) +end +@resumable function send_tags(env) + @yield timeout(env, 1.0) + put!(channel(net, 1=>2), Tag(:my_tag)) + @yield timeout(env, 2.0) + put!(channel(net, 3=>2), Tag(:second_tag, 123, 456)) +end +@process send_tags(env); +@process receive_tags(env); +run(env, 10) - @test query(messagebuffer(net, 2), :second_tag, ❓, ❓) === nothing - @test query(messagebuffer(net, 2), :my_tag).tag == Tag(:my_tag) +@test query(messagebuffer(net, 2), :second_tag, ❓, ❓) === nothing +@test query(messagebuffer(net, 2), :my_tag).tag == Tag(:my_tag) - ## +## - net = RegisterNet([Register(4), Register(4)]) - sim = get_time_tracker(net) - proc1 = put!(channel(net, 2=>1), SwitchRequest(2,3)) - proc2 = put!(channel(net, 2=>1), Tag(SwitchRequest(2,3))) - proc3 = put!(messagebuffer(net[1]), Tag(SwitchRequest(2,3))) - proc4 = put!(messagebuffer(net[1]), SwitchRequest(2,3)) - run(sim, 10) - @test QuantumSavory.peektags(messagebuffer(net,1)) == [Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3))] - @test_throws "does not support `tag!`" tag!(messagebuffer(net, 1), EntanglementCounterpart, 1, 10) +net = RegisterNet([Register(4), Register(4)]) +sim = get_time_tracker(net) +proc1 = put!(channel(net, 2=>1), SwitchRequest(2,3)) +proc2 = put!(channel(net, 2=>1), Tag(SwitchRequest(2,3))) +proc3 = put!(messagebuffer(net[1]), Tag(SwitchRequest(2,3))) +proc4 = put!(messagebuffer(net[1]), SwitchRequest(2,3)) +run(sim, 10) +@test QuantumSavory.peektags(messagebuffer(net,1)) == [Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3)), Tag(SwitchRequest(2,3))] +@test_throws "does not support `tag!`" tag!(messagebuffer(net, 1), EntanglementCounterpart, 1, 10) end diff --git a/test/test_noninstant_and_backgrounds_qubit.jl b/test/test_noninstant_and_backgrounds_qubit.jl index 94bfdf08..bcdfd65a 100644 --- a/test/test_noninstant_and_backgrounds_qubit.jl +++ b/test/test_noninstant_and_backgrounds_qubit.jl @@ -1,56 +1,56 @@ @testitem "Noninstant and Backgrounds Qubit" tags=[:noninstant_and_backgrounds_qubit] begin - using QuantumSavory: NonInstantGate +using QuantumSavory: NonInstantGate - ## - # Time of application and gate durations - reg = Register([Qubit(),Qubit()]) - initialize!(reg[1]) - initialize!(reg[2]) - uptotime!(reg[1],0.2) - uptotime!(reg[1],0.2) - @test_throws ErrorException uptotime!(reg[1],0.1) - apply!(reg[1], H; time=0.3) - apply!(reg[1], NonInstantGate(H,0.1); time=0.4) - apply!([reg[1],reg[2]], NonInstantGate(CNOT, 0.1)) - @test_throws ErrorException uptotime!(reg[1],0.55) - @test_throws ErrorException apply!(reg[1], H; time=0.55) +## +# Time of application and gate durations +reg = Register([Qubit(),Qubit()]) +initialize!(reg[1]) +initialize!(reg[2]) +uptotime!(reg[1],0.2) +uptotime!(reg[1],0.2) +@test_throws ErrorException uptotime!(reg[1],0.1) +apply!(reg[1], H; time=0.3) +apply!(reg[1], NonInstantGate(H,0.1); time=0.4) +apply!([reg[1],reg[2]], NonInstantGate(CNOT, 0.1)) +@test_throws ErrorException uptotime!(reg[1],0.55) +@test_throws ErrorException apply!(reg[1], H; time=0.55) - ## - # Kraus vs Lindblad - function kraus_lindblad_test(background,initstate) - reg = Register([Qubit(),Qubit()],[background, background]) - initialize!(reg[1], initstate) - initialize!(reg[2], initstate) - uptotime!(reg[1],0.2) - uptotime!(reg[2],0.1) - uptotime!(reg[2],0.2) - # Test that Kraus weights are calculated correctly - @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] +## +# Kraus vs Lindblad +function kraus_lindblad_test(background,initstate) + reg = Register([Qubit(),Qubit()],[background, background]) + initialize!(reg[1], initstate) + initialize!(reg[2], initstate) + uptotime!(reg[1],0.2) + uptotime!(reg[2],0.1) + uptotime!(reg[2],0.2) + # Test that Kraus weights are calculated correctly + @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] - regb = Register([Qubit(),Qubit()],[background, background]) - initialize!(regb[1], initstate) - initialize!(regb[2], initstate) - subsystemcompose(regb[1],regb[2]) - uptotime!(regb[1],0.2) - uptotime!(regb[2],0.1) - uptotime!(regb[2],0.2) - @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] + regb = Register([Qubit(),Qubit()],[background, background]) + initialize!(regb[1], initstate) + initialize!(regb[2], initstate) + subsystemcompose(regb[1],regb[2]) + uptotime!(regb[1],0.2) + uptotime!(regb[2],0.1) + uptotime!(regb[2],0.2) + @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] - apply!(reg[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) - uptotime!(reg[2],0.4) - @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] + apply!(reg[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) + uptotime!(reg[2],0.4) + @test reg.staterefs[1].state[] ≈ reg.staterefs[2].state[] - apply!(regb[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) - uptotime!(regb[2],0.4) - @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] - end + apply!(regb[1],ConstantHamiltonianEvolution(IdentityOp(X1),0.1),time=0.3) + uptotime!(regb[2],0.4) + @test reg.staterefs[1].state[]⊗reg.staterefs[2].state[] ≈ regb.staterefs[2].state[] +end - kraus_lindblad_test(T1Decay(1.0),Z1) - kraus_lindblad_test(T1Decay(1.0),Z2) - kraus_lindblad_test(T1Decay(1.0),X1) - kraus_lindblad_test(T1Decay(1.0),X2) - kraus_lindblad_test(T2Dephasing(1.0),Z1) - kraus_lindblad_test(T2Dephasing(1.0),Z2) - kraus_lindblad_test(T2Dephasing(1.0),X1) - kraus_lindblad_test(T2Dephasing(1.0),X2) +kraus_lindblad_test(T1Decay(1.0),Z1) +kraus_lindblad_test(T1Decay(1.0),Z2) +kraus_lindblad_test(T1Decay(1.0),X1) +kraus_lindblad_test(T1Decay(1.0),X2) +kraus_lindblad_test(T2Dephasing(1.0),Z1) +kraus_lindblad_test(T2Dephasing(1.0),Z2) +kraus_lindblad_test(T2Dephasing(1.0),X1) +kraus_lindblad_test(T2Dephasing(1.0),X2) end diff --git a/test/test_noninstant_and_backgrounds_qumode.jl b/test/test_noninstant_and_backgrounds_qumode.jl index 99b2c120..a542498e 100644 --- a/test/test_noninstant_and_backgrounds_qumode.jl +++ b/test/test_noninstant_and_backgrounds_qumode.jl @@ -1,12 +1,12 @@ @testitem "Noninstant and Backgrounds Qumode" tags=[:noninstant_and_backgrounds_qumode] begin - ## - # Time of application and gate durations - reg = Register([Qumode(),Qubit(),Qumode()],[AmplitudeDamping(1.0),nothing,nothing]) - initialize!(reg[1],F1) - initialize!(reg[2]) - initialize!(reg[3],F1) - uptotime!(reg[1],0.2) - uptotime!(reg[1],0.2) - @test_throws ErrorException uptotime!(reg[1],0.1) +## +# Time of application and gate durations +reg = Register([Qumode(),Qubit(),Qumode()],[AmplitudeDamping(1.0),nothing,nothing]) +initialize!(reg[1],F1) +initialize!(reg[2]) +initialize!(reg[3],F1) +uptotime!(reg[1],0.2) +uptotime!(reg[1],0.2) +@test_throws ErrorException uptotime!(reg[1],0.1) end diff --git a/test/test_observable.jl b/test/test_observable.jl index 4a783e0d..d10eae3f 100644 --- a/test/test_observable.jl +++ b/test/test_observable.jl @@ -1,17 +1,17 @@ @testitem "Observable" tags=[:observable] begin - const bell = StabilizerState("XX ZZ") - # or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, - # however converting to stabilizer state for Clifford simulations - # is not implemented (and can not be done efficiently). +const bell = StabilizerState("XX ZZ") +# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, +# however converting to stabilizer state for Clifford simulations +# is not implemented (and can not be done efficiently). - for rep in [QuantumOpticsRepr(), CliffordRepr()] - a = Register(2,rep) - initialize!(a[1:2], bell) - @test observable(a[1:2], SProjector(bell)) ≈ 1.0 - @test observable(a[1:2], σˣ⊗σˣ) ≈ 1.0 - apply!(a[1], σʸ) - @test observable(a[1:2], SProjector(bell)) ≈ 0.0 - @test observable(a[1:2], σˣ⊗σˣ) ≈ -1.0 - end +for rep in [QuantumOpticsRepr(), CliffordRepr()] + a = Register(2,rep) + initialize!(a[1:2], bell) + @test observable(a[1:2], SProjector(bell)) ≈ 1.0 + @test observable(a[1:2], σˣ⊗σˣ) ≈ 1.0 + apply!(a[1], σʸ) + @test observable(a[1:2], SProjector(bell)) ≈ 0.0 + @test observable(a[1:2], σˣ⊗σˣ) ≈ -1.0 +end end diff --git a/test/test_plotting_cairo.jl b/test/test_plotting_cairo.jl index 1e07a9e4..86363b1e 100644 --- a/test/test_plotting_cairo.jl +++ b/test/test_plotting_cairo.jl @@ -1,12 +1,12 @@ @testitem "Plotting Cairo" tags=[:plotting_cairo] begin - include("setup_plotting.jl") - using CairoMakie - CairoMakie.activate!() +include("setup_plotting.jl") +using CairoMakie +CairoMakie.activate!() - @testset "register coordinates" begin - include("test_plotting_1_regcoords.jl") - end - @testset "arguments and observables and tags" begin - include("test_plotting_2_tags_observables.jl") - end +@testset "register coordinates" begin + include("test_plotting_1_regcoords.jl") +end +@testset "arguments and observables and tags" begin + include("test_plotting_2_tags_observables.jl") +end end diff --git a/test/test_plotting_gl.jl b/test/test_plotting_gl.jl index 748ab973..6ed88b67 100644 --- a/test/test_plotting_gl.jl +++ b/test/test_plotting_gl.jl @@ -3,15 +3,12 @@ using GLMakie GLMakie.activate!() - @testset "register coordinates" begin - include("test_plotting_1_regcoords.jl") - end - @testset "arguments and observables and tags" begin - include("test_plotting_2_tags_observables.jl") - end +@testset "register coordinates" begin + include("test_plotting_1_regcoords.jl") +end +@testset "arguments and observables and tags" begin + include("test_plotting_2_tags_observables.jl") end - -using QuantumSavory @testset "data inspectors" begin # only available in GLMakie # create a network of qubit registers @@ -30,3 +27,4 @@ using QuantumSavory # check the data inspector tooltip functionality @test Base.get_extension(QuantumSavory, :QuantumSavoryMakie).get_state_vis_string(plt.state_coords_backref[],1) == "Subsystem 1 of a state of 1 subsystems, stored in\nRegister 1 | Slot 1\n not tagged" end +end diff --git a/test/test_project_traceout.jl b/test/test_project_traceout.jl index 223dae36..8584b47f 100644 --- a/test/test_project_traceout.jl +++ b/test/test_project_traceout.jl @@ -1,33 +1,33 @@ @testitem "Project Traceout" tags=[:project_traceout] begin - const bell = StabilizerState("XX ZZ") - # or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, - # however converting to stabilizer state for Clifford simulations - # is not implemented (and can not be done efficiently). +const bell = StabilizerState("XX ZZ") +# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, +# however converting to stabilizer state for Clifford simulations +# is not implemented (and can not be done efficiently). - for rep in [QuantumOpticsRepr(), CliffordRepr()] - a = Register(2,rep) - initialize!(a[1:2], bell) - m1 = project_traceout!(a[1], σʸ) - m2 = project_traceout!(a[2], σʸ) - @test m1!=m2 +for rep in [QuantumOpticsRepr(), CliffordRepr()] + a = Register(2,rep) + initialize!(a[1:2], bell) + m1 = project_traceout!(a[1], σʸ) + m2 = project_traceout!(a[2], σʸ) + @test m1!=m2 - a = Register(4,rep) - @test_throws "Attempting to initialize a set of registers with a state that does not have the correct number of subsystems." initialize!(a[1:2], bell⊗bell) - initialize!(a[1:4], bell⊗bell) - m1 = project_traceout!(a[1], σʸ) - m2 = project_traceout!(a[2], σʸ) - m3 = project_traceout!(a[3], σʸ) - m4 = project_traceout!(a[4], σʸ) - @test m1!=m2 - @test m3!=m4 + a = Register(4,rep) + @test_throws "Attempting to initialize a set of registers with a state that does not have the correct number of subsystems." initialize!(a[1:2], bell⊗bell) + initialize!(a[1:4], bell⊗bell) + m1 = project_traceout!(a[1], σʸ) + m2 = project_traceout!(a[2], σʸ) + m3 = project_traceout!(a[3], σʸ) + m4 = project_traceout!(a[4], σʸ) + @test m1!=m2 + @test m3!=m4 - a = Register(2,rep) - initialize!(a[1], X1) - @test project_traceout!(a[1], σˣ) == 1 - end + a = Register(2,rep) + initialize!(a[1], X1) + @test project_traceout!(a[1], σˣ) == 1 +end - r = Register(1) - initialize!(r[1], Z) - @test_throws "State not normalized. Could be due to passing wrong state to `initialize!`" project_traceout!(r[1], (L0, L1)) +r = Register(1) +initialize!(r[1], Z) +@test_throws "State not normalized. Could be due to passing wrong state to `initialize!`" project_traceout!(r[1], (L0, L1)) end diff --git a/test/test_protocolzoo_entanglement_consumer.jl b/test/test_protocolzoo_entanglement_consumer.jl index 7cb2ade7..673928b9 100644 --- a/test/test_protocolzoo_entanglement_consumer.jl +++ b/test/test_protocolzoo_entanglement_consumer.jl @@ -1,7 +1,7 @@ @testitem "ProtocolZoo Entanglement Consumer" tags=[:protocolzoo_entanglement_consumer] begin - using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer - using Graphs - using ConcurrentSim +using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer +using Graphs +using ConcurrentSim if isinteractive() using Logging @@ -21,10 +21,15 @@ for n in 3:30 @process eprot() end + for v in 2:n-1 + sprot = SwapperProt(sim, net, v; nodeL = <(v), nodeH = >(v), chooseL = argmin, chooseH = argmax, rounds = -1) + @process sprot() + end - for n in 3:30 - net = RegisterNet([Register(10) for j in 1:n]) - sim = get_time_tracker(net) + for v in vertices(net) + etracker = EntanglementTracker(sim, net, v) + @process etracker() + end econ = EntanglementConsumer(sim, net, 1, n; period=1.0) @process econ() @@ -37,28 +42,5 @@ for n in 3:30 @test econ.log[i][3] ≈ 1.0 end - for v in 2:n-1 - sprot = SwapperProt(sim, net, v; nodeL = <(v), nodeH = >(v), chooseL = argmin, chooseH = argmax, rounds = -1) - @process sprot() - end - - for v in vertices(net) - etracker = EntanglementTracker(sim, net, v) - @process etracker() - end - - econ = EntanglementConsumer(sim, net, 1, n; period=1.0) - @process econ() - - run(sim, 100) - - - for i in 1:length(econ.log) - if !isnothing(econ.log[i][2]) - @test econ.log[i][2] ≈ 1.0 - @test econ.log[i][3] ≈ 1.0 - end - end - - end +end end diff --git a/test/test_protocolzoo_entanglement_tracker.jl b/test/test_protocolzoo_entanglement_tracker.jl index 602232ac..e2f151ea 100644 --- a/test/test_protocolzoo_entanglement_tracker.jl +++ b/test/test_protocolzoo_entanglement_tracker.jl @@ -1,112 +1,112 @@ @testitem "ProtocolZoo Entanglement Tracker" tags=[:protocolzoo_entanglement_tracker] begin - using Revise - using ResumableFunctions - using ConcurrentSim - using QuantumSavory.ProtocolZoo - using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ - using Graphs - - if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") - end +using Revise +using ResumableFunctions +using ConcurrentSim +using QuantumSavory.ProtocolZoo +using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ +using Graphs + +if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") +end - ## +## - # without an entanglement tracker +# without an entanglement tracker - for i in 1:10 +for i in 1:10 - net = RegisterNet([Register(3), Register(4), Register(2), Register(3)]) - sim = get_time_tracker(net) + net = RegisterNet([Register(3), Register(4), Register(2), Register(3)]) + sim = get_time_tracker(net) - entangler1 = EntanglerProt(sim, net, 1, 2; rounds=1) - @process entangler1() - run(sim, 20) + entangler1 = EntanglerProt(sim, net, 1, 2; rounds=1) + @process entangler1() + run(sim, 20) - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] - entangler2 = EntanglerProt(sim, net, 2, 3; rounds=1) - @process entangler2() - run(sim, 40) - entangler3 = EntanglerProt(sim, net, 4, 3; rounds=1) - @process entangler3() - run(sim, 60) + entangler2 = EntanglerProt(sim, net, 2, 3; rounds=1) + @process entangler2() + run(sim, 40) + entangler3 = EntanglerProt(sim, net, 4, 3; rounds=1) + @process entangler3() + run(sim, 60) - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] - @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] - @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] - @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] + @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] + @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), chooseL = argmin, chooseH = argmax, rounds = 1) - swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), chooseL = argmin, chooseH = argmax, rounds = 1) - @process swapper2() - @process swapper3() - run(sim, 80) + swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), chooseL = argmin, chooseH = argmax, rounds = 1) + swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), chooseL = argmin, chooseH = argmax, rounds = 1) + @process swapper2() + @process swapper3() + run(sim, 80) - # In the absence of an entanglement tracker the tags will not all be updated - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] - @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] - @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementHistory, 2, 2, 4, 1, 2), Tag(EntanglementHistory, 4, 1, 2, 2, 1)] - @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] + # In the absence of an entanglement tracker the tags will not all be updated + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[2].tag_info[i].tag for i in net[2].guids] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] + @test [net[3].tag_info[i].tag for i in net[3].guids] == [Tag(EntanglementHistory, 2, 2, 4, 1, 2), Tag(EntanglementHistory, 4, 1, 2, 2, 1)] + @test [net[4].tag_info[i].tag for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] - @test isassigned(net[1][1]) && isassigned(net[4][1]) - @test !isassigned(net[2][1]) && !isassigned(net[3][1]) - @test !isassigned(net[2][2]) && !isassigned(net[3][2]) + @test isassigned(net[1][1]) && isassigned(net[4][1]) + @test !isassigned(net[2][1]) && !isassigned(net[3][1]) + @test !isassigned(net[2][2]) && !isassigned(net[3][2]) - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - end +end - ## - - using Revise - using ResumableFunctions - using ConcurrentSim - using QuantumSavory.ProtocolZoo - using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ - using Graphs - using Random - - if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Warn; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") - end +## + +using Revise +using ResumableFunctions +using ConcurrentSim +using QuantumSavory.ProtocolZoo +using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ +using Graphs +using Random + +if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Warn; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") +end - ## - - # same but this time with an entanglement tracker - - for i in 1:30, n in 2:30 - net = RegisterNet([Register(j+3) for j in 1:n]) - sim = get_time_tracker(net) - for j in vertices(net) - tracker = EntanglementTracker(sim, net, j) - @process tracker() - end - for e in edges(net) - eprot = EntanglerProt(sim, net, e.src, e.dst; rounds=1, randomize=true) - @process eprot() - end - for j in 2:n-1 - swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) - @process swapper() - end - run(sim, 200) - - q1 = query(net[1], EntanglementCounterpart, n, ❓) - q2 = query(net[n], EntanglementCounterpart, 1, ❓) - @test q1.tag[2] == n - @test q2.tag[2] == 1 - @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 - @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 +## + +# same but this time with an entanglement tracker + +for i in 1:30, n in 2:30 + net = RegisterNet([Register(j+3) for j in 1:n]) + sim = get_time_tracker(net) + for j in vertices(net) + tracker = EntanglementTracker(sim, net, j) + @process tracker() + end + for e in edges(net) + eprot = EntanglerProt(sim, net, e.src, e.dst; rounds=1, randomize=true) + @process eprot() end + for j in 2:n-1 + swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) + @process swapper() + end + run(sim, 200) + + q1 = query(net[1], EntanglementCounterpart, n, ❓) + q2 = query(net[n], EntanglementCounterpart, 1, ❓) + @test q1.tag[2] == n + @test q2.tag[2] == 1 + @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 + @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 +end end diff --git a/test/test_protocolzoo_entanglement_tracker_grid.jl b/test/test_protocolzoo_entanglement_tracker_grid.jl index b3d1f16c..ed9677e9 100644 --- a/test/test_protocolzoo_entanglement_tracker_grid.jl +++ b/test/test_protocolzoo_entanglement_tracker_grid.jl @@ -1,234 +1,186 @@ @testitem "ProtocolZoo Entanglement Tracker Grid" tags=[:protocolzoo_entanglement_tracker_grid] begin - using Revise - using ResumableFunctions - using ConcurrentSim - using QuantumSavory.ProtocolZoo - using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ - using Graphs - - if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") - end - - ## - - # This set of tests ensures that the combination of entanglement genererator, tracker, and swapper works on what is basically a 1D chain of nodes that happen to be otherwise located in a grid. - # This set of tests DOES NOT test anything related to 2D grid structure of a network. - # It is little more than a copy of `test_entanglement_tracker` but with more complicated predicates for choosing who to swap in swapper protocol. - - # Custom Predicates - - #Choose any nodes that have a positive manhattan distance for "low nodes" and any nodes that have a negative manhattan distance for the "high nodes" case - function check_nodes(net, c_node, node; low=true) - n = Int(sqrt(size(net.graph)[1])) # grid size - c_x = c_node%n == 0 ? c_node ÷ n : (c_node ÷ n) + 1 - c_y = c_node - n*(c_x-1) - x = node%n == 0 ? node ÷ n : (node ÷ n) + 1 - y = node - n*(x-1) - return low ? (c_x - x) >= 0 && (c_y - y) >= 0 : (c_x - x) <= 0 && (c_y - y) <= 0 - end - - # predicate for picking the furthest node - function distance(n, a, b) - x1 = a%n == 0 ? a ÷ n : (a ÷ n) + 1 - x2 = b%n == 0 ? b ÷ n : (b ÷ n) + 1 - y1 = a - n*(x1-1) - y2 = b - n*(x2-1) - - return x1 - x2 + y1 - y2 - end +using Revise +using ResumableFunctions +using ConcurrentSim +using QuantumSavory.ProtocolZoo +using QuantumSavory.ProtocolZoo: EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ +using Graphs + +if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") +end - # filter for picking the furthest node - function choose_node(net, node, arr; low=true) - grid_size = Int(sqrt(size(net.graph)[1])) - return low ? argmax((distance.(grid_size, node, arr))) : argmin((distance.(grid_size, node, arr))) - end +## - ## - - # Here we run a bunch of low-level correctness tests for EntanglementProt and SwapperProt - # but we do not run a complete simulation that includes EntanglementTracker. - # Some arbitrary possible 1D chains embedded in the 2D grid - paths = [ - [2, 3, 4, 8, 12], - [2, 6, 7, 11, 15], - [5, 9, 13, 14, 15], - [2, 6, 10, 14, 15], - [5, 6, 7, 8, 12], - [5, 6, 10, 11, 12], - [2, 3, 7, 11, 12] - ] # for 4x4 grid setup - for path in paths - graph = grid([4, 4]) - - net = RegisterNet(graph, [Register(3) for i in 1:16]) - sim = get_time_tracker(net) - - - entangler1 = EntanglerProt(sim, net, 1, path[1]; rounds=1) - @process entangler1() - run(sim, 20) - - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] - - - # For no particular reason we are starting the entangler protocols at different times - # and we run them for only one round - entangler2 = EntanglerProt(sim, net, path[1], path[2]; rounds=1) - @process entangler2() - run(sim, 40) - entangler3 = EntanglerProt(sim, net, path[2], path[3]; rounds=1) - @process entangler3() - run(sim, 60) - entangler4 = EntanglerProt(sim, net, path[3], path[4]; rounds=1) - @process entangler4() - run(sim, 80) - entangler5 = EntanglerProt(sim, net, path[4], path[5];rounds=1) - @process entangler5() - run(sim, 100) - entangler6 = EntanglerProt(sim, net, path[5], 16; rounds=1) - @process entangler6() - run(sim, 120) - - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] - @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] - @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementCounterpart, path[1], 2), Tag(EntanglementCounterpart, path[3], 1)] - @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] - @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementCounterpart, path[3], 2), Tag(EntanglementCounterpart, path[5], 1)] - @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementCounterpart, path[4], 2), Tag(EntanglementCounterpart, 16, 1)] - @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] - - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - - for i in 1:5 - l = x->check_nodes(net, path[i], x) - h = x->check_nodes(net, path[i], x; low=false) - cL = arr->choose_node(net, path[i], arr) - cH = arr->choose_node(net, path[i], arr; low=false) - swapper = SwapperProt(sim, net, path[i]; nodeL=l, nodeH=h, chooseL=cL, chooseH=cH, rounds=1) - @process swapper() - end - run(sim, 200) - - # In the absence of an entanglement tracker the tags will not all be updated - @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] - @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] - @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] - @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementHistory, path[2], 2, path[4], 1, 2), Tag(EntanglementHistory, path[4], 1, path[2], 2, 1)] - @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementHistory, path[3], 2, path[5], 1, 2), Tag(EntanglementHistory, path[5], 1, path[3], 2, 1)] - @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementHistory, path[4], 2, 16, 1, 2), Tag(EntanglementHistory, 16, 1, path[4], 2, 1)] - @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] - - @test isassigned(net[1][1]) && isassigned(net[16][1]) - @test !isassigned(net[path[1]][1]) && !isassigned(net[path[2]][1]) - @test !isassigned(net[path[1]][2]) && !isassigned(net[path[2]][2]) - @test !isassigned(net[path[3]][1]) && !isassigned(net[path[4]][1]) - @test !isassigned(net[path[3]][2]) && !isassigned(net[path[4]][2]) - @test !isassigned(net[path[5]][1]) && !isassigned(net[path[5]][2]) - - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - end +# This set of tests ensures that the combination of entanglement genererator, tracker, and swapper works on what is basically a 1D chain of nodes that happen to be otherwise located in a grid. +# This set of tests DOES NOT test anything related to 2D grid structure of a network. +# It is little more than a copy of `test_entanglement_tracker` but with more complicated predicates for choosing who to swap in swapper protocol. - ## +# Custom Predicates - # Finally, we run the complete simulation, with EntanglerProt, SwapperProt, and EntanglementTracker, - # and we actually use a 2D grid of nodes. - # In these tests, we still use only a finite number of rounds. +#Choose any nodes that have a positive manhattan distance for "low nodes" and any nodes that have a negative manhattan distance for the "high nodes" case +function check_nodes(net, c_node, node; low=true) + n = Int(sqrt(size(net.graph)[1])) # grid size + c_x = c_node%n == 0 ? c_node ÷ n : (c_node ÷ n) + 1 + c_y = c_node - n*(c_x-1) + x = node%n == 0 ? node ÷ n : (node ÷ n) + 1 + y = node - n*(x-1) + return low ? (c_x - x) >= 0 && (c_y - y) >= 0 : (c_x - x) <= 0 && (c_y - y) <= 0 +end - # For this one, we have a square grid of nodes, and we add diagonal channels to the grid. - for n in 4:10 - graph = grid([n,n]) +# predicate for picking the furthest node +function distance(n, a, b) + x1 = a%n == 0 ? a ÷ n : (a ÷ n) + 1 + x2 = b%n == 0 ? b ÷ n : (b ÷ n) + 1 + y1 = a - n*(x1-1) + y2 = b - n*(x2-1) - for i in 1:(n^2 - n + 1) # add diagonal channels - if !iszero(i%n) # no diagonal channel from last node in a row - add_edge!(graph, i, i + n + 1) - end - end + return x1 - x2 + y1 - y2 +end - net = RegisterNet(graph, [Register(8) for i in 1:n^2]) +# filter for picking the furthest node +function choose_node(net, node, arr; low=true) + grid_size = Int(sqrt(size(net.graph)[1])) + return low ? argmax((distance.(grid_size, node, arr))) : argmin((distance.(grid_size, node, arr))) +end - sim = get_time_tracker(net) +## - for (;src, dst) in edges(net) - eprot = EntanglerProt(sim, net, src, dst; rounds=5, randomize=true) # A single round doesn't always get the ends entangled, when number of nodes is high - @process eprot() - end +# Here we run a bunch of low-level correctness tests for EntanglementProt and SwapperProt +# but we do not run a complete simulation that includes EntanglementTracker. +# Some arbitrary possible 1D chains embedded in the 2D grid +paths = [ + [2, 3, 4, 8, 12], + [2, 6, 7, 11, 15], + [5, 9, 13, 14, 15], + [2, 6, 10, 14, 15], + [5, 6, 7, 8, 12], + [5, 6, 10, 11, 12], + [2, 3, 7, 11, 12] +] # for 4x4 grid setup +for path in paths + graph = grid([4, 4]) + + net = RegisterNet(graph, [Register(3) for i in 1:16]) + sim = get_time_tracker(net) - for i in 2:(size(graph)[1] - 1) - l(x) = check_nodes(net, i, x) - h(x) = check_nodes(net, i, x; low=false) - cL(arr) = choose_node(net, i, arr) - cH(arr) = choose_node(net, i, arr; low=false) - swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds = 5) # A single round doesn't always get the ends entangled, when number of nodes is high - @process swapper() - end - for v in vertices(net) - tracker = EntanglementTracker(sim, net, v) - @process tracker() - end + entangler1 = EntanglerProt(sim, net, 1, path[1]; rounds=1) + @process entangler1() + run(sim, 20) - run(sim, 200) + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] - # has a small chance of failing due to the randomization of the entanglement protocols - q1 = query(net[1], EntanglementCounterpart, size(graph)[1], ❓) - q2 = query(net[size(graph)[1]], EntanglementCounterpart, 1, q1.slot.idx) - @test q1.tag[2] == size(graph)[1] - @test q2.tag[2] == 1 - @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1.0 - @test observable((q1.slot, q2.slot), X⊗X) ≈ 1.0 + # For no particular reason we are starting the entangler protocols at different times + # and we run them for only one round + entangler2 = EntanglerProt(sim, net, path[1], path[2]; rounds=1) + @process entangler2() + run(sim, 40) + entangler3 = EntanglerProt(sim, net, path[2], path[3]; rounds=1) + @process entangler3() + run(sim, 60) + entangler4 = EntanglerProt(sim, net, path[3], path[4]; rounds=1) + @process entangler4() + run(sim, 80) + entangler5 = EntanglerProt(sim, net, path[4], path[5];rounds=1) + @process entangler5() + run(sim, 100) + entangler6 = EntanglerProt(sim, net, path[5], 16; rounds=1) + @process entangler6() + run(sim, 120) + + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] + @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementCounterpart, path[1], 2), Tag(EntanglementCounterpart, path[3], 1)] + @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] + @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementCounterpart, path[3], 2), Tag(EntanglementCounterpart, path[5], 1)] + @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementCounterpart, path[4], 2), Tag(EntanglementCounterpart, 16, 1)] + @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + + for i in 1:5 + l = x->check_nodes(net, path[i], x) + h = x->check_nodes(net, path[i], x; low=false) + cL = arr->choose_node(net, path[i], arr) + cH = arr->choose_node(net, path[i], arr; low=false) + swapper = SwapperProt(sim, net, path[i]; nodeL=l, nodeH=h, chooseL=cL, chooseH=cH, rounds=1) + @process swapper() end + run(sim, 200) + + # In the absence of an entanglement tracker the tags will not all be updated + @test [net[1].tag_info[i].tag for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[path[1]].tag_info[i].tag for i in net[path[1]].guids] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] + @test [net[path[2]].tag_info[i].tag for i in net[path[2]].guids] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] + @test [net[path[3]].tag_info[i].tag for i in net[path[3]].guids] == [Tag(EntanglementHistory, path[2], 2, path[4], 1, 2), Tag(EntanglementHistory, path[4], 1, path[2], 2, 1)] + @test [net[path[4]].tag_info[i].tag for i in net[path[4]].guids] == [Tag(EntanglementHistory, path[3], 2, path[5], 1, 2), Tag(EntanglementHistory, path[5], 1, path[3], 2, 1)] + @test [net[path[5]].tag_info[i].tag for i in net[path[5]].guids] == [Tag(EntanglementHistory, path[4], 2, 16, 1, 2), Tag(EntanglementHistory, 16, 1, path[4], 2, 1)] + @test [net[16].tag_info[i].tag for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] + + @test isassigned(net[1][1]) && isassigned(net[16][1]) + @test !isassigned(net[path[1]][1]) && !isassigned(net[path[2]][1]) + @test !isassigned(net[path[1]][2]) && !isassigned(net[path[2]][2]) + @test !isassigned(net[path[3]][1]) && !isassigned(net[path[4]][1]) + @test !isassigned(net[path[3]][2]) && !isassigned(net[path[4]][2]) + @test !isassigned(net[path[5]][1]) && !isassigned(net[path[5]][2]) + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false +end - # and here we test for a simple 2d rectangular grid - for n in 4:10 - graph = grid([n,n]) - - net = RegisterNet(graph, [Register(8) for i in 1:n^2]) +## - sim = get_time_tracker(net) +# Finally, we run the complete simulation, with EntanglerProt, SwapperProt, and EntanglementTracker, +# and we actually use a 2D grid of nodes. +# In these tests, we still use only a finite number of rounds. - for (;src, dst) in edges(net) - eprot = EntanglerProt(sim, net, src, dst; rounds=5, randomize=true) # A single round doesn't always get the ends entangled, when number of nodes is high - @process eprot() - end +# For this one, we have a square grid of nodes, and we add diagonal channels to the grid. +for n in 4:10 + graph = grid([n,n]) - for i in 2:(size(graph)[1] - 1) - l(x) = check_nodes(net, i, x) - h(x) = check_nodes(net, i, x; low=false) - cL(arr) = choose_node(net, i, arr) - cH(arr) = choose_node(net, i, arr; low=false) - swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds = 5) # A single round doesn't always get the ends entangled, when number of nodes is high - @process swapper() + for i in 1:(n^2 - n + 1) # add diagonal channels + if !iszero(i%n) # no diagonal channel from last node in a row + add_edge!(graph, i, i + n + 1) end + end - for v in vertices(net) - tracker = EntanglementTracker(sim, net, v) - @process tracker() - end + net = RegisterNet(graph, [Register(8) for i in 1:n^2]) - run(sim, 100) + sim = get_time_tracker(net) - q1 = query(net[1], EntanglementCounterpart, size(graph)[1], ❓) - q2 = query(net[size(graph)[1]], EntanglementCounterpart, 1, q1.slot.idx) + for (;src, dst) in edges(net) + eprot = EntanglerProt(sim, net, src, dst; rounds=5, randomize=true) # A single round doesn't always get the ends entangled, when number of nodes is high + @process eprot() + end - @test q1.tag[2] == size(graph)[1] - @test q2.tag[2] == 1 - @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1.0 - @test observable((q1.slot, q2.slot), X⊗X) ≈ 1.0 + for i in 2:(size(graph)[1] - 1) + l(x) = check_nodes(net, i, x) + h(x) = check_nodes(net, i, x; low=false) + cL(arr) = choose_node(net, i, arr) + cH(arr) = choose_node(net, i, arr; low=false) + swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds = 5) # A single round doesn't always get the ends entangled, when number of nodes is high + @process swapper() end + for v in vertices(net) + tracker = EntanglementTracker(sim, net, v) + @process tracker() + end - ## + run(sim, 200) - # More tests of 2D rectangular grids with the full stack of protocols, - # but also now with an unlimited number of rounds and an entanglement consumer. + # has a small chance of failing due to the randomization of the entanglement protocols + q1 = query(net[1], EntanglementCounterpart, size(graph)[1], ❓) + q2 = query(net[size(graph)[1]], EntanglementCounterpart, 1, q1.slot.idx) - #TODO - @test_broken false + @test q1.tag[2] == size(graph)[1] + @test q2.tag[2] == 1 + @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1.0 + @test observable((q1.slot, q2.slot), X⊗X) ≈ 1.0 end # and here we test for a simple 2d rectangular grid @@ -321,3 +273,4 @@ for i in 1:length(consumer.log) @test consumer.log[i][2] ≈ 1.0 @test consumer.log[i][3] ≈ 1.0 end +end diff --git a/test/test_quantumchannel.jl b/test/test_quantumchannel.jl index 16a3c979..8c1a2a48 100644 --- a/test/test_quantumchannel.jl +++ b/test/test_quantumchannel.jl @@ -1,111 +1,111 @@ @testitem "Quantum Channel" tags=[:quantumchannel] begin - using ResumableFunctions - using ConcurrentSim - - bell = (Z1⊗Z1 + Z2⊗Z2)/sqrt(2.0) - - ## Manually construct a QuantumChannel and test a simple put/take - - sim = Simulation() - regA = Register(1) - regB = Register(2) - initialize!((regA[1], regB[2]), bell) - # Delay queue for quantum channel - queue = DelayQueue{Register}(sim, 10.0) - qc = QuantumChannel(queue) - - @resumable function alice_node(env, qc) - put!(qc, regA[1]) - end - - @resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) - end - - @process alice_node(sim, qc) - @process bob_node(sim, qc) - - run(sim) - - # the above code puts both the qubits of the state in the same register - sref = regB.staterefs[1] - @test sref.registers[1] == sref.registers[2] - @test !isassigned(regA, 1) - - ## Test with the second constructor - - regA = Register(1) - regB = Register(2) - initialize!((regA[1], regB[2]), bell) - sim = Simulation() - qc = QuantumChannel(sim, 10.0) - @resumable function alice_node(env, qc) - put!(qc, regA[1]) - end - @resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) - end - @process alice_node(sim, qc) - @process bob_node(sim, qc) - run(sim) - sref = regB.staterefs[1] - @test sref.registers[1] == sref.registers[2] - @test !isassigned(regA, 1) - - ## Test with T1Decay - - regA = Register(1) - regB = Register(2) - initialize!((regA[1], regB[2]), bell) - sim = Simulation() - qc = QuantumChannel(sim, 10.0, T1Decay(0.1)) - @resumable function alice_node(env, qc) - put!(qc, regA[1]) - end - @resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) - end - @process alice_node(sim, qc) - @process bob_node(sim, qc) - run(sim) - - # compare against a stationary qubit experiencing the same T1 decay - reg = Register([Qubit(), Qubit()], [T1Decay(0.1), nothing]) - initialize!(reg[1:2], bell) - uptotime!(reg[1], 10.0) - - @test observable(reg[1:2], projector(bell)) ≈ observable(regB[1:2], projector(bell)) - - ## Test with T2Dephasing - - regA = Register(2) - regB = Register(2) - initialize!((regA[1], regB[2]), bell) - sim = Simulation() - qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) - @resumable function alice_node(env, qc) - put!(qc, regA[1]) - end - @resumable function bob_node(env, qc) - @yield take!(qc, regB[1]) - end - @process alice_node(sim, qc) - @process bob_node(sim, qc) - run(sim) - - reg = Register([Qubit(), Qubit()], [T2Dephasing(0.1), nothing]) - initialize!(reg[1:2], bell) - uptotime!(reg[1], 10.0) - - @test observable(reg[1:2], projector(bell)) == observable(regB[1:2], projector(bell)) - - ## Test for slot availability - - sim = Simulation() - qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) - regC = Register(1) - initialize!(regC[1], Z1) - put!(qc, regC[1]) - take!(qc, regB[1]) - @test_throws "A take! operation is being performed on a QuantumChannel in order to swap the state into a Register, but the target register slot is not empty (it is already initialized)." run(sim) +using ResumableFunctions +using ConcurrentSim + +bell = (Z1⊗Z1 + Z2⊗Z2)/sqrt(2.0) + +## Manually construct a QuantumChannel and test a simple put/take + +sim = Simulation() +regA = Register(1) +regB = Register(2) +initialize!((regA[1], regB[2]), bell) +# Delay queue for quantum channel +queue = DelayQueue{Register}(sim, 10.0) +qc = QuantumChannel(queue) + +@resumable function alice_node(env, qc) + put!(qc, regA[1]) +end + +@resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) +end + +@process alice_node(sim, qc) +@process bob_node(sim, qc) + +run(sim) + +# the above code puts both the qubits of the state in the same register +sref = regB.staterefs[1] +@test sref.registers[1] == sref.registers[2] +@test !isassigned(regA, 1) + +## Test with the second constructor + +regA = Register(1) +regB = Register(2) +initialize!((regA[1], regB[2]), bell) +sim = Simulation() +qc = QuantumChannel(sim, 10.0) +@resumable function alice_node(env, qc) + put!(qc, regA[1]) +end +@resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) +end +@process alice_node(sim, qc) +@process bob_node(sim, qc) +run(sim) +sref = regB.staterefs[1] +@test sref.registers[1] == sref.registers[2] +@test !isassigned(regA, 1) + +## Test with T1Decay + +regA = Register(1) +regB = Register(2) +initialize!((regA[1], regB[2]), bell) +sim = Simulation() +qc = QuantumChannel(sim, 10.0, T1Decay(0.1)) +@resumable function alice_node(env, qc) + put!(qc, regA[1]) +end +@resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) +end +@process alice_node(sim, qc) +@process bob_node(sim, qc) +run(sim) + +# compare against a stationary qubit experiencing the same T1 decay +reg = Register([Qubit(), Qubit()], [T1Decay(0.1), nothing]) +initialize!(reg[1:2], bell) +uptotime!(reg[1], 10.0) + +@test observable(reg[1:2], projector(bell)) ≈ observable(regB[1:2], projector(bell)) + +## Test with T2Dephasing + +regA = Register(2) +regB = Register(2) +initialize!((regA[1], regB[2]), bell) +sim = Simulation() +qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) +@resumable function alice_node(env, qc) + put!(qc, regA[1]) +end +@resumable function bob_node(env, qc) + @yield take!(qc, regB[1]) +end +@process alice_node(sim, qc) +@process bob_node(sim, qc) +run(sim) + +reg = Register([Qubit(), Qubit()], [T2Dephasing(0.1), nothing]) +initialize!(reg[1:2], bell) +uptotime!(reg[1], 10.0) + +@test observable(reg[1:2], projector(bell)) == observable(regB[1:2], projector(bell)) + +## Test for slot availability + +sim = Simulation() +qc = QuantumChannel(sim, 10.0, T2Dephasing(0.1)) +regC = Register(1) +initialize!(regC[1], Z1) +put!(qc, regC[1]) +take!(qc, regB[1]) +@test_throws "A take! operation is being performed on a QuantumChannel in order to swap the state into a Register, but the target register slot is not empty (it is already initialized)." run(sim) end diff --git a/test/test_register_interface.jl b/test/test_register_interface.jl index b1d2f2e1..4770e907 100644 --- a/test/test_register_interface.jl +++ b/test/test_register_interface.jl @@ -1,79 +1,79 @@ @testitem "Register Interface" tags=[:register_interface] begin - using QuantumOpticsBase: Ket, Operator - using QuantumClifford: MixedDestabilizer +using QuantumOpticsBase: Ket, Operator +using QuantumClifford: MixedDestabilizer - ## - # no backgrounds - traits = [Qubit(), Qubit(), Qubit()] - reg1 = Register(traits) - qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] - reg2 = Register(traits, qc_repr) - qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] - reg3 = Register(traits, qmc_repr) - net = RegisterNet([reg1, reg2, reg3]) +## +# no backgrounds +traits = [Qubit(), Qubit(), Qubit()] +reg1 = Register(traits) +qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] +reg2 = Register(traits, qc_repr) +qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] +reg3 = Register(traits, qmc_repr) +net = RegisterNet([reg1, reg2, reg3]) - i = 1 - initialize!(net[i,2]) - @test nsubsystems(net[i].staterefs[2]) == 1 - initialize!(net[i,3],X1) - @test nsubsystems(net[i].staterefs[2]) == 1 - apply!([net[i,2], net[i,3]], CNOT) - @test net[i].staterefs[2].state[] isa Ket - @test nsubsystems(net[i].staterefs[2]) == 2 +i = 1 +initialize!(net[i,2]) +@test nsubsystems(net[i].staterefs[2]) == 1 +initialize!(net[i,3],X1) +@test nsubsystems(net[i].staterefs[2]) == 1 +apply!([net[i,2], net[i,3]], CNOT) +@test net[i].staterefs[2].state[] isa Ket +@test nsubsystems(net[i].staterefs[2]) == 2 - i = 2 - initialize!(net[i,2]) - @test nsubsystems(net[i].staterefs[2]) == 1 - initialize!(net[i,3],X1) - @test nsubsystems(net[i].staterefs[2]) == 1 - apply!([net[i,2], net[i,3]], CNOT) - @test net[i].staterefs[2].state[] isa MixedDestabilizer - @test nsubsystems(net[i].staterefs[2]) == 2 +i = 2 +initialize!(net[i,2]) +@test nsubsystems(net[i].staterefs[2]) == 1 +initialize!(net[i,3],X1) +@test nsubsystems(net[i].staterefs[2]) == 1 +apply!([net[i,2], net[i,3]], CNOT) +@test net[i].staterefs[2].state[] isa MixedDestabilizer +@test nsubsystems(net[i].staterefs[2]) == 2 - i = 3 - initialize!(net[i,2]) - @test nsubsystems(net[i].staterefs[2]) == 1 - initialize!(net[i,3],X1) - @test nsubsystems(net[i].staterefs[2]) == 1 - apply!([net[i,2], net[i,3]], CNOT) - @test net[i].staterefs[2].state[] isa Ket - @test nsubsystems(net[i].staterefs[2]) == 2 +i = 3 +initialize!(net[i,2]) +@test nsubsystems(net[i].staterefs[2]) == 1 +initialize!(net[i,3],X1) +@test nsubsystems(net[i].staterefs[2]) == 1 +apply!([net[i,2], net[i,3]], CNOT) +@test net[i].staterefs[2].state[] isa Ket +@test nsubsystems(net[i].staterefs[2]) == 2 - ## - # with backgrounds - traits = [Qubit(), Qubit(), Qubit()] - backgrounds = [T2Dephasing(1.0),T2Dephasing(1.0),T2Dephasing(1.0)] - reg1 = Register(traits, backgrounds) - qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] - reg2 = Register(traits, qc_repr, backgrounds) - qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] - reg3 = Register(traits, qmc_repr, backgrounds) - net = RegisterNet([reg1, reg2, reg3]) +## +# with backgrounds +traits = [Qubit(), Qubit(), Qubit()] +backgrounds = [T2Dephasing(1.0),T2Dephasing(1.0),T2Dephasing(1.0)] +reg1 = Register(traits, backgrounds) +qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()] +reg2 = Register(traits, qc_repr, backgrounds) +qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()] +reg3 = Register(traits, qmc_repr, backgrounds) +net = RegisterNet([reg1, reg2, reg3]) - i = 1 - initialize!(net[i,2], time=1.0) - @test nsubsystems(net[i].staterefs[2]) == 1 - initialize!(net[i,3],X1, time=2.0) - @test nsubsystems(net[i].staterefs[2]) == 1 - apply!([net[i,2], net[i,3]], CNOT, time=3.0) - @test net[i].staterefs[2].state[] isa Operator - @test nsubsystems(net[i].staterefs[2]) == 2 +i = 1 +initialize!(net[i,2], time=1.0) +@test nsubsystems(net[i].staterefs[2]) == 1 +initialize!(net[i,3],X1, time=2.0) +@test nsubsystems(net[i].staterefs[2]) == 1 +apply!([net[i,2], net[i,3]], CNOT, time=3.0) +@test net[i].staterefs[2].state[] isa Operator +@test nsubsystems(net[i].staterefs[2]) == 2 - i = 2 - initialize!(net[i,2], time=1.0) - @test nsubsystems(net[i].staterefs[2]) == 1 - initialize!(net[i,3],X1, time=2.0) - @test nsubsystems(net[i].staterefs[2]) == 1 - apply!([net[i,2], net[i,3]], CNOT, time=3.0) - @test net[i].staterefs[2].state[] isa MixedDestabilizer - @test nsubsystems(net[i].staterefs[2]) == 2 +i = 2 +initialize!(net[i,2], time=1.0) +@test nsubsystems(net[i].staterefs[2]) == 1 +initialize!(net[i,3],X1, time=2.0) +@test nsubsystems(net[i].staterefs[2]) == 1 +apply!([net[i,2], net[i,3]], CNOT, time=3.0) +@test net[i].staterefs[2].state[] isa MixedDestabilizer +@test nsubsystems(net[i].staterefs[2]) == 2 - i = 3 - initialize!(net[i,2], time=1.0) - @test nsubsystems(net[i].staterefs[2]) == 1 - initialize!(net[i,3],X1, time=2.0) - @test nsubsystems(net[i].staterefs[2]) == 1 - apply!([net[i,2], net[i,3]], CNOT, time=3.0) - @test_broken net[i].staterefs[2].state[] isa Ket - @test nsubsystems(net[i].staterefs[2]) == 2 +i = 3 +initialize!(net[i,2], time=1.0) +@test nsubsystems(net[i].staterefs[2]) == 1 +initialize!(net[i,3],X1, time=2.0) +@test nsubsystems(net[i].staterefs[2]) == 1 +apply!([net[i,2], net[i,3]], CNOT, time=3.0) +@test_broken net[i].staterefs[2].state[] isa Ket +@test nsubsystems(net[i].staterefs[2]) == 2 end diff --git a/test/test_registernet_interface.jl b/test/test_registernet_interface.jl index 78d7359e..a6ec8a99 100644 --- a/test/test_registernet_interface.jl +++ b/test/test_registernet_interface.jl @@ -1,19 +1,19 @@ @testitem "RegisterNet Interface" tags=[:registernet_interface] begin - using Graphs - using QuantumOpticsBase: Ket, Operator - using QuantumClifford: MixedDestabilizer +using Graphs +using QuantumOpticsBase: Ket, Operator +using QuantumClifford: MixedDestabilizer - ## +## - r1 = Register(3) - r2 = Register(4) - r3 = Register(5) +r1 = Register(3) +r2 = Register(4) +r3 = Register(5) - net = RegisterNet([r1, r2, r3]) +net = RegisterNet([r1, r2, r3]) - @test net[1,2] == r1[2] - @test net[2,3] == r2[3] +@test net[1,2] == r1[2] +@test net[2,3] == r2[3] - net[1,:label] = "lala" - @test net[1,:label] == "lala" +net[1,:label] = "lala" +@test net[1,:label] == "lala" end diff --git a/test/test_stateszoo_api.jl b/test/test_stateszoo_api.jl index cac472c7..005d0e2f 100644 --- a/test/test_stateszoo_api.jl +++ b/test/test_stateszoo_api.jl @@ -1,37 +1,37 @@ @testitem "StatesZoo API" tags=[:stateszoo_api] begin - using QuantumSavory.StatesZoo: ZALMSpinPairW, ZALMSpinPair, SingleRailMidSwapBellW, SingleRailMidSwapBell, DualRailMidSwapBellW, DualRailMidSwapBell - using QuantumOpticsBase - - zalmW = ZALMSpinPairW(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) - zalm = ZALMSpinPair(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) - srmsW = SingleRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) - srms = SingleRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) - drmsW = DualRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) - drms = DualRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) - - r_zalmW = Register(2) - initialize!(r_zalmW[1:2], zalmW) - @test ! iszero(observable(r_zalmW[1:2], Z⊗Z)) - - r_zalm = Register(2) - initialize!(r_zalm[1:2], zalm) - @test ! iszero(observable(r_zalm[1:2], Z⊗Z)) - - r_srmsW = Register(2) - initialize!(r_srmsW[1:2], srmsW) - @test ! iszero(observable(r_srmsW[1:2], Z⊗Z)) - - r_srms = Register(2) - initialize!(r_srms[1:2], srms) - @test ! iszero(observable(r_srms[1:2], Z⊗Z)) - - r_drmsW = Register(2) - initialize!(r_drmsW[1:2], drmsW) - @test ! iszero(observable(r_drmsW[1:2], Z⊗Z)) - - r_drms = Register(2) - initialize!(r_drms[1:2], drms) - @test ! iszero(observable(r_drms[1:2], Z⊗Z)) +using QuantumSavory.StatesZoo: ZALMSpinPairW, ZALMSpinPair, SingleRailMidSwapBellW, SingleRailMidSwapBell, DualRailMidSwapBellW, DualRailMidSwapBell +using QuantumOpticsBase + +zalmW = ZALMSpinPairW(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) +zalm = ZALMSpinPair(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) +srmsW = SingleRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) +srms = SingleRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) +drmsW = DualRailMidSwapBellW(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) +drms = DualRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) + +r_zalmW = Register(2) +initialize!(r_zalmW[1:2], zalmW) +@test ! iszero(observable(r_zalmW[1:2], Z⊗Z)) + +r_zalm = Register(2) +initialize!(r_zalm[1:2], zalm) +@test ! iszero(observable(r_zalm[1:2], Z⊗Z)) + +r_srmsW = Register(2) +initialize!(r_srmsW[1:2], srmsW) +@test ! iszero(observable(r_srmsW[1:2], Z⊗Z)) + +r_srms = Register(2) +initialize!(r_srms[1:2], srms) +@test ! iszero(observable(r_srms[1:2], Z⊗Z)) + +r_drmsW = Register(2) +initialize!(r_drmsW[1:2], drmsW) +@test ! iszero(observable(r_drmsW[1:2], Z⊗Z)) + +r_drms = Register(2) +initialize!(r_drms[1:2], drms) +@test ! iszero(observable(r_drms[1:2], Z⊗Z)) @test tr(zalm) ≈ tr(express(zalm)) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index 74f11fb9..5a0a9388 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -2,157 +2,157 @@ using QuantumSavory: tag_types using QuantumSavory.ProtocolZoo: EntanglementCounterpart - function strip_id(query_result) - return (;slot=query_result.slot, tag=query_result.tag) - end - - strip_id(::Nothing) = nothing - - function f() - - ## - @test tag_types.SymbolIntInt(:symbol1, 4, 5) == Tag(:symbol1, 4, 5) - - r = Register(10) - tag!(r[1], :symbol1, 2, 3) - tag!(r[2], :symbol1, 4, 5) - tag!(r[3], :symbol1, 4, 1) - tag!(r[5], Int, 4, 5) - - @test Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3) - @test strip_id(query(r, :symbol1, 4, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) - @test strip_id(query(r, :symbol1, 4, 5)) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) - @test strip_id(query(r, :symbol1, ❓, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order - @test query(r, :symbol2, ❓, ❓) == nothing - @test strip_id(query(r, Int, 4, 5)) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) - @test query(r, Float32, 4, 5) == nothing - @test query(r, Int, 4, >(5)) == nothing - @test strip_id(query(r, Int, 4, <(6))) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) - - @test strip_id.(queryall(r, :symbol1, ❓, ❓)) == [(slot=r[3], tag=Tag(:symbol1, 4, 1)), (slot=r[2], tag=Tag(:symbol1, 4, 5)), (slot=r[1], tag=Tag(:symbol1, 2, 3))] # filo by default - @test isempty(queryall(r, :symbol2, ❓, ❓)) - - @test strip_id(query(r[2], Tag(:symbol1, 4, 5))) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) - @test strip_id.(queryall(r[2], Tag(:symbol1, 4, 5))) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] - @test strip_id(query(r[2], :symbol1, 4, 5)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) - @test strip_id.(queryall(r[2], :symbol1, 4, 5)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] - - @test strip_id(query(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) - @test strip_id.(queryall(r[2], :symbol1, 4, ❓)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] - - @test strip_id(querydelete!(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) - @test querydelete!(r[2], :symbol1, 4, ❓) === nothing - @test strip_id(querydelete!(r[3], :symbol1, 4, ❓)) == (slot=r[3], tag=Tag(:symbol1, 4, 1)) - - ## - # tests for fifo and filo order queries (default is filo) - # for RegRefs - - reg = Register(5) - tag!(reg[3], EntanglementCounterpart, 1, 10) - tag!(reg[3], EntanglementCounterpart, 2, 21) - tag!(reg[3], EntanglementCounterpart, 3, 30) - tag!(reg[3], EntanglementCounterpart, 2, 22) - tag!(reg[3], EntanglementCounterpart, 1, 10) - tag!(reg[3], EntanglementCounterpart, 6, 60) - tag!(reg[3], EntanglementCounterpart, 2, 23) - tag!(reg[3], EntanglementCounterpart, 1, 10) - - @test query(reg[3], EntanglementCounterpart, 1, 11) === nothing - @test strip_id(query(reg[3], EntanglementCounterpart, 1, 10)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) - @test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) - @test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) - @test query(reg[3], EntanglementCounterpart, 1, 10; filo=true).id > query(reg[3], EntanglementCounterpart, 1, 10; filo=false).id - @test query(reg[3], EntanglementCounterpart, 2, ❓; filo=true).tag[3] == 23 - @test query(reg[3], EntanglementCounterpart, 2, ❓; filo=false).tag[3] == 21 - - @test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) - @test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,21)) - @test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) - - @test queryall(reg, EntanglementCounterpart, 1, 11) == [] - default_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10)] - @test default_ids == sort(default_ids, rev=true) - fifo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false)] - @test fifo_ids == sort(fifo_ids) - filo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true)] - @test filo_ids == default_ids - - ## - # tests for fifo and filo order queries (default is filo) - # for Register - - reg = Register(5) - for i in 2:4 - tag!(reg[i], EntanglementCounterpart, 1, 10+i) - tag!(reg[i], EntanglementCounterpart, 2, 20+i) - tag!(reg[i], EntanglementCounterpart, 3, 30+i) - tag!(reg[i], EntanglementCounterpart, 2, 120+i) - tag!(reg[i], EntanglementCounterpart, 1, 110+i) - tag!(reg[i], EntanglementCounterpart, 6, 60+i) - tag!(reg[i], EntanglementCounterpart, 2, 20+i) - tag!(reg[i], EntanglementCounterpart, 1, 310+i) - end - - @test query(reg, EntanglementCounterpart, 1, 10) === nothing - @test strip_id(query(reg, EntanglementCounterpart, 1, 12)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) - @test query(reg, EntanglementCounterpart, 1, 12) == query(reg, EntanglementCounterpart, ==(1), ==(12)) - @test query(reg, Tag(EntanglementCounterpart, 1, 10)) === nothing - @test strip_id(query(reg, Tag(EntanglementCounterpart, 1, 12))) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) - @test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) - @test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=true)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) - @test query(reg, EntanglementCounterpart, 1, 12; filo=false) == query(reg, EntanglementCounterpart, 1, ==(12); filo=false) - @test query(reg, EntanglementCounterpart, 1, 12; filo=true) == query(reg, EntanglementCounterpart, 1, ==(12); filo=true) - @test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) - @test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=true)) == (slot = reg[4], tag = Tag(EntanglementCounterpart,1,314)) - - default_res = queryall(reg, EntanglementCounterpart, 1, ❓) - default_res_id = [r.id for r in default_res] - @test strip_id.(default_res) == reverse([(slot = reg[i], tag = Tag(EntanglementCounterpart, 1, j+i)) for i in 2:4 for j in (10,110,310)]) - @test default_res_id == reverse(sort(default_res_id)) - filo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) - filo_res_id = [r.id for r in filo_res] - @test strip_id.(filo_res) == strip_id.(default_res) - @test filo_res_id == default_res_id - fifo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) - fifo_res_id = [r.id for r in fifo_res] - @test strip_id.(fifo_res) == reverse(strip_id.(default_res)) - @test fifo_res_id == sort(fifo_res_id) - - @test strip_id.(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] - @test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] - @test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) - @test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] - @test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) - - reg = Register(4) - tag!(reg[1], EntanglementCounterpart, 4, 9) - tag!(reg[1], EntanglementCounterpart, 5, 2) - tag!(reg[1], EntanglementCounterpart, 7, 7) - tag!(reg[1], EntanglementCounterpart, 4, 9) - tag!(reg[1], EntanglementCounterpart, 2, 3) - tag!(reg[1], EntanglementCounterpart, 4, 9) - - @test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3), Tag(EntanglementCounterpart, 4, 9)] - querydelete!(reg[1], EntanglementCounterpart, 4, 9) - @test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] - querydelete!(reg[1], EntanglementCounterpart, 4, 9;filo=false) - @test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] - - ## - # untagging tests - - reg = Register(5) - id1 = tag!(reg[1], :symA, 1, 2) - id2 = tag!(reg[2], :symB, 2, 3) - id3 = tag!(reg[3], :symB, 3, 4) - id3 = tag!(reg[4], :symB, 4, 5) - @test untag!(reg[1], id1).tag == Tag(:symA, 1, 2) - @test untag!(reg, id2).tag == Tag(:symB, 2, 3) - @test_throws "Attempted to delete a nonexistent" untag!(reg, -1) - end - - f() - #using BenchmarkTools - #@benchmark f() +function strip_id(query_result) + return (;slot=query_result.slot, tag=query_result.tag) +end + +strip_id(::Nothing) = nothing + +function f() + +## +@test tag_types.SymbolIntInt(:symbol1, 4, 5) == Tag(:symbol1, 4, 5) + +r = Register(10) +tag!(r[1], :symbol1, 2, 3) +tag!(r[2], :symbol1, 4, 5) +tag!(r[3], :symbol1, 4, 1) +tag!(r[5], Int, 4, 5) + +@test Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3) +@test strip_id(query(r, :symbol1, 4, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) +@test strip_id(query(r, :symbol1, 4, 5)) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) +@test strip_id(query(r, :symbol1, ❓, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order +@test query(r, :symbol2, ❓, ❓) == nothing +@test strip_id(query(r, Int, 4, 5)) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) +@test query(r, Float32, 4, 5) == nothing +@test query(r, Int, 4, >(5)) == nothing +@test strip_id(query(r, Int, 4, <(6))) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) + +@test strip_id.(queryall(r, :symbol1, ❓, ❓)) == [(slot=r[3], tag=Tag(:symbol1, 4, 1)), (slot=r[2], tag=Tag(:symbol1, 4, 5)), (slot=r[1], tag=Tag(:symbol1, 2, 3))] # filo by default +@test isempty(queryall(r, :symbol2, ❓, ❓)) + +@test strip_id(query(r[2], Tag(:symbol1, 4, 5))) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test strip_id.(queryall(r[2], Tag(:symbol1, 4, 5))) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] +@test strip_id(query(r[2], :symbol1, 4, 5)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test strip_id.(queryall(r[2], :symbol1, 4, 5)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] + +@test strip_id(query(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test strip_id.(queryall(r[2], :symbol1, 4, ❓)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] + +@test strip_id(querydelete!(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test querydelete!(r[2], :symbol1, 4, ❓) === nothing +@test strip_id(querydelete!(r[3], :symbol1, 4, ❓)) == (slot=r[3], tag=Tag(:symbol1, 4, 1)) + +## +# tests for fifo and filo order queries (default is filo) +# for RegRefs + +reg = Register(5) +tag!(reg[3], EntanglementCounterpart, 1, 10) +tag!(reg[3], EntanglementCounterpart, 2, 21) +tag!(reg[3], EntanglementCounterpart, 3, 30) +tag!(reg[3], EntanglementCounterpart, 2, 22) +tag!(reg[3], EntanglementCounterpart, 1, 10) +tag!(reg[3], EntanglementCounterpart, 6, 60) +tag!(reg[3], EntanglementCounterpart, 2, 23) +tag!(reg[3], EntanglementCounterpart, 1, 10) + +@test query(reg[3], EntanglementCounterpart, 1, 11) === nothing +@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) +@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) +@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) +@test query(reg[3], EntanglementCounterpart, 1, 10; filo=true).id > query(reg[3], EntanglementCounterpart, 1, 10; filo=false).id +@test query(reg[3], EntanglementCounterpart, 2, ❓; filo=true).tag[3] == 23 +@test query(reg[3], EntanglementCounterpart, 2, ❓; filo=false).tag[3] == 21 + +@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) +@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,21)) +@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓; filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) + +@test queryall(reg, EntanglementCounterpart, 1, 11) == [] +default_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10)] +@test default_ids == sort(default_ids, rev=true) +fifo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false)] +@test fifo_ids == sort(fifo_ids) +filo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true)] +@test filo_ids == default_ids + +## +# tests for fifo and filo order queries (default is filo) +# for Register + +reg = Register(5) +for i in 2:4 + tag!(reg[i], EntanglementCounterpart, 1, 10+i) + tag!(reg[i], EntanglementCounterpart, 2, 20+i) + tag!(reg[i], EntanglementCounterpart, 3, 30+i) + tag!(reg[i], EntanglementCounterpart, 2, 120+i) + tag!(reg[i], EntanglementCounterpart, 1, 110+i) + tag!(reg[i], EntanglementCounterpart, 6, 60+i) + tag!(reg[i], EntanglementCounterpart, 2, 20+i) + tag!(reg[i], EntanglementCounterpart, 1, 310+i) +end + +@test query(reg, EntanglementCounterpart, 1, 10) === nothing +@test strip_id(query(reg, EntanglementCounterpart, 1, 12)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, EntanglementCounterpart, 1, 12) == query(reg, EntanglementCounterpart, ==(1), ==(12)) +@test query(reg, Tag(EntanglementCounterpart, 1, 10)) === nothing +@test strip_id(query(reg, Tag(EntanglementCounterpart, 1, 12))) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, 12; filo=true)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, EntanglementCounterpart, 1, 12; filo=false) == query(reg, EntanglementCounterpart, 1, ==(12); filo=false) +@test query(reg, EntanglementCounterpart, 1, 12; filo=true) == query(reg, EntanglementCounterpart, 1, ==(12); filo=true) +@test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, ❓; filo=true)) == (slot = reg[4], tag = Tag(EntanglementCounterpart,1,314)) + +default_res = queryall(reg, EntanglementCounterpart, 1, ❓) +default_res_id = [r.id for r in default_res] +@test strip_id.(default_res) == reverse([(slot = reg[i], tag = Tag(EntanglementCounterpart, 1, j+i)) for i in 2:4 for j in (10,110,310)]) +@test default_res_id == reverse(sort(default_res_id)) +filo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) +filo_res_id = [r.id for r in filo_res] +@test strip_id.(filo_res) == strip_id.(default_res) +@test filo_res_id == default_res_id +fifo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) +fifo_res_id = [r.id for r in fifo_res] +@test strip_id.(fifo_res) == reverse(strip_id.(default_res)) +@test fifo_res_id == sort(fifo_res_id) + +@test strip_id.(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) +@test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) + +reg = Register(4) +tag!(reg[1], EntanglementCounterpart, 4, 9) +tag!(reg[1], EntanglementCounterpart, 5, 2) +tag!(reg[1], EntanglementCounterpart, 7, 7) +tag!(reg[1], EntanglementCounterpart, 4, 9) +tag!(reg[1], EntanglementCounterpart, 2, 3) +tag!(reg[1], EntanglementCounterpart, 4, 9) + +@test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3), Tag(EntanglementCounterpart, 4, 9)] +querydelete!(reg[1], EntanglementCounterpart, 4, 9) +@test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] +querydelete!(reg[1], EntanglementCounterpart, 4, 9;filo=false) +@test [reg.tag_info[i].tag for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] + +## +# untagging tests + +reg = Register(5) +id1 = tag!(reg[1], :symA, 1, 2) +id2 = tag!(reg[2], :symB, 2, 3) +id3 = tag!(reg[3], :symB, 3, 4) +id3 = tag!(reg[4], :symB, 4, 5) +@test untag!(reg[1], id1).tag == Tag(:symA, 1, 2) +@test untag!(reg, id2).tag == Tag(:symB, 2, 3) +@test_throws "Attempted to delete a nonexistent" untag!(reg, -1) +end + +f() +#using BenchmarkTools +#@benchmark f() end From ae50ea95b58fb3d39c83fa72a815aab9ed5fe8ee Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 11:54:37 +0200 Subject: [PATCH 10/23] re-add setup file --- test/setup_circuitzoo_purification.jl | 22 ++++++++++++++++++++++ test/test_circuitzoo_purification.jl | 19 ------------------- 2 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 test/setup_circuitzoo_purification.jl diff --git a/test/setup_circuitzoo_purification.jl b/test/setup_circuitzoo_purification.jl new file mode 100644 index 00000000..418f520c --- /dev/null +++ b/test/setup_circuitzoo_purification.jl @@ -0,0 +1,22 @@ +using QuantumSavory.CircuitZoo +using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient + +const bell = StabilizerState("XX ZZ") +export bell; +# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, +# however converting to stabilizer state for Clifford simulations +# is not implemented (and can not be done efficiently). + + +# QOptics repr +const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) +const perfect_pair_dm = SProjector(perfect_pair) +const mixed_dm = MixedState(perfect_pair_dm) +noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper + + +# Qclifford repr +const stab_perfect_pair = StabilizerState("XX ZZ") +const stab_perfect_pair_dm = SProjector(stab_perfect_pair) +const stab_mixed_dm = MixedState(stab_perfect_pair_dm) +stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm diff --git a/test/test_circuitzoo_purification.jl b/test/test_circuitzoo_purification.jl index 1d4288b7..637053da 100644 --- a/test/test_circuitzoo_purification.jl +++ b/test/test_circuitzoo_purification.jl @@ -2,25 +2,6 @@ using QuantumSavory.CircuitZoo using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1, Purify3to1, Purify3to1Node, Purify2to1Node, PurifyStringent, StringentHead, StringentBody, PurifyExpedient, PurifyStringentNode, PurifyExpedient -const bell = StabilizerState("XX ZZ") -# or equivalently `const bell = (Z₁⊗Z₁+Z₂⊗Z₂)/√2`, -# however converting to stabilizer state for Clifford simulations -# is not implemented (and can not be done efficiently). - - -# QOptics repr -const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) -const perfect_pair_dm = SProjector(perfect_pair) -const mixed_dm = MixedState(perfect_pair_dm) -noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper - - -# Qclifford repr -const stab_perfect_pair = StabilizerState("XX ZZ") -const stab_perfect_pair_dm = SProjector(stab_perfect_pair) -const stab_mixed_dm = MixedState(stab_perfect_pair_dm) -stab_noisy_pair_func(F) = F*stab_perfect_pair_dm + (1-F)*stab_mixed_dm - @test_throws ArgumentError Purify2to1(:lalala) @test_throws ArgumentError Purify3to1(:lalala, :X) @test_throws ArgumentError Purify2to1Node(:lalala) From bfe6fe4b83672741bd5c1ac6be1503223b786229 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 12:14:21 +0200 Subject: [PATCH 11/23] fix typo --- test/test_circuitzoo_ent_swap.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_circuitzoo_ent_swap.jl b/test/test_circuitzoo_ent_swap.jl index b92a9e8d..11faf92a 100644 --- a/test/test_circuitzoo_ent_swap.jl +++ b/test/test_circuitzoo_ent_swap.jl @@ -1,6 +1,6 @@ @testitem "Circuit Zoo Entanglement Swap" tags=[:circuitzoo_ent_swap] begin using QuantumSavory.CircuitZoo -using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwapusing QuantumSavory +using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap const perfect_pair_stab = StabilizerState("XX ZZ") const perfect_pair = (Z1⊗Z1 + Z2⊗Z2) / sqrt(2) From b22fa82350371c4de990a2f67964c2979fa7faa3 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 12:27:49 +0200 Subject: [PATCH 12/23] Remove GraphsMatching from test_jet --- test/test_jet.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_jet.jl b/test/test_jet.jl index 27a0088a..9f0fe4b1 100644 --- a/test/test_jet.jl +++ b/test/test_jet.jl @@ -16,7 +16,6 @@ rep = report_package("QuantumSavory"; AnyFrameModule(ResumableFunctions), AnyFrameModule(ConcurrentSim), AnyFrameModule(WignerSymbols), - AnyFrameModule(GraphsMatching), AnyFrameModule(JuMP.Containers), AnyFrameModule(SumTypes), )) From 7fb8ba6de32a828c79c3064a2a74afbdd25e48cc Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 16:15:45 +0200 Subject: [PATCH 13/23] Remove GraphsMatching from test/Project.toml --- test/Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index 193d45d1..5d7464c9 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -8,7 +8,6 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" -GraphsMatching = "c3af3a8c-b79e-4b01-bf44-c718d7e0e0d6" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" From 5f8a04f296fe2b6c1ce689560b088f7c659dd016 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 16:41:34 +0200 Subject: [PATCH 14/23] Remove JuMP refs in JET test (already removed from main Project.toml) --- test/Project.toml | 1 - test/test_jet.jl | 1 - 2 files changed, 2 deletions(-) diff --git a/test/Project.toml b/test/Project.toml index 5d7464c9..ce12b7b2 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -11,7 +11,6 @@ Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" -JuMP = "4076af6c-e467-56ae-b986-b466b2749572" JumpProcesses = "ccbc3e58-028d-4f4c-8cd5-9ae44345cda5" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" diff --git a/test/test_jet.jl b/test/test_jet.jl index 9f0fe4b1..52835982 100644 --- a/test/test_jet.jl +++ b/test/test_jet.jl @@ -16,7 +16,6 @@ rep = report_package("QuantumSavory"; AnyFrameModule(ResumableFunctions), AnyFrameModule(ConcurrentSim), AnyFrameModule(WignerSymbols), - AnyFrameModule(JuMP.Containers), AnyFrameModule(SumTypes), )) From 3013fba63b444bb7e2a9cb5a82b24eb1dc69a620 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Sun, 22 Sep 2024 17:11:25 +0200 Subject: [PATCH 15/23] Add dropped using --- test/test_jet.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_jet.jl b/test/test_jet.jl index 52835982..a17594d4 100644 --- a/test/test_jet.jl +++ b/test/test_jet.jl @@ -1,6 +1,6 @@ @testitem "JET" tags=[:jet] begin using JET -using DiffEqBase, Graphs, JumpProcesses, Makie, ResumableFunctions, ConcurrentSim, QuantumOptics, QuantumOpticsBase, QuantumClifford, Symbolics, WignerSymbols +using DiffEqBase, Graphs, JumpProcesses, Makie, ResumableFunctions, ConcurrentSim, QuantumOptics, QuantumOpticsBase, QuantumClifford, Symbolics, WignerSymbols, SumTypes rep = report_package("QuantumSavory"; ignored_modules=( From b41c5bfd230a7c5ecdf561b4a717c00e6e279666 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Tue, 24 Sep 2024 19:06:38 +0200 Subject: [PATCH 16/23] Fix JET tests --- src/ProtocolZoo/switches.jl | 5 ++++- test/Project.toml | 1 + test/test_jet.jl | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ProtocolZoo/switches.jl b/src/ProtocolZoo/switches.jl index 2b1ac824..e8927f37 100644 --- a/src/ProtocolZoo/switches.jl +++ b/src/ProtocolZoo/switches.jl @@ -66,7 +66,7 @@ julia> let function promponas_bruteforce_choice(M,N,backlog,eprobs) # TODO mark as public but unexported @warn "The switch optimization routine is using a random placeholder optimization method due to issues with installing the BlossomV algorithm. Do not rely on this code to validate research results." return randperm(N)[1:M] - # TODO-MATCHING due to the dependence on BlossomV.jl this has trouble installing. See https://github.com/JuliaGraphs/GraphsMatching.jl/issues/14 + #= TODO-MATCHING due to the dependence on BlossomV.jl this has trouble installing. See https://github.com/JuliaGraphs/GraphsMatching.jl/issues/14 best_weight = 0.0 best_assignment = zeros(Int, M) graphs = [complete_graph(i) for i in 1:M] # preallocating them to avoid expensive allocations in the inner loop @@ -91,8 +91,10 @@ function promponas_bruteforce_choice(M,N,backlog,eprobs) # TODO mark as public b end end return found ? best_assignment : nothing + =# end +#= TODO-MATCHING due to the dependence on BlossomV.jl this has trouble installing. See https://github.com/JuliaGraphs/GraphsMatching.jl/issues/14 """ Perform the match of clients in `entangled_nodes` based on matching weights from `backlog`. `g` and `w` are just preallocated buffers. @@ -111,6 +113,7 @@ function match_entangled_pattern(backlog, entangled_nodes, g, w) mate = [(entangled_nodes[i],entangled_nodes[j]) for (i,j) in enumerate(match.mate) if i Date: Tue, 24 Sep 2024 19:31:45 +0200 Subject: [PATCH 17/23] re-add dropped setup file --- test/setup_plotting.jl | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/setup_plotting.jl diff --git a/test/setup_plotting.jl b/test/setup_plotting.jl new file mode 100644 index 00000000..2414d8fa --- /dev/null +++ b/test/setup_plotting.jl @@ -0,0 +1,2 @@ +using Pkg +Pkg.add("GLMakie") From 6f8bec6e809dd5deaf2bd67ef73f52f08426168f Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Wed, 25 Sep 2024 11:47:53 +0200 Subject: [PATCH 18/23] Revert unneeded indents --- test/test_protocolzoo_switch.jl | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/test/test_protocolzoo_switch.jl b/test/test_protocolzoo_switch.jl index bd3b64fd..1e5d4c28 100644 --- a/test/test_protocolzoo_switch.jl +++ b/test/test_protocolzoo_switch.jl @@ -1,16 +1,16 @@ @testitem "ProtocolZoo Switch - SimpleSwitchDiscreteProt" tags=[:protocolzoo_switch] begin - using Revise - using ResumableFunctions - using ConcurrentSim - using QuantumSavory.ProtocolZoo - using Graphs +using Revise +using ResumableFunctions +using ConcurrentSim +using QuantumSavory.ProtocolZoo +using Graphs - if isinteractive() - using Logging - logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) - global_logger(logger) - println("Logger set to debug") - end +if isinteractive() + using Logging + logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) + global_logger(logger) + println("Logger set to debug") +end n = 5 # number of clients m = n-2 # memory slots in switch @@ -42,4 +42,3 @@ #@test abs(observable([res.slot, net[3][res.tag[3]]], X⊗X)) ≈ 1.0 # we are not running an EntanglementTracker so Pauli corrections are not applied #@test abs(observable([res.slot, net[3][res.tag[3]]], Z⊗Z)) ≈ 1.0 # we are not running an EntanglementTracker so Pauli corrections are not applied end -end From 8ad0d30f6b7653b96131667f40952c5401baf1e4 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Wed, 25 Sep 2024 11:49:34 +0200 Subject: [PATCH 19/23] Fix dropped end, add refactor new test file to testitem --- test/test_aqua.jl | 1 + test/test_protocolzoo_cutoffprot.jl | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_aqua.jl b/test/test_aqua.jl index cdcd426c..dc1f8d6d 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -15,3 +15,4 @@ Aqua.test_all(QuantumSavory, @test length(Aqua.Piracy.hunt(QuantumSavory)) == 6 end +end \ No newline at end of file diff --git a/test/test_protocolzoo_cutoffprot.jl b/test/test_protocolzoo_cutoffprot.jl index 1bdfd65c..5dc00dc6 100644 --- a/test/test_protocolzoo_cutoffprot.jl +++ b/test/test_protocolzoo_cutoffprot.jl @@ -1,11 +1,9 @@ -using QuantumSavory +@testitem "ProtocolZoo CutoffProt" tags=[:protocolzoo_cutoffprot] begin using QuantumSavory.ProtocolZoo using ConcurrentSim using ResumableFunctions -using Test - if isinteractive() using Logging logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"","")) @@ -28,4 +26,5 @@ run(sim, 2.0) run(sim, 6.0) @test !isassigned(net[1][1]) -@test isassigned(net[2][1]) \ No newline at end of file +@test isassigned(net[2][1]) +end From 168c8059e7c975ec7129ab4bfa705b43cc3a68a5 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Wed, 25 Sep 2024 11:50:25 +0200 Subject: [PATCH 20/23] run_package_tests with verbose to show file-level breakdown of test results more like current behavior --- test/runtests.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index ad598b72..34a388c0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -18,5 +18,4 @@ function testfilter(tags) end println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREADS = $(Sys.CPU_THREADS)`...") - -@run_package_tests filter=ti->testfilter(ti.tags) \ No newline at end of file +@run_package_tests filter=ti->testfilter(ti.tags) verbose=true From 30afb15dba557bb1934f11d8321a2589d76b52d0 Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Wed, 25 Sep 2024 13:38:13 +0200 Subject: [PATCH 21/23] Need setup files for example tests --- test/test_examples.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_examples.jl b/test/test_examples.jl index ce550a4f..e9bbba30 100644 --- a/test/test_examples.jl +++ b/test/test_examples.jl @@ -7,12 +7,14 @@ end @testitem "Examples - congestionchain" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" + include("setup_plotting.jl") include("../examples/congestionchain/1_visualization.jl") end end @testitem "Examples - firstgenrepeater" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" + include("setup_plotting.jl") include("../examples/firstgenrepeater/1_entangler_example.jl") include("../examples/firstgenrepeater/2_swapper_example.jl") include("../examples/firstgenrepeater/3_purifier_example.jl") @@ -25,6 +27,7 @@ end @testitem "Examples - firstgenrepeater_v2" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" + include("setup_plotting.jl") include("../examples/firstgenrepeater_v2/1_entangler_example.jl") include("../examples/firstgenrepeater_v2/2_swapper_example.jl") end @@ -33,12 +36,14 @@ end @testitem "Examples - simpleswitch" tags=[:examples] begin if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" # TODO-MATCHING due to the dependence on BlossomV.jl this has trouble installing. See https://github.com/JuliaGraphs/GraphsMatching.jl/issues/14 + #include("setup_plotting.jl") #include("../examples/simpleswitch/1_interactive_visualization.jl") end end @safetestset "repeatergrid" begin if get(ENV, "QUANTUMSAVORY_PLOT_TEST","")=="true" + include("setup_plotting.jl") include("../examples/repeatergrid/1a_async_interactive_visualization.jl") include("../examples/repeatergrid/2a_sync_interactive_visualization.jl") end From 253fbe8abaae737a02b40542d66262ac800e91fc Mon Sep 17 00:00:00 2001 From: Bryan Kaperick Date: Wed, 25 Sep 2024 14:07:54 +0200 Subject: [PATCH 22/23] Empty commit: See if CI/Documentation job fail persists --- test/test_aqua.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_aqua.jl b/test/test_aqua.jl index dc1f8d6d..f826deb4 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -15,4 +15,4 @@ Aqua.test_all(QuantumSavory, @test length(Aqua.Piracy.hunt(QuantumSavory)) == 6 end -end \ No newline at end of file +end From 3f3bce4870a06040e5d68f7285617c0e3f6bfe7b Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Fri, 27 Sep 2024 14:38:52 -0400 Subject: [PATCH 23/23] run doctests always (I think the inequality sign was inverted, but it does not matter because we have dropped julia 1.9 anyway) --- test/runtests.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 34a388c0..e28256e0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,9 +7,7 @@ function testfilter(tags) if get(ENV,"QUANTUMSAVORY_PLOT_TEST","")!="true" push!(exclude, :plotting_cairo) push!(exclude, :plotting_gl) - if VERSION >= v"1.9" - push!(exclude, :doctests) - end + push!(exclude, :doctests) end if get(ENV,"JET_TEST","")!="true" push!(exclude, :jet)