diff --git a/examples/controlplane/2a_cnc_interactive.jl b/examples/controlplane/2a_cnc_interactive.jl index 43595067..ee4dfe83 100644 --- a/examples/controlplane/2a_cnc_interactive.jl +++ b/examples/controlplane/2a_cnc_interactive.jl @@ -3,7 +3,7 @@ include("setup.jl") controller = Controller(sim, net, 6, zeros(8,8)) @process controller() -req_gen = RequestGenerator(sim, net, 1, 8, 6) +req_gen = RequestGeneratorCO(sim, net, 1, 8, 6) @process req_gen() consumer = EntanglementConsumer(sim, net, 1, 8) diff --git a/examples/controlplane/3a_cl_interactive.jl b/examples/controlplane/3a_cl_interactive.jl index 18f8171f..30b90d96 100644 --- a/examples/controlplane/3a_cl_interactive.jl +++ b/examples/controlplane/3a_cl_interactive.jl @@ -8,7 +8,7 @@ end controller = CLController(sim, net, 6) @process controller() -req_gen = RequestGenerator(sim, net, 1, 8, 6) +req_gen = RequestGeneratorCL(sim, net, 1, 8, 6) @process req_gen() consumer = EntanglementConsumer(sim, net, 1, 8) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 07af87b9..d6105c6a 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -18,7 +18,7 @@ using Memoize export # protocols - EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer, CutoffProt, RequestTracker, RequestGenerator, + EntanglerProt, SwapperProt, EntanglementTracker, EntanglementConsumer, CutoffProt, RequestTracker, RequestGeneratorCO, RequestGeneratorCL, # tags EntanglementCounterpart, EntanglementHistory, EntanglementUpdateX, EntanglementUpdateZ, EntanglementRequest, SwapRequest, DistributionRequest, # from Switches @@ -210,9 +210,11 @@ See also: [`EntanglementRequest`](@ref), [`SwapRequest`] src::Int """The node with which entanglement is to be generated""" dst::Int + """The number of rounds of swaps requested""" + rounds::Int = 1 end Base.show(io::IO, tag::DistributionRequest) = print(io, "Node $(tag.src) requesting entanglement with $(tag.dst)") -Tag(tag::DistributionRequest) = Tag(DistributionRequest, tag.src, tag.dst) +Tag(tag::DistributionRequest) = Tag(DistributionRequest, tag.src, tag.dst, tag.rounds) """ @@ -576,7 +578,7 @@ user pairs in the same network. $TYPEDFIELDS """ -@kwdef struct RequestGenerator <: AbstractProtocol # TODO Should path_selection be a parameter here, so that it can be customized by the user? +@kwdef struct RequestGeneratorCO <: AbstractProtocol """time-and-schedule-tracking instance from `ConcurrentSim`""" sim::Simulation """a network graph of registers""" @@ -591,15 +593,15 @@ $TYPEDFIELDS λ::Int = 3 end -function RequestGenerator(sim, net, src, dst, controller; kwargs...) - return RequestGenerator(;sim, net, src, dst, controller, kwargs...) +function RequestGeneratorCO(sim, net, src, dst, controller; kwargs...) + return RequestGeneratorCO(;sim, net, src, dst, controller, kwargs...) end -@resumable function (prot::RequestGenerator)() +@resumable function (prot::RequestGeneratorCO)() d = Exponential(inv(prot.λ)) # Parametrized with the scale which is inverse of the rate mb = messagebuffer(prot.net, prot.src) while true - msg = Tag(DistributionRequest, prot.src, prot.dst) + msg = Tag(DistributionRequest, prot.src, prot.dst, 1) put!(channel(prot.net, prot.src=>prot.controller; permit_forward=true), msg) @yield timeout(prot.sim, rand(d)) @@ -607,6 +609,41 @@ end end +""" +$TYPEDEF + +Protocol for the simulation of request traffic for a controller in a connection-oriented network for bipartite entanglement distribution. The requests are considered to be generated according to the Poisson model with rate λ, hence the inter-arrival time is +sampled from an exponential distribution. Physically, the request is generated at the source node(Alice) and is classically communicated to the node where the controller is located. Multiple `RequestGenerator`s can be instantiated for simulation with multiple +user pairs in the same network. + +$TYPEDFIELDS +""" +@kwdef struct RequestGeneratorCL <: AbstractProtocol + """time-and-schedule-tracking instance from `ConcurrentSim`""" + sim::Simulation + """a network graph of registers""" + net::RegisterNet + """The source node(and the node where this protocol runs) of the user pair, commonly called Alice""" + src::Int + """The destination node, commonly called Bob""" + dst::Int + """The node at which the controller is located""" + controller::Int + """The number of rounds of swaps to be requested, -1 for infinite""" + rounds::Int = -1 +end + +function RequestGeneratorCL(sim, net, src, dst, controller; kwargs...) + return RequestGeneratorCL(;sim, net, src, dst, controller, kwargs...) +end + +@resumable function (prot::RequestGeneratorCL)() + mb = messagebuffer(prot.net, prot.src) + msg = Tag(DistributionRequest, prot.src, prot.dst, prot.rounds) + put!(channel(prot.net, prot.src=>prot.controller; permit_forward=true), msg) +end + + include("cutoff.jl") include("swapping.jl") include("controllers.jl") diff --git a/src/ProtocolZoo/controllers.jl b/src/ProtocolZoo/controllers.jl index b37aeb40..9945c15d 100644 --- a/src/ProtocolZoo/controllers.jl +++ b/src/ProtocolZoo/controllers.jl @@ -81,9 +81,9 @@ end workwasdone = true while workwasdone workwasdone = false - msg = querydelete!(mb, DistributionRequest, ❓, ❓) + msg = querydelete!(mb, DistributionRequest, ❓, ❓, ❓) if !isnothing(msg) - (msg_src, (_, req_src, req_dst)) = msg + (msg_src, (_, req_src, req_dst, rounds)) = msg if typeof(prot.path_mat[req_src, req_dst]) <: Number prot.path_mat[req_src, req_dst] = PathMetadata(prot.net.graph, req_src, req_dst, Int(length(prot.net[1].staterefs)/2)) end @@ -104,7 +104,7 @@ end end for i in 2:length(path)-1 - msg = Tag(SwapRequest, path[i], 1, path[i-1], path[i+1], 0) + msg = Tag(SwapRequest, path[i], rounds, path[i-1], path[i+1], 0) if prot.node == path[i] put!(mb, msg) else @@ -145,12 +145,12 @@ end workwasdone = true while workwasdone workwasdone = false - msg = querydelete!(mb, DistributionRequest, ❓, ❓) + msg = querydelete!(mb, DistributionRequest, ❓, ❓, ❓) if !isnothing(msg) - (msg_src, (_, req_src, req_dst)) = msg + (msg_src, (_, req_src, req_dst, rounds)) = msg for v in vertices(prot.net) if v != req_src && v != req_dst - msg = Tag(SwapRequest, v, 1, req_src, req_dst, 1) + msg = Tag(SwapRequest, v, rounds, req_src, req_dst, 1) if prot.node == v put!(mb, msg) else