Skip to content

Commit

Permalink
grid entanglement with multiple paths, copy over fifo filo query changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ba2tripleO committed Feb 16, 2024
1 parent 1a0b40d commit 9fb110f
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 93 deletions.
10 changes: 8 additions & 2 deletions src/ProtocolZoo/ProtocolZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,13 @@ end
@resumable function (prot::EntanglerProt)(;_prot::EntanglerProt=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
rounds = prot.rounds
round = 1
while rounds != 0
a = findfreeslot(prot.net[prot.nodeA], randomize=prot.randomize)
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)|round $(round): 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 @@ -132,9 +134,11 @@ end
# 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)| round $(round): Entangled .$(a.idx) and .$(b.idx)"
unlock(a)
unlock(b)
rounds==-1 || (rounds -= 1)
round += 1
end
end

Expand Down Expand Up @@ -180,6 +184,7 @@ end
@resumable function (prot::SwapperProt)(;_prot::SwapperProt=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
rounds = prot.rounds
round = 1
while rounds != 0
reg = prot.net[prot.node]
qubit_pair = findswapablequbits(prot.net, prot.node, prot.nodeL, prot.nodeH, prot.chooseL, prot.chooseH)
Expand Down Expand Up @@ -207,15 +212,16 @@ end
# tag with EntanglementUpdateX past_local_node, past_local_slot_idx past_remote_slot_idx new_remote_node, new_remote_slot, correction
msg1 = Tag(EntanglementUpdateX, prot.node, q1.idx, tag1[3], tag2[2], tag2[3], xmeas)
put!(channel(prot.net, prot.node=>tag1[2]; permit_forward=true), msg1)
@debug "SwapperProt @$(prot.node): Send message to $(tag1[2]) | message=`$msg1`"
@debug "SwapperProt @$(prot.node)|round $(round): Send message to $(tag1[2]) | message=`$msg1`"
# send from here to new entanglement counterpart:
# tag with EntanglementUpdateZ past_local_node, past_local_slot_idx past_remote_slot_idx new_remote_node, new_remote_slot, correction
msg2 = Tag(EntanglementUpdateZ, prot.node, q2.idx, tag2[3], tag1[2], tag1[3], zmeas)
put!(channel(prot.net, prot.node=>tag2[2]; permit_forward=true), msg2)
@debug "SwapperProt @$(prot.node): Send message to $(tag2[2]) | message=`$msg2`"
@debug "SwapperProt @$(prot.node)|round $(round): Send message to $(tag2[2]) | message=`$msg2`"
unlock(q1)
unlock(q2)
rounds==-1 || (rounds -= 1)
round += 1
end
end

Expand Down
41 changes: 28 additions & 13 deletions src/queries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ julia> queryall(r, :symbol, ❓, >(5))
@NamedTuple{slot::RegRef, tag::Tag}[]
```
"""
queryall(args...; kwargs...) = query(args..., Val{true}(); kwargs...)
queryall(args...; fifo=true, kwargs...) = query(args..., Val{true}(), Val{fifo}(); kwargs...)


""" A query function searching for the first slot in a register that has a given tag.
Expand Down Expand Up @@ -95,11 +95,12 @@ julia> query(r, Int, 4, <(7))
See also: [`queryall`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)
"""
function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing) where {allB}
find = allB ? findall : findfirst
function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing) where {allB, fifo}
find = allB ? findall : fifo ? findlast : findfirst # findlast corresponds to fifo because new tags are pushed at the end of the tags vector for a RegRef in `tag!`
i = find(i -> _nothingor(locked, islocked(reg[i])) && _nothingor(assigned, isassigned(reg[i])) && tag reg.tags[i],
1:length(reg))
if allB
i = fifo ? reverse(i) : i # findall still starts looking from the first index, so we reverse here
return NamedTuple{(:slot, :tag), Tuple{RegRef, Tag}}[(slot=reg[i], tag=tag) for i in i]
else
isnothing(i) ? nothing : (;slot=reg[i], tag=tag)
Expand All @@ -124,10 +125,11 @@ julia> queryall(r[2], :symbol, 2, 3)
(depth = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag)
```
"""
function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}()) where {allB} # TODO there is a lot of code duplication here
find = allB ? findall : findfirst
function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}()) where {allB, fifo} # TODO there is a lot of code duplication here
find = allB ? findall : fifo ? findlast : findfirst # findlast corresponds to fifo because new tags are pushed at the end of the tags vector for a RegRef in `tag!`
i = find(==(tag), ref.reg.tags[ref.idx])
if allB
i = fifo ? reverse(i) : i # findall still starts looking from the first index, so we reverse here
return NamedTuple{(:depth, :tag), Tuple{Int, Tag}}[(depth=i, tag=tag) for i in i]
else
isnothing(i) ? nothing : (;depth=i, tag=tag)
Expand Down Expand Up @@ -259,15 +261,26 @@ for (tagsymbol, tagvariant) in pairs(tag_types)
argssig_wild = [:($a::$t) for (a,t) in zip(args, sig_wild)]
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}
newmethod_reg = quote function query(reg::Register, $(argssig_wild...), ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing) where {allB, fifo}
res = NamedTuple{(:slot, :tag), Tuple{RegRef, Tag}}[]
for (reg_idx, tags) in enumerate(reg.tags)
slot = reg[reg_idx]
for tag in tags
if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol
(_nothingor(locked, islocked(slot)) && _nothingor(assigned, isassigned(slot))) || continue
if _all($(nonwild_checks...)) && _all($(wild_checks...))
allB ? push!(res, (;slot, tag)) : return (;slot, tag)
if fifo
for tag in reverse(tags)
if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol
(_nothingor(locked, islocked(slot)) && _nothingor(assigned, isassigned(slot))) || continue
if _all($(nonwild_checks...)) && _all($(wild_checks...))
allB ? push!(res, (;slot, tag)) : return (;slot, tag)
end
end
end
else
for tag in tags
if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol
(_nothingor(locked, islocked(slot)) && _nothingor(assigned, isassigned(slot))) || continue
if _all($(nonwild_checks...)) && _all($(wild_checks...))
allB ? push!(res, (;slot, tag)) : return (;slot, tag)

Check warning on line 282 in src/queries.jl

View check run for this annotation

Codecov / codecov/patch

src/queries.jl#L278-L282

Added lines #L278 - L282 were not covered by tests
end
end
end
end
Expand All @@ -283,9 +296,11 @@ for (tagsymbol, tagvariant) in pairs(tag_types)
end
end
end end
newmethod_rr = quote function query(ref::RegRef, $(argssig_wild...), ::Val{allB}=Val{false}()) where {allB}
newmethod_rr = quote function query(ref::RegRef, $(argssig_wild...), ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}()) where {allB, fifo}
res = NamedTuple{(:depth, :tag), Tuple{Int, Tag}}[]
for (depth, tag) in pairs(ref.reg.tags[ref.idx])
tags = fifo ? reverse(ref.reg.tags[ref.idx]) : ref.reg.tags[ref.idx]
for (depth, tag) in pairs(tags) # no `reverse` dispatch on `Base.Pairs`, so we end up with the original depth but only the order of tags reversed
depth = fifo ? length(ref.reg.tags[ref.idx]) + 1 - depth : depth # to adjust the depth
if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol
if _all($(nonwild_checks...)) && _all($(wild_checks...))
allB ? push!(res, (;depth, tag)) : return (;depth, tag)
Expand Down
Loading

0 comments on commit 9fb110f

Please sign in to comment.