From f9cc7acc42bd89e8889a345a0686e3401a7d4dfb Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 17 Jan 2024 06:26:09 -0500 Subject: [PATCH 01/11] Entanglement simulation on a grid with custom predicates --- src/ProtocolZoo/ProtocolZoo.jl | 24 +++-- test/test_entanglement_tracker.jl | 140 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 8 deletions(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 1226a017..2247c127 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -175,7 +175,7 @@ end rounds = prot.rounds while rounds != 0 reg = prot.net[prot.node] - qubit_pair = findswapablequbits(prot.net,prot.node) + qubit_pair = findswapablequbits(prot.net,prot.node, prot.nodeL, prot.nodeR) if isnothing(qubit_pair) isnothing(prot.retry_lock_time) && error("We do not yet support waiting on register to make qubits available") # TODO @yield timeout(prot.sim, prot.retry_lock_time) @@ -212,16 +212,24 @@ end end end -function findswapablequbits(net,node) # TODO parameterize the query predicates and the findmin/findmax +function findswapablequbits(net, node, pred_low, pred_high) # TODO parameterize the query predicates and the findmin/findmax reg = net[node] + + if typeof(pred_low) == Wildcard + l = <(node) + r = >(node) + else + l(x) = pred_low(net, node, x) + h(x) = pred_high(net, node, x) + end - leftnodes = queryall(reg, EntanglementCounterpart, <(node), ❓; locked=false, assigned=true) - rightnodes = queryall(reg, EntanglementCounterpart, >(node), ❓; locked=false, assigned=true) + low_nodes = queryall(reg, EntanglementCounterpart, l, ❓; locked=false, assigned=true) + high_nodes = queryall(reg, EntanglementCounterpart, h, ❓; locked=false, assigned=true) - (isempty(leftnodes) || isempty(rightnodes)) && return nothing - _, il = findmin(n->n.tag[2], leftnodes) # TODO make [2] into a nice named property - _, ir = findmax(n->n.tag[2], rightnodes) - return leftnodes[il], rightnodes[ir] + (isempty(low_nodes) || isempty(high_nodes)) && return nothing + _, il = findmin(n->n.tag[2], low_nodes) # TODO make [2] into a nice named property + _, ih = findmax(n->n.tag[2], high_nodes) + return low_nodes[il], high_nodes[ih] end diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index 3698fd06..9aacf953 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -114,3 +114,143 @@ for i in 1:30, n in 2:30 @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 end + + +# Tests with 2d Grid + +using Revise +using QuantumSavory +using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker +using Graphs +using Test +using ResumableFunctions +using ConcurrentSim + +using Logging +logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black, "", "")) +global_logger(logger) + +## Custom Predicates +function top_left(net, node, x) + n = sqrt(size(net.graph)[1]) # grid size + a = (node ÷ n) + 1 # row number + for i in 1:a-1 + if x == (i-1)*n + i + return true + end + end + return false +end + +function bottom_right(net, node, x) + n = sqrt(size(net.graph)[1]) # grid size + a = (node ÷ n) + 1 # row number + for i in a+1:n + if x == (i-1)*n + i + return true + end + end + return false +end + +## Simulation + +#without entanglement tracker +for i in 1:10 + graph = grid([4, 4]) + add_edge!(graph, 1, 6) + add_edge!(graph, 6, 11) + add_edge!(graph, 11, 16) + + net = RegisterNet(graph, [Register(3) for i in 1:16]) + sim = get_time_tracker(net) + + + entangler1 = EntanglerProt(sim, net, 1, 6; rounds=1) + @process entangler1() + run(sim, 20) + + @test net[1].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] + + + entangler2 = EntanglerProt(sim, net, 6, 11; rounds=1) + @process entangler2() + run(sim, 40) + entangler3 = EntanglerProt(sim, net, 11, 16; rounds=1) + @process entangler3() + run(sim, 60) + + @test net[1].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] + @test net[6].tags == [[Tag(EntanglementCounterpart, 1, 1)],[Tag(EntanglementCounterpart, 11, 1)],[]] + @test net[11].tags == [[Tag(EntanglementCounterpart, 6, 2)],[Tag(EntanglementCounterpart, 16, 1)], []] + @test net[16].tags == [[Tag(EntanglementCounterpart, 11, 2)],[],[]] + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + + + swapper2 = SwapperProt(sim, net, 6; nodeL=top_left, nodeR=bottom_right, rounds=1) + swapper3 = SwapperProt(sim, net, 11; nodeL=top_left, nodeR=bottom_right, 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].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] + @test net[6].tags == [[Tag(EntanglementHistory, 1, 1, 11, 1, 2)],[Tag(EntanglementHistory, 11, 1, 1, 1, 1)],[]] + @test net[11].tags == [[Tag(EntanglementHistory, 6, 2, 16, 1, 2)],[Tag(EntanglementHistory, 16, 1, 6, 2, 1)], []] + @test net[16].tags == [[Tag(EntanglementCounterpart, 11, 2)],[],[]] + + @test isassigned(net[1][1]) && isassigned(net[16][1]) + @test !isassigned(net[6][1]) && !isassigned(net[11][1]) + @test !isassigned(net[6][2]) && !isassigned(net[11][2]) + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + +end + +# with entanglement tracker +for n in 4:10 + graph = grid([n,n]) + + diag_pairs = [] + diag_nodes = [] + reg_num = 1 # starting register + for i in 1:n-1 # a grid with n nodes has n-1 pairs of diagonal nodes + push!(diag_pairs, (reg_num, reg_num+n+1)) + push!(diag_nodes, reg_num) + reg_num += n + 1 + end + push!(diag_nodes, n^2) + + for (src, dst) in diag_pairs # need edges down the diagonal to establish cchannels and qchannels between the diagonal nodes + add_edge!(graph, src, dst) + end + + net = RegisterNet(graph, [Register(8) for i in 1:n^2]) + + sim = get_time_tracker(net) + + for (src, dst) in diag_pairs + eprot = EntanglerProt(sim, net, src, dst; rounds=1, randomize=true) + @process eprot() + end + + for i in 2:n-1 + swapper = SwapperProt(sim, net, diag_nodes[i]; nodeL = top_left, nodeR = bottom_right, rounds = 1) + @process swapper() + end + + for v in diag_nodes + tracker = EntanglementTracker(sim, net, v) + @process tracker() + end + + run(sim, 200) + + q1 = query(net[1], EntanglementCounterpart, diag_nodes[n], ❓) + q2 = query(net[diag_nodes[n]], EntanglementCounterpart, 1, ❓) + @test q1.tag[2] == diag_nodes[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 From 962f5d6139afc9bfe4ef03658044d210c5043b57 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 17 Jan 2024 06:34:00 -0500 Subject: [PATCH 02/11] correct typo, test cleanup --- src/ProtocolZoo/ProtocolZoo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 2247c127..99c3a34f 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -217,7 +217,7 @@ function findswapablequbits(net, node, pred_low, pred_high) # TODO parameterize if typeof(pred_low) == Wildcard l = <(node) - r = >(node) + h = >(node) else l(x) = pred_low(net, node, x) h(x) = pred_high(net, node, x) From 5b726da0a03dbff5eabe774d40dc09617a70e059 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 17 Jan 2024 06:36:51 -0500 Subject: [PATCH 03/11] update test_entanglement_tracker.jl --- test/test_entanglement_tracker.jl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index 9aacf953..f8681907 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -118,18 +118,6 @@ end # Tests with 2d Grid -using Revise -using QuantumSavory -using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker -using Graphs -using Test -using ResumableFunctions -using ConcurrentSim - -using Logging -logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black, "", "")) -global_logger(logger) - ## Custom Predicates function top_left(net, node, x) n = sqrt(size(net.graph)[1]) # grid size From 7d1b3fcccff17f531237ffec13238486be9c29fd Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 17 Jan 2024 12:32:42 -0500 Subject: [PATCH 04/11] temprorary fix for SumTypes --- src/queries.jl | 4 ++-- src/tags.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 1af825ff..9d58530e 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -257,8 +257,8 @@ for (tagsymbol, tagvariant) in pairs(tag_types) sig_wild = collect(sig) sig_wild[idx] .= Union{Wildcard,Function} argssig_wild = [:($a::$t) for (a,t) in zip(args, sig_wild)] - wild_checks = [:(isa($(args[i]),Wildcard) || $(args[i])(tag.data[$i])) for i in idx] - nonwild_checks = [:(tag.data[$i]==$(args[i])) for i in complement_idx] + wild_checks = [:(isa($(args[i]),Wildcard) || $(args[i])(tag[$i])) for i in idx] + nonwild_checks = [:(tag[$i]==$(args[i])) for i in complement_idx] newmethod_reg = quote function query(reg::Register, $(argssig_wild...), ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing) where {allB} res = NamedTuple{(:slot, :tag), Tuple{RegRef, Tag}}[] for (reg_idx, tags) in enumerate(reg.tags) diff --git a/src/tags.jl b/src/tags.jl index cb9e3de3..8af53368 100644 --- a/src/tags.jl +++ b/src/tags.jl @@ -24,9 +24,9 @@ end See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" const tag_types = Tag' -Base.getindex(tag::Tag, i::Int) = tag.data[i] -Base.length(tag::Tag) = length(tag.data.data) -Base.iterate(tag::Tag, state=1) = state > length(tag) ? nothing : (tag[state],state+1) +Base.getindex(tag::Tag, i::Int) = SumTypes.unwrap(tag)[i] +Base.length(tag::Tag) = length(SumTypes.unwrap(tag).data) +Base.iterate(tag::Tag, state=1) = state > length(tag) ? nothing : (SumTypes.unwrap(tag)[state],state+1) function SumTypes.show_sumtype(io::IO, x::Tag) data = SumTypes.unwrap(x) From 1f981237befed3f99ecaa714d342a0e4343f5f76 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 17 Jan 2024 13:49:29 -0500 Subject: [PATCH 05/11] a better generalization --- src/ProtocolZoo/ProtocolZoo.jl | 9 ++------- test/test_entanglement_tracker.jl | 13 +++++++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 99c3a34f..c2c2da00 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -215,13 +215,8 @@ end function findswapablequbits(net, node, pred_low, pred_high) # TODO parameterize the query predicates and the findmin/findmax reg = net[node] - if typeof(pred_low) == Wildcard - l = <(node) - h = >(node) - else - l(x) = pred_low(net, node, x) - h(x) = pred_high(net, node, x) - end + l = typeof(pred_low) == Wildcard ? <(node) : pred_low + h = typeof(pred_high) == Wildcard ? >(node) : pred_high low_nodes = queryall(reg, EntanglementCounterpart, l, ❓; locked=false, assigned=true) high_nodes = queryall(reg, EntanglementCounterpart, h, ❓; locked=false, assigned=true) diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index f8681907..4adef175 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -175,9 +175,12 @@ for i in 1:10 @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - - swapper2 = SwapperProt(sim, net, 6; nodeL=top_left, nodeR=bottom_right, rounds=1) - swapper3 = SwapperProt(sim, net, 11; nodeL=top_left, nodeR=bottom_right, rounds=1) + l1(x) = top_left(net, 6, x) + h1(x) = bottom_right(net, 6, x) + swapper2 = SwapperProt(sim, net, 6; nodeL=l1, nodeR=h1, rounds=1) + l2(x) = top_left(net, 11, x) + h2(x) = bottom_right(net, 11, x) + swapper3 = SwapperProt(sim, net, 11; nodeL=l2, nodeR=h2, rounds=1) @process swapper2() @process swapper3() run(sim, 80) @@ -224,7 +227,9 @@ for n in 4:10 end for i in 2:n-1 - swapper = SwapperProt(sim, net, diag_nodes[i]; nodeL = top_left, nodeR = bottom_right, rounds = 1) + l(x) = top_left(net, diag_nodes[i], x) + h(x) = bottom_right(net, diag_nodes[i], x) + swapper = SwapperProt(sim, net, diag_nodes[i]; nodeL = l, nodeR = h, rounds = 1) @process swapper() end From f9c5f90285a4492ac1993ad72dab536d771b0a7d Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 31 Jan 2024 15:10:20 -0500 Subject: [PATCH 06/11] apply changes from code review --- .../firstgenrepeater_v2/2_swapper_example.jl | 2 +- src/ProtocolZoo/ProtocolZoo.jl | 19 +-- test/test_entanglement_tracker.jl | 139 +---------------- test/test_entanglement_tracker_grid.jl | 145 ++++++++++++++++++ 4 files changed, 157 insertions(+), 148 deletions(-) create mode 100644 test/test_entanglement_tracker_grid.jl diff --git a/examples/firstgenrepeater_v2/2_swapper_example.jl b/examples/firstgenrepeater_v2/2_swapper_example.jl index 4425f53f..e0e4a23c 100644 --- a/examples/firstgenrepeater_v2/2_swapper_example.jl +++ b/examples/firstgenrepeater_v2/2_swapper_example.jl @@ -20,7 +20,7 @@ for (;src, dst) in edges(network) @process eprot() end for node in vertices(network) - sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeR = >(node)) + sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node)) @process sprot() end diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index c2c2da00..bc88fd6a 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -146,17 +146,17 @@ A protocol, running at a given node, that finds swappable entangled pairs and pe $FIELDS """ -@kwdef struct SwapperProt{L,R,LT} <: AbstractProtocol where {L<:Union{Int,<:Function,Wildcard}, R<:Union{Int,<:Function,Wildcard}, LT<:Union{Float64,Nothing}} +@kwdef struct SwapperProt{NL,NH,LT} <: AbstractProtocol where {NL<:Union{Int,<:Function,Wildcard}, NH<:Union{Int,<:Function,Wildcard}, LT<:Union{Float64,Nothing}} """time-and-schedule-tracking instance from `ConcurrentSim`""" sim::Simulation """a network graph of registers""" net::RegisterNet """the vertex of the node where swapping is happening""" node::Int - """the vertex of one of the remote nodes (or a predicate function or a wildcard)""" - nodeL::L = ❓ - """the vertex of the other remote node (or a predicate function or a wildcard)""" - nodeR::R = ❓ + """the vertex of one of the remote nodes that is lower than the current node value (or a predicate function or a wildcard)""" + nodeL::NL = ❓ + """the vertex of the other remote node that is higher than the current node value (or a predicate function or a wildcard)""" + nodeH::NH = ❓ """fixed "busy time" duration immediately before starting entanglement generation attempts""" local_busy_time::Float64 = 0.0 # TODO the gates should have that busy time built in """how long to wait before retrying to lock qubits if no qubits are available (`nothing` for queuing up and waiting)""" @@ -175,7 +175,7 @@ end rounds = prot.rounds while rounds != 0 reg = prot.net[prot.node] - qubit_pair = findswapablequbits(prot.net,prot.node, prot.nodeL, prot.nodeR) + qubit_pair = findswapablequbits(prot.net,prot.node, prot.nodeL, prot.nodeH) if isnothing(qubit_pair) isnothing(prot.retry_lock_time) && error("We do not yet support waiting on register to make qubits available") # TODO @yield timeout(prot.sim, prot.retry_lock_time) @@ -214,12 +214,9 @@ end function findswapablequbits(net, node, pred_low, pred_high) # TODO parameterize the query predicates and the findmin/findmax reg = net[node] - - l = typeof(pred_low) == Wildcard ? <(node) : pred_low - h = typeof(pred_high) == Wildcard ? >(node) : pred_high - low_nodes = queryall(reg, EntanglementCounterpart, l, ❓; locked=false, assigned=true) - high_nodes = queryall(reg, EntanglementCounterpart, h, ❓; locked=false, assigned=true) + low_nodes = queryall(reg, EntanglementCounterpart, pred_low, ❓; locked=false, assigned=true) + high_nodes = queryall(reg, EntanglementCounterpart, pred_high, ❓; locked=false, assigned=true) (isempty(low_nodes) || isempty(high_nodes)) && return nothing _, il = findmin(n->n.tag[2], low_nodes) # TODO make [2] into a nice named property diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index 4adef175..ab22d07f 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -46,8 +46,8 @@ for i in 1:10 @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - swapper2 = SwapperProt(sim, net, 2; rounds=1) - swapper3 = SwapperProt(sim, net, 3; rounds=1) + swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), rounds = 1) + swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), rounds = 1) @process swapper2() @process swapper3() run(sim, 80) @@ -102,7 +102,7 @@ for i in 1:30, n in 2:30 @process eprot() end for j in 2:n-1 - swapper = SwapperProt(sim, net, j; rounds=1) + swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), rounds = 1) @process swapper() end run(sim, 200) @@ -114,136 +114,3 @@ for i in 1:30, n in 2:30 @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 end - - -# Tests with 2d Grid - -## Custom Predicates -function top_left(net, node, x) - n = sqrt(size(net.graph)[1]) # grid size - a = (node ÷ n) + 1 # row number - for i in 1:a-1 - if x == (i-1)*n + i - return true - end - end - return false -end - -function bottom_right(net, node, x) - n = sqrt(size(net.graph)[1]) # grid size - a = (node ÷ n) + 1 # row number - for i in a+1:n - if x == (i-1)*n + i - return true - end - end - return false -end - -## Simulation - -#without entanglement tracker -for i in 1:10 - graph = grid([4, 4]) - add_edge!(graph, 1, 6) - add_edge!(graph, 6, 11) - add_edge!(graph, 11, 16) - - net = RegisterNet(graph, [Register(3) for i in 1:16]) - sim = get_time_tracker(net) - - - entangler1 = EntanglerProt(sim, net, 1, 6; rounds=1) - @process entangler1() - run(sim, 20) - - @test net[1].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] - - - entangler2 = EntanglerProt(sim, net, 6, 11; rounds=1) - @process entangler2() - run(sim, 40) - entangler3 = EntanglerProt(sim, net, 11, 16; rounds=1) - @process entangler3() - run(sim, 60) - - @test net[1].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] - @test net[6].tags == [[Tag(EntanglementCounterpart, 1, 1)],[Tag(EntanglementCounterpart, 11, 1)],[]] - @test net[11].tags == [[Tag(EntanglementCounterpart, 6, 2)],[Tag(EntanglementCounterpart, 16, 1)], []] - @test net[16].tags == [[Tag(EntanglementCounterpart, 11, 2)],[],[]] - - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - - l1(x) = top_left(net, 6, x) - h1(x) = bottom_right(net, 6, x) - swapper2 = SwapperProt(sim, net, 6; nodeL=l1, nodeR=h1, rounds=1) - l2(x) = top_left(net, 11, x) - h2(x) = bottom_right(net, 11, x) - swapper3 = SwapperProt(sim, net, 11; nodeL=l2, nodeR=h2, 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].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] - @test net[6].tags == [[Tag(EntanglementHistory, 1, 1, 11, 1, 2)],[Tag(EntanglementHistory, 11, 1, 1, 1, 1)],[]] - @test net[11].tags == [[Tag(EntanglementHistory, 6, 2, 16, 1, 2)],[Tag(EntanglementHistory, 16, 1, 6, 2, 1)], []] - @test net[16].tags == [[Tag(EntanglementCounterpart, 11, 2)],[],[]] - - @test isassigned(net[1][1]) && isassigned(net[16][1]) - @test !isassigned(net[6][1]) && !isassigned(net[11][1]) - @test !isassigned(net[6][2]) && !isassigned(net[11][2]) - - @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - -end - -# with entanglement tracker -for n in 4:10 - graph = grid([n,n]) - - diag_pairs = [] - diag_nodes = [] - reg_num = 1 # starting register - for i in 1:n-1 # a grid with n nodes has n-1 pairs of diagonal nodes - push!(diag_pairs, (reg_num, reg_num+n+1)) - push!(diag_nodes, reg_num) - reg_num += n + 1 - end - push!(diag_nodes, n^2) - - for (src, dst) in diag_pairs # need edges down the diagonal to establish cchannels and qchannels between the diagonal nodes - add_edge!(graph, src, dst) - end - - net = RegisterNet(graph, [Register(8) for i in 1:n^2]) - - sim = get_time_tracker(net) - - for (src, dst) in diag_pairs - eprot = EntanglerProt(sim, net, src, dst; rounds=1, randomize=true) - @process eprot() - end - - for i in 2:n-1 - l(x) = top_left(net, diag_nodes[i], x) - h(x) = bottom_right(net, diag_nodes[i], x) - swapper = SwapperProt(sim, net, diag_nodes[i]; nodeL = l, nodeR = h, rounds = 1) - @process swapper() - end - - for v in diag_nodes - tracker = EntanglementTracker(sim, net, v) - @process tracker() - end - - run(sim, 200) - - q1 = query(net[1], EntanglementCounterpart, diag_nodes[n], ❓) - q2 = query(net[diag_nodes[n]], EntanglementCounterpart, 1, ❓) - @test q1.tag[2] == diag_nodes[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_entanglement_tracker_grid.jl b/test/test_entanglement_tracker_grid.jl new file mode 100644 index 00000000..9d96f754 --- /dev/null +++ b/test/test_entanglement_tracker_grid.jl @@ -0,0 +1,145 @@ +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 + +## Custom Predicates +function top_left(net, node, x) + n = sqrt(size(net.graph)[1]) # grid size + a = (node ÷ n) + 1 # row number + for i in 1:a-1 + if x == (i-1)*n + i + return true + end + end + return false +end + +function bottom_right(net, node, x) + n = sqrt(size(net.graph)[1]) # grid size + a = (node ÷ n) + 1 # row number + for i in a+1:n + if x == (i-1)*n + i + return true + end + end + return false +end + +## Simulation + +#without entanglement tracker +for i in 1:10 + graph = grid([4, 4]) + add_edge!(graph, 1, 6) + add_edge!(graph, 6, 11) + add_edge!(graph, 11, 16) + + net = RegisterNet(graph, [Register(3) for i in 1:16]) + sim = get_time_tracker(net) + + + entangler1 = EntanglerProt(sim, net, 1, 6; rounds=1) + @process entangler1() + run(sim, 20) + + @test net[1].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] + + + entangler2 = EntanglerProt(sim, net, 6, 11; rounds=1) + @process entangler2() + run(sim, 40) + entangler3 = EntanglerProt(sim, net, 11, 16; rounds=1) + @process entangler3() + run(sim, 60) + + @test net[1].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] + @test net[6].tags == [[Tag(EntanglementCounterpart, 1, 1)],[Tag(EntanglementCounterpart, 11, 1)],[]] + @test net[11].tags == [[Tag(EntanglementCounterpart, 6, 2)],[Tag(EntanglementCounterpart, 16, 1)], []] + @test net[16].tags == [[Tag(EntanglementCounterpart, 11, 2)],[],[]] + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + + l1(x) = top_left(net, 6, x) + h1(x) = bottom_right(net, 6, x) + swapper2 = SwapperProt(sim, net, 6; nodeL=l1, nodeH=h1, rounds=1) + l2(x) = top_left(net, 11, x) + h2(x) = bottom_right(net, 11, x) + swapper3 = SwapperProt(sim, net, 11; nodeL=l2, nodeH=h2, 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].tags == [[Tag(EntanglementCounterpart, 6, 1)],[],[]] + @test net[6].tags == [[Tag(EntanglementHistory, 1, 1, 11, 1, 2)],[Tag(EntanglementHistory, 11, 1, 1, 1, 1)],[]] + @test net[11].tags == [[Tag(EntanglementHistory, 6, 2, 16, 1, 2)],[Tag(EntanglementHistory, 16, 1, 6, 2, 1)], []] + @test net[16].tags == [[Tag(EntanglementCounterpart, 11, 2)],[],[]] + + @test isassigned(net[1][1]) && isassigned(net[16][1]) + @test !isassigned(net[6][1]) && !isassigned(net[11][1]) + @test !isassigned(net[6][2]) && !isassigned(net[11][2]) + + @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false + +end + +# with entanglement tracker +for n in 4:10 + graph = grid([n,n]) + + diag_pairs = [] + diag_nodes = [] + reg_num = 1 # starting register + for i in 1:n-1 # a grid with n nodes has n-1 pairs of diagonal nodes + push!(diag_pairs, (reg_num, reg_num+n+1)) + push!(diag_nodes, reg_num) + reg_num += n + 1 + end + push!(diag_nodes, n^2) + + for (src, dst) in diag_pairs # need edges down the diagonal to establish cchannels and qchannels between the diagonal nodes + add_edge!(graph, src, dst) + end + + net = RegisterNet(graph, [Register(8) for i in 1:n^2]) + + sim = get_time_tracker(net) + + for (src, dst) in diag_pairs + eprot = EntanglerProt(sim, net, src, dst; rounds=1, randomize=true) + @process eprot() + end + + for i in 2:n-1 + l(x) = top_left(net, diag_nodes[i], x) + h(x) = bottom_right(net, diag_nodes[i], x) + swapper = SwapperProt(sim, net, diag_nodes[i]; nodeL = l, nodeH = h, rounds = 1) + @process swapper() + end + + for v in diag_nodes + tracker = EntanglementTracker(sim, net, v) + @process tracker() + end + + run(sim, 200) + + q1 = query(net[1], EntanglementCounterpart, diag_nodes[n], ❓) + q2 = query(net[diag_nodes[n]], EntanglementCounterpart, 1, ❓) + @test q1.tag[2] == diag_nodes[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 \ No newline at end of file From b127a3edae678d93d3933f150d25db8531049025 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 5 Feb 2024 15:45:41 -0500 Subject: [PATCH 07/11] parameterize not only predicate but also filter that picks out of all predicate-true results --- .../firstgenrepeater_v2/2_swapper_example.jl | 2 +- src/ProtocolZoo/ProtocolZoo.jl | 23 ++++++++++++------- test/test_entanglement_tracker.jl | 6 ++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/examples/firstgenrepeater_v2/2_swapper_example.jl b/examples/firstgenrepeater_v2/2_swapper_example.jl index e0e4a23c..0301c31b 100644 --- a/examples/firstgenrepeater_v2/2_swapper_example.jl +++ b/examples/firstgenrepeater_v2/2_swapper_example.jl @@ -20,7 +20,7 @@ for (;src, dst) in edges(network) @process eprot() end for node in vertices(network) - sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node)) + sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node), chooseL = argmin, chooseH = argmax) @process sprot() end diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index bc88fd6a..bd964a46 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -138,6 +138,9 @@ end end end +function random_index(arr) + return rand(keys(arr)) +end """ $TYPEDEF @@ -146,17 +149,21 @@ A protocol, running at a given node, that finds swappable entangled pairs and pe $FIELDS """ -@kwdef struct SwapperProt{NL,NH,LT} <: AbstractProtocol where {NL<:Union{Int,<:Function,Wildcard}, NH<:Union{Int,<:Function,Wildcard}, LT<:Union{Float64,Nothing}} +@kwdef struct SwapperProt{NL,NH,CL,CH,LT} <: AbstractProtocol where {NL<:Union{Int,<:Function,Wildcard}, NH<:Union{Int,<:Function,Wildcard}, CL<:Function, CH<:Function, LT<:Union{Float64,Nothing}} """time-and-schedule-tracking instance from `ConcurrentSim`""" sim::Simulation """a network graph of registers""" net::RegisterNet """the vertex of the node where swapping is happening""" node::Int - """the vertex of one of the remote nodes that is lower than the current node value (or a predicate function or a wildcard)""" + """the vertex of one of the remote nodes for the swap, arbitrarily refered to as the "low" node (or a predicate function or a wildcard); if you are working on a repeater chain, a good choice is `<(current_node)`, i.e. any node to the "left" of the current node""" nodeL::NL = ❓ - """the vertex of the other remote node that is higher than the current node value (or a predicate function or a wildcard)""" - nodeH::NH = ❓ + """the vertex of the other remote node for the swap, the "high" counterpart of `nodeL`; if you are working on a repeater chain, a good choice is `>(current_node)`, i.e. any node to the "right" of the current node""" + nodeH::NH = ❓ # TODO consider changing the default to random + """the `nodeL` predicate can return many positive candidates; `chooseL` picks one of them (by index into the array of filtered `nodeL` results), defaults to a random pick `arr->rand(keys(arr))`; if you are working on a repeater chain a good choice is `argmin`, i.e. the node furthest to the "left" """ + chooseL::CL = random_index + """the `nodeH` counterpart for `chooseH`; if you are working on a repeater chain a good choice is `argmax`, i.e. the node furthest to the "right" """ + chooseH::CH = random_index """fixed "busy time" duration immediately before starting entanglement generation attempts""" local_busy_time::Float64 = 0.0 # TODO the gates should have that busy time built in """how long to wait before retrying to lock qubits if no qubits are available (`nothing` for queuing up and waiting)""" @@ -175,7 +182,7 @@ end rounds = prot.rounds while rounds != 0 reg = prot.net[prot.node] - qubit_pair = findswapablequbits(prot.net,prot.node, prot.nodeL, prot.nodeH) + qubit_pair = findswapablequbits(prot.net, prot.node, prot.nodeL, prot.nodeH, prot.chooseL, prot.chooseH) if isnothing(qubit_pair) isnothing(prot.retry_lock_time) && error("We do not yet support waiting on register to make qubits available") # TODO @yield timeout(prot.sim, prot.retry_lock_time) @@ -212,15 +219,15 @@ end end end -function findswapablequbits(net, node, pred_low, pred_high) # TODO parameterize the query predicates and the findmin/findmax +function findswapablequbits(net, node, pred_low, pred_high, choose_low, choose_high) # TODO parameterize the query predicates and the findmin/findmax reg = net[node] low_nodes = queryall(reg, EntanglementCounterpart, pred_low, ❓; locked=false, assigned=true) high_nodes = queryall(reg, EntanglementCounterpart, pred_high, ❓; locked=false, assigned=true) (isempty(low_nodes) || isempty(high_nodes)) && return nothing - _, il = findmin(n->n.tag[2], low_nodes) # TODO make [2] into a nice named property - _, ih = findmax(n->n.tag[2], high_nodes) + _, il = choose_low(n->n.tag[2], low_nodes) # TODO make [2] into a nice named property + _, ih = choose_high(n->n.tag[2], high_nodes) return low_nodes[il], high_nodes[ih] end diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index ab22d07f..b75ac758 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -46,8 +46,8 @@ for i in 1:10 @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false - swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), rounds = 1) - swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), rounds = 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) @@ -102,7 +102,7 @@ for i in 1:30, n in 2:30 @process eprot() end for j in 2:n-1 - swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), rounds = 1) + swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) @process swapper() end run(sim, 200) From cfe1f31d92517fe4f1c05142902caa379d581a9a Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 5 Feb 2024 15:50:00 -0500 Subject: [PATCH 08/11] typo --- src/ProtocolZoo/ProtocolZoo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index bd964a46..67ee086b 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -156,7 +156,7 @@ $FIELDS net::RegisterNet """the vertex of the node where swapping is happening""" node::Int - """the vertex of one of the remote nodes for the swap, arbitrarily refered to as the "low" node (or a predicate function or a wildcard); if you are working on a repeater chain, a good choice is `<(current_node)`, i.e. any node to the "left" of the current node""" + """the vertex of one of the remote nodes for the swap, arbitrarily referred to as the "low" node (or a predicate function or a wildcard); if you are working on a repeater chain, a good choice is `<(current_node)`, i.e. any node to the "left" of the current node""" nodeL::NL = ❓ """the vertex of the other remote node for the swap, the "high" counterpart of `nodeL`; if you are working on a repeater chain, a good choice is `>(current_node)`, i.e. any node to the "right" of the current node""" nodeH::NH = ❓ # TODO consider changing the default to random From 7547205200826b7562b6ef8f0f139dcedc486e15 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 6 Feb 2024 11:57:28 -0500 Subject: [PATCH 09/11] revert to `findmin` and `findmax` --- examples/firstgenrepeater_v2/2_swapper_example.jl | 2 +- test/test_entanglement_tracker.jl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/firstgenrepeater_v2/2_swapper_example.jl b/examples/firstgenrepeater_v2/2_swapper_example.jl index 0301c31b..4f8fa34e 100644 --- a/examples/firstgenrepeater_v2/2_swapper_example.jl +++ b/examples/firstgenrepeater_v2/2_swapper_example.jl @@ -20,7 +20,7 @@ for (;src, dst) in edges(network) @process eprot() end for node in vertices(network) - sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node), chooseL = argmin, chooseH = argmax) + sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node), chooseL = findmin, chooseH = findmax) @process sprot() end diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index b75ac758..7462d4f0 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -46,8 +46,8 @@ for i in 1:10 @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) + swapper2 = SwapperProt(sim, net, 2; nodeL = <(2), nodeH = >(2), chooseL = findmin, chooseH = findmax, rounds = 1) + swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), chooseL = findmin, chooseH = findmax, rounds = 1) @process swapper2() @process swapper3() run(sim, 80) @@ -102,7 +102,7 @@ for i in 1:30, n in 2:30 @process eprot() end for j in 2:n-1 - swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) + swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = findmin, chooseH = findmax, rounds = 1) @process swapper() end run(sim, 200) From 2943e2e1a1ff727da4dc4ba31abc418fda8f0611 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 7 Feb 2024 23:14:26 -0500 Subject: [PATCH 10/11] update `findswapablequbits` --- examples/firstgenrepeater_v2/2_swapper_example.jl | 2 +- src/ProtocolZoo/ProtocolZoo.jl | 4 ++-- test/test_entanglement_tracker.jl | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/firstgenrepeater_v2/2_swapper_example.jl b/examples/firstgenrepeater_v2/2_swapper_example.jl index 4f8fa34e..0301c31b 100644 --- a/examples/firstgenrepeater_v2/2_swapper_example.jl +++ b/examples/firstgenrepeater_v2/2_swapper_example.jl @@ -20,7 +20,7 @@ for (;src, dst) in edges(network) @process eprot() end for node in vertices(network) - sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node), chooseL = findmin, chooseH = findmax) + sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node), chooseL = argmin, chooseH = argmax) @process sprot() end diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 67ee086b..994eecda 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -226,8 +226,8 @@ function findswapablequbits(net, node, pred_low, pred_high, choose_low, choose_h high_nodes = queryall(reg, EntanglementCounterpart, pred_high, ❓; locked=false, assigned=true) (isempty(low_nodes) || isempty(high_nodes)) && return nothing - _, il = choose_low(n->n.tag[2], low_nodes) # TODO make [2] into a nice named property - _, ih = choose_high(n->n.tag[2], high_nodes) + il = choose_low((n.tag[2] for n in low_nodes)) # TODO make [2] into a nice named property + ih = choose_high((n.tag[2] for n in high_nodes)) return low_nodes[il], high_nodes[ih] end diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index 7462d4f0..4ba67e17 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -18,7 +18,7 @@ end # 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) @@ -46,8 +46,8 @@ for i in 1:10 @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 = findmin, chooseH = findmax, rounds = 1) - swapper3 = SwapperProt(sim, net, 3; nodeL = <(3), nodeH = >(3), chooseL = findmin, chooseH = findmax, rounds = 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) @@ -64,7 +64,7 @@ for i in 1:10 @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false -end +# end ## @@ -102,7 +102,7 @@ for i in 1:30, n in 2:30 @process eprot() end for j in 2:n-1 - swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = findmin, chooseH = findmax, rounds = 1) + swapper = SwapperProt(sim, net, j; nodeL = <(j), nodeH = >(j), chooseL = argmin, chooseH = argmax, rounds = 1) @process swapper() end run(sim, 200) From 427e079ea5214985809534d1ecac1fa97fef870b Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Sun, 11 Feb 2024 21:51:44 -0500 Subject: [PATCH 11/11] fixups --- src/ProtocolZoo/ProtocolZoo.jl | 4 ++-- test/runtests.jl | 1 + test/test_entanglement_tracker.jl | 4 ++-- test/test_entanglement_tracker_grid.jl | 16 +++++++++++----- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 994eecda..bf4469e1 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -159,7 +159,7 @@ $FIELDS """the vertex of one of the remote nodes for the swap, arbitrarily referred to as the "low" node (or a predicate function or a wildcard); if you are working on a repeater chain, a good choice is `<(current_node)`, i.e. any node to the "left" of the current node""" nodeL::NL = ❓ """the vertex of the other remote node for the swap, the "high" counterpart of `nodeL`; if you are working on a repeater chain, a good choice is `>(current_node)`, i.e. any node to the "right" of the current node""" - nodeH::NH = ❓ # TODO consider changing the default to random + nodeH::NH = ❓ """the `nodeL` predicate can return many positive candidates; `chooseL` picks one of them (by index into the array of filtered `nodeL` results), defaults to a random pick `arr->rand(keys(arr))`; if you are working on a repeater chain a good choice is `argmin`, i.e. the node furthest to the "left" """ chooseL::CL = random_index """the `nodeH` counterpart for `chooseH`; if you are working on a repeater chain a good choice is `argmax`, i.e. the node furthest to the "right" """ @@ -219,7 +219,7 @@ end end end -function findswapablequbits(net, node, pred_low, pred_high, choose_low, choose_high) # TODO parameterize the query predicates and the findmin/findmax +function findswapablequbits(net, node, pred_low, pred_high, choose_low, choose_high) reg = net[node] low_nodes = queryall(reg, EntanglementCounterpart, pred_low, ❓; locked=false, assigned=true) diff --git a/test/runtests.jl b/test/runtests.jl index 7fc4b624..be159025 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -32,6 +32,7 @@ println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREA @doset "messagebuffer" @doset "tags_and_queries" @doset "entanglement_tracker" +@doset "entanglement_tracker_grid" @doset "circuitzoo_api" @doset "circuitzoo_ent_swap" diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index 4ba67e17..b75ac758 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -18,7 +18,7 @@ end # 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) @@ -64,7 +64,7 @@ end @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false -# end +end ## diff --git a/test/test_entanglement_tracker_grid.jl b/test/test_entanglement_tracker_grid.jl index 9d96f754..0dc74860 100644 --- a/test/test_entanglement_tracker_grid.jl +++ b/test/test_entanglement_tracker_grid.jl @@ -14,7 +14,13 @@ if isinteractive() println("Logger set to debug") end +## +# Here we test entanglement tracker and swapper protocols on an arbitrary hardcoded path of long-range connection inside of what is otherwise a 2D grid +# We do NOT test anything related to automatic routing on such a grid -- only the hardcoded path is tested +## + ## Custom Predicates + function top_left(net, node, x) n = sqrt(size(net.graph)[1]) # grid size a = (node ÷ n) + 1 # row number @@ -39,13 +45,13 @@ end ## Simulation -#without entanglement tracker +## without entanglement tracker - this is almost the same test as the one in test_entanglement_tracker.jl which tests a simple chain -- the only difference is that we have picked a few hardcoded arbitrary nodes through a grid (creating an ad-hoc chain) for i in 1:10 graph = grid([4, 4]) add_edge!(graph, 1, 6) add_edge!(graph, 6, 11) add_edge!(graph, 11, 16) - + net = RegisterNet(graph, [Register(3) for i in 1:16]) sim = get_time_tracker(net) @@ -95,10 +101,10 @@ for i in 1:10 end -# with entanglement tracker +## with entanglement tracker -- here we hardcode the diagonal of the grid as the path on which we are making connections for n in 4:10 graph = grid([n,n]) - + diag_pairs = [] diag_nodes = [] reg_num = 1 # starting register @@ -142,4 +148,4 @@ for n in 4:10 @test q2.tag[2] == 1 @test observable((q1.slot, q2.slot), Z⊗Z) ≈ 1 @test observable((q1.slot, q2.slot), X⊗X) ≈ 1 -end \ No newline at end of file +end