Skip to content

Commit

Permalink
Currently first round produces correct fused state, but then mismatch…
Browse files Browse the repository at this point in the history
… in locks happens
  • Loading branch information
Luisenden committed Aug 28, 2024
1 parent 4229843 commit 7db527e
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 24 deletions.
1 change: 0 additions & 1 deletion dev/QuantumSavory
Submodule QuantumSavory deleted from 6e9935
2 changes: 1 addition & 1 deletion examples/simpleswitch_randomassign/3_simple_run.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include("setup.jl")
# Prepare all of the simulation components
n, sim = prepare_simulation()

step_ts = range(0, 20, step=0.1)
step_ts = range(0, 3, step=0.1)
for t in step_ts
run(sim, t)
end
5 changes: 2 additions & 3 deletions examples/simpleswitch_randomassign/setup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ end
# init piecemaker slot in |+>
@yield lock(net[1][m])
if !isassigned(net[1][m])
@info "Init piecemaker!"
#@info "Init piecemaker!"
initialize!(net[1][m], X1)
tag!(net[1][m], Piecemaker, 1, m)
unlock(net[1][m])
Expand All @@ -28,13 +28,12 @@ end
unlock(net[1][m])
@yield timeout(sim, 0.1)
end
@yield timeout(sim, 0.1)
end
end


function prepare_simulation()
n = 10 # number of clients
n = 4 # number of clients
m = n+1 # memory slots in switch is equal to the number of clients + 1 slot for piecemaker qubit

# The graph of network connectivity. Index 1 corresponds to the switch.
Expand Down
34 changes: 23 additions & 11 deletions src/ProtocolZoo/ProtocolZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,31 @@ end
@yield timeout(prot.sim, prot.retry_lock_time)
continue
end

@yield lock(a) & lock(b) # this yield is expected to return immediately
if isassigned(a)
traceout!(a) # TODO: why?
end
if isassigned(b)
traceout!(b) # TODO: why?
end

@info "EntanglerProt: Client $(prot.nodeB) STILL HERE 1"
if islocked(a)
@info "switchnode: $(a) is locked!"
end
if islocked(b)
@info "clientnode: $(b) is locked!"
end
@yield lock(a) & lock(b) # this yield is expected to return immediately

@info "EntanglerProt: Client $(prot.nodeB) STILL HERE 2"

@yield timeout(prot.sim, prot.local_busy_time_pre)
attempts = if isone(prot.success_prob)
1
else
rand(Geometric(prot.success_prob))+1
end

if prot.attempts == -1 || prot.attempts >= attempts
@yield timeout(prot.sim, attempts * prot.attempt_time)
initialize!((a,b), prot.pairstate; time=now(prot.sim))
Expand All @@ -252,6 +266,7 @@ end
end
unlock(a)
unlock(b)
@yield timeout(prot.sim, prot.retry_lock_time)
rounds==-1 || (rounds -= 1)
round += 1
end
Expand Down Expand Up @@ -487,7 +502,7 @@ end
apply!(localslot, updategate)
end
# tag local with updated EntanglementCounterpart new_remote_node new_remote_slot_idx
tag!(localslot, EntanglementCounterpart, newremotenode, newremoteslotid)
# tag!(localslot, EntanglementCounterpart, newremotenode, newremoteslotid)
unlock(localslot)
continue
end
Expand Down Expand Up @@ -548,7 +563,6 @@ end
end
while true
nclients = nsubsystems(prot.net[1])-1
@show nclients
qparticipating = queryall(prot.piecemaker, FusionCounterpart, ❓, ❓) # TODO Need a `querydelete!` dispatch on `Register` rather than using `query` here followed by `untag!` below
if isnothing(qparticipating)
@debug "GHZConsumer between $(prot.piecemaker): query on piecemaker slot found no entanglement"
Expand All @@ -561,12 +575,11 @@ end
# Wait for all locks to complete
tasks = []
for resource in client_slots
push!(tasks, @async lock(resource))
end
push!(tasks, @async lock(prot.piecemaker))
for task in tasks
wait(task)
push!(tasks, lock(resource))
end
push!(tasks, lock(prot.piecemaker))
all_locks = reduce(&, tasks)
@yield all_locks

