Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EntanglementConsumer #86

Merged
merged 29 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
19a3a9a
Initial EntanglementConsumer setup with a very loose test around the …
ba2tro Jan 4, 2024
722311d
upper bound for compat
ba2tro Jan 5, 2024
0d593b5
traceout
ba2tro Jan 5, 2024
65f943d
add fifo and filo order for queries and some code rearrangement
ba2tro Jan 15, 2024
0a0f99b
fix for query test
ba2tro Jan 15, 2024
4ac7bfc
Merge branch 'master' into entanglementconsumer
ba2tro Feb 1, 2024
8ebeecb
update and polish the code
ba2tro Feb 2, 2024
2fd1da5
update test_entanglement_consumer.jl
ba2tro Feb 2, 2024
680a023
Update test_entanglement_consumer.jl
ba2tro Feb 2, 2024
8e1f3cd
Add margins to EntanglerProt
ba2tro Feb 5, 2024
4deca04
Merge branch 'master' into entanglementconsumer
ba2tro Feb 13, 2024
463f4f6
Merge branch 'entanglementconsumer' of https://github.com/Abhishek-1B…
ba2tro Feb 13, 2024
7971807
update the code with new changes in swapper, remove typos
ba2tro Feb 14, 2024
a1df3a1
test thoroughly
ba2tro Feb 14, 2024
b6163ff
update ProtocolZoo.jl
ba2tro Feb 23, 2024
b99cd4b
Update test_entanglement_consumer.jl
ba2tro Feb 28, 2024
a320db7
Merge branch 'QuantumSavory:master' into entanglementconsumer
ba2tro Feb 28, 2024
e24b574
Update test_entanglement_consumer.jl
ba2tro Mar 1, 2024
87e3c95
Merge branch 'master' into entanglementconsumer
ba2tro Mar 27, 2024
aacea30
call traceout once, make queries with kwargs
ba2tro Mar 27, 2024
5c2ce5d
modify the margin functionality
ba2tro Mar 29, 2024
f50de9c
change docstrings
ba2tro Mar 29, 2024
a8e989c
apply suggestions from review
ba2tro Mar 31, 2024
ef7c7c6
Update test_entanglement_consumer.jl
ba2tro Mar 31, 2024
6e0130e
Fixes to docs
ba2tro Apr 3, 2024
187348e
minor rewording of the docs to make the bullet points shorter (and so…
Krastanov Apr 4, 2024
8593f38
do not require the user to make empty arrays
Krastanov Apr 4, 2024
d455681
add missing constructor
Krastanov Apr 4, 2024
461ac46
don't log when queries fail
ba2tro Apr 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions src/ProtocolZoo/ProtocolZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import ResumableFunctions
using ResumableFunctions: @resumable
import SumTypes

export EntanglerProt, SwapperProt, EntanglementTracker
export EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer

abstract type AbstractProtocol end

Expand Down Expand Up @@ -116,6 +116,7 @@ end
b = findfreeslot(prot.net[prot.nodeB], randomize=prot.randomize)
if isnothing(a) || isnothing(b)
isnothing(prot.retry_lock_time) && error("We do not yet support waiting on register to make qubits available") # TODO
@debug "EntanglerProt between $(prot.nodeA) and $(prot.nodeB): Failed to find free slots. \n Got:\n \t $a \n \t $b \n retrying..."
@yield timeout(prot.sim, prot.retry_lock_time)
continue
end
Expand All @@ -131,7 +132,8 @@ end
tag!(a, EntanglementCounterpart, prot.nodeB, b.idx)
# tag local node b with EntanglementCounterpart remote_node_idx_a remote_slot_idx_a
tag!(b, EntanglementCounterpart, prot.nodeA, a.idx)


@debug "EntanglerProt between $(prot.nodeA) and $(prot.nodeB): Entangled .$(a.idx) and .$(b.idx)"
Krastanov marked this conversation as resolved.
Show resolved Hide resolved
unlock(a)
unlock(b)
rounds==-1 || (rounds -= 1)
Expand Down Expand Up @@ -305,4 +307,66 @@ end
end
end

"""
$TYPEDEF

A protocol running between two nodes, checking periodically for any entangled pairs between the two nodes and consuming/emptying the qubit slots.

$FIELDS
"""
@kwdef struct EntanglementConsumer <:AbstractProtocol
"""time-and-schedule-tracking instance from `ConcurrentSim`"""
sim::Simulation
"""a network graph of registers"""
net::RegisterNet
"""the vertex index of node A"""
nodeA::Int
"""the vertex index of node B"""
nodeB::Int
"""stores the time and resulting observable from querying nodeA and nodeB for `EntanglementCounterpart`"""
log::Vector{Any}
"""Time period between successive queries on the nodes"""
period::Float64
end

@resumable function (prot::EntanglementConsumer)(;_prot::EntanglementConsumer=prot)
prot = _prot # weird workaround for no support for `struct A a::Int end; @resumable function (fa::A) return fa.a end`; see https://github.com/JuliaDynamics/ResumableFunctions.jl/issues/77
while true
query1 = query(prot.net[prot.nodeA], EntanglementCounterpart, prot.nodeB, ❓)
if isnothing(query1)
push!(prot.log, (now(prot.sim), nothing, nothing))
@yield timeout(prot.sim, prot.period)
@debug "EntanglementConsumer between $(prot.nodeA) and $(prot.nodeB): query1 failed"
continue
else
query2 = query(prot.net[prot.nodeB], EntanglementCounterpart, prot.nodeA, query1.slot.idx)

if isnothing(query2) # in case EntanglementUpdate hasn't reached the second node yet, but the first node has the EntanglementCounterpart
push!(prot.log, (now(prot.sim), nothing, nothing))
@yield timeout(prot.sim, prot.period)
@debug "EntanglementConsumer between $(prot.nodeA) and $(prot.nodeB): query2 failed"
continue
end
end

q1 = query1.slot
q2 = query2.slot
@debug "EntanglementConsumer between $(prot.nodeA) and $(prot.nodeB): queries successful, consuming entanglement"
untag!(q1, query1.tag)
untag!(q2, query2.tag)
# TODO do we need to add EntanglementHistory and should that be a different EntanglementHistory since the current one is specifically for SwapperProt
# TODO currently when calculating the observable we assume that EntanglerProt.pairstate is always (|00⟩ + |11⟩)/√2, make it more general for other states
ob1 = observable((q1, q2), Z⊗Z)
ob2 = observable((q1, q2), X⊗X)

prot.net[prot.nodeA].staterefs[q1.idx] = nothing
ba2tro marked this conversation as resolved.
Show resolved Hide resolved
prot.net[prot.nodeA].stateindices[q1.idx] = 0
prot.net[prot.nodeB].staterefs[q2.idx] = nothing
prot.net[prot.nodeB].stateindices[q2.idx] = 0
push!(prot.log, (now(prot.sim), ob1, ob2))

@yield timeout(prot.sim, prot.period)
end
end

end # module
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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_consumer"

@doset "circuitzoo_api"
@doset "circuitzoo_ent_swap"
Expand Down
37 changes: 37 additions & 0 deletions test/test_entanglement_consumer.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using QuantumSavory
using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer
using Graphs
using ConcurrentSim
using Test

# using Logging
# logger = ConsoleLogger(Logging.Debug; meta_formatter=(args...)->(:black,"",""))
# global_logger(logger)

n = 3

net = RegisterNet([Register(4) for j in 1:n])
sim = get_time_tracker(net)

for e in edges(net)
eprot = EntanglerProt(sim, net, e.src, e.dst; rounds=-1)
@process eprot()
end

for v in 2:n-1
sprot = SwapperProt(sim, net, v; rounds=-1)
@process sprot()
end

for v in vertices(net)
etracker = EntanglementTracker(sim, net, v)
@process etracker()
end

econ = EntanglementConsumer(sim, net, 1, 3, [], 1.0)
@process econ()

run(sim, 400)


@test length([econ.log[i] for i in 1:400 if !isnothing(econ.log[i][2])]) > 100
Loading