@debug "GHZConsumer of $(prot.piecemaker): queries successful, consuming entanglement"
for q in qparticipating
Expand All @@ -588,7 +601,7 @@ end
ob1 = real(observable(client_slots, tensor(collect(fill(Z, nclients))...)))
ob2 = real(observable(client_slots, tensor(collect(fill(X, nclients))...)))
# if nclients-GHZ state achieved both observables equal 1
@show ob1, ob2
@info "GHZConsumer: expectation values $(ob1) $(ob2)"

# delete tags and free client slots
for k in 2:nclients+1
Expand Down Expand Up @@ -620,7 +633,6 @@ end

# traceout!(prot.net[prot.nodeA][q1.idx], prot.net[prot.nodeB][q2.idx])
# push!(prot.log, (now(prot.sim), ob1, ob2))
@info "CONSUMER DONE"
@yield timeout(prot.sim, prot.period)
end
end
Expand Down
11 changes: 3 additions & 8 deletions src/ProtocolZoo/switches.jl
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ SimpleSwitchDiscreteProt(net, switchnode, clientnodes, success_probs; kwrags...)
_switch_entangler(prot, assignment)
else
# run entangler without requests (=no assignment)
println("RUN WITH NO ASSIGNMENTS")
_switch_entangler_all(prot)
end
@yield timeout(prot.sim, prot.ticktock/2) # TODO this is a pretty arbitrary value # TODO timeouts should work on prot and on net
Expand All @@ -290,7 +289,6 @@ SimpleSwitchDiscreteProt(net, switchnode, clientnodes, success_probs; kwrags...)

#match = _switch_successful_entanglements_best_match(prot, reverseclientindex)
match = _switch_successful_entanglements(prot, reverseclientindex)
@show match
if isnothing(match)
@yield timeout(prot.sim, prot.ticktock/2) # TODO this is a pretty arbitrary value # TODO timeouts should work on prot and on net
continue
Expand Down Expand Up @@ -407,9 +405,7 @@ end

function _switch_successful_entanglements(prot, reverseclientindex)
switch = prot.net[prot.switchnode]
@show prot.clientnodes
successes = queryall(switch, EntanglementCounterpart, in(prot.clientnodes), ❓)
@show successes
entangled_clients = [r.tag[2] for r in successes] # RegRef (qubit slot)
if isempty(entangled_clients)
@debug "Switch $(prot.switchnode) failed to entangle with any clients"
Expand All @@ -419,7 +415,7 @@ function _switch_successful_entanglements(prot, reverseclientindex)
ne = length(entangled_clients)
if ne < 1 return nothing end
entangled_clients_revindex = [reverseclientindex[k] for k in entangled_clients]
@debug "Switch $(prot.switchnode) successfully entangled with clients $entangled_clients"
@info "Switch $(prot.switchnode) successfully entangled with clients $entangled_clients"
return entangled_clients_revindex
end

Expand All @@ -445,10 +441,9 @@ Assuming the clientnodes are entangled,
perform fusion to connect them with piecemaker qubit (no backlog discounter yet!).
"""
function _switch_run_fusions(prot, match)
@info "Switch $(prot.switchnode) performs fusions for clients in $(match)"
@debug "Switch $(prot.switchnode) performs fusions for clients in $(match)"
for i in match
@show i
@info "Enter fusion protocol with client $(i)"
@debug "Enter fusion protocol with client $(i)"
fusion = FusionProt( # TODO be more careful about how much simulated time this takes
sim=prot.sim, net=prot.net, node=prot.switchnode,
nodeC=prot.clientnodes[i],
Expand Down

0 comments on commit 7db527e

Please sign in to comment.