diff --git a/examples/controlplane/2a_cnc_interactive.jl b/examples/controlplane/2a_cnc_interactive.jl index 09ece2e3..43595067 100644 --- a/examples/controlplane/2a_cnc_interactive.jl +++ b/examples/controlplane/2a_cnc_interactive.jl @@ -1,10 +1,9 @@ include("setup.jl") -phys_graph = PhysicalGraph(graph, 1, 8, regsize) -controller = Controller(sim, net, 6, phys_graph) +controller = Controller(sim, net, 6, zeros(8,8)) @process controller() -req_gen = RequestGenerator(sim, net, 1, 8, 6, phys_graph) +req_gen = RequestGenerator(sim, net, 1, 8, 6) @process req_gen() consumer = EntanglementConsumer(sim, net, 1, 8) diff --git a/examples/controlplane/2b_cnc_wglmakie.jl b/examples/controlplane/2b_cnc_wglmakie.jl index 72db04cc..99d840f5 100644 --- a/examples/controlplane/2b_cnc_wglmakie.jl +++ b/examples/controlplane/2b_cnc_wglmakie.jl @@ -7,11 +7,10 @@ include("setup.jl") const custom_css = Bonito.DOM.style("ul {list-style: circle !important;}") # TODO remove after fix of bug in JSServe https://github.com/SimonDanisch/JSServe.jl/issues/178 -phys_graph = PhysicalGraph(graph, 1, 8, regsize) -controller = Controller(sim, net, 6, phys_graph) +controller = Controller(sim, net, 6, zeros(8,8)) @process controller() -req_gen = RequestGenerator(sim, net, 1, 8, 6, phys_graph) +req_gen = RequestGenerator(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 f52d71ef..7eb70988 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -25,7 +25,7 @@ export # controllers NetController, Controller, #utils - PhysicalGraph, path_selection + PathMetadata, path_selection abstract type AbstractProtocol end @@ -203,27 +203,9 @@ See also: [`EntanglementRequest`](@ref), [`SwapRequest`] src::Int """The node with which entanglement is to be generated""" dst::Int - """Index of the path to be taken for the entanglement generation""" - path::Int 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.path) - - -""" -$TYPEDEF - -A message sent from the controller to a request generating node after its request has been served. - -$TYPEDFIELDS - -See also: [`EntanglementRequest`](@ref), [`SwapRequest`] -""" -@kwdef struct RequestCompletion - path_id::Int -end -Base.show(io::IO, tag::RequestCompletion) = print(io, "Request on path id $(tag.path_id) served") -Tag(tag::RequestCompletion) = Tag(RequestCompletion, tag.path_id) +Tag(tag::DistributionRequest) = Tag(DistributionRequest, tag.src, tag.dst) """ @@ -442,7 +424,7 @@ end error("`EntanglementTracker` on node $(prot.node) received a message $(msg) that it does not know how to handle (due to the absence of corresponding `EntanglementCounterpart` or `EntanglementHistory` or `EntanglementDelete` tags). This might have happened due to `CutoffProt` deleting qubits while swaps are happening. Make sure that the retention times in `CutoffProt` are sufficiently larger than the `agelimit` in `SwapperProt`. Otherwise, this is a bug in the protocol and should not happen -- please report an issue at QuantumSavory's repository.") end end - @debug "EntanglementTracker @$(prot.node): Starting message wait at $(now(prot.sim)) with MessageBuffer containing: $(mb.buffer)" + # @debug "EntanglementTracker @$(prot.node): Starting message wait at $(now(prot.sim)) with MessageBuffer containing: $(mb.buffer)" @yield wait(mb) @debug "EntanglementTracker @$(prot.node): Message wait ends at $(now(prot.sim))" end @@ -561,7 +543,7 @@ end end end end - @debug "RequestTracker @$(prot.node): Starting message wait at $(now(prot.sim)) with MessageBuffer containing: $(mb.buffer)" + # @debug "RequestTracker @$(prot.node): Starting message wait at $(now(prot.sim)) with MessageBuffer containing: $(mb.buffer)" @yield wait(mb) @debug "RequestTracker @$(prot.node): Message wait ends at $(now(prot.sim))" end @@ -589,35 +571,21 @@ $TYPEDFIELDS dst::Int """The node at which the controller is located""" controller::Int - """The object containing physical graph metadata for the network""" - phys_graph::PhysicalGraph """rate of arrival of requests/number of requests sent unit time""" λ::Int = 3 end -function RequestGenerator(sim, net, src, dst, controller, phys_graph; kwargs...) - return RequestGenerator(;sim, net, src, dst, controller, phys_graph, kwargs...) +function RequestGenerator(sim, net, src, dst, controller; kwargs...) + return RequestGenerator(;sim, net, src, dst, controller, kwargs...) end @resumable function (prot::RequestGenerator)() d = Exponential(inv(prot.λ)) # Parametrized with the scale which is inverse of the rate mb = messagebuffer(prot.net, prot.src) while true - path_index = path_selection(prot.phys_graph) - if isnothing(path_index) - prot.phys_graph.failures[] += 1 - @yield timeout(prot.sim, rand(d)) - continue - end - msg = Tag(DistributionRequest, prot.src, prot.dst, path_index) + msg = Tag(DistributionRequest, prot.src, prot.dst) put!(channel(prot.net, prot.src=>prot.controller; permit_forward=true), msg) - # incoming message from the controller after a request has been served - in_msg = querydelete!(mb, RequestCompletion, ❓) - if !isnothing(in_msg) - (src, (_, path_id)) = in_msg - prot.phys_graph.workloads[path_id] -= 1 - end @yield timeout(prot.sim, rand(d)) end end diff --git a/src/ProtocolZoo/controllers.jl b/src/ProtocolZoo/controllers.jl index 650e5fcf..95b4e901 100644 --- a/src/ProtocolZoo/controllers.jl +++ b/src/ProtocolZoo/controllers.jl @@ -71,8 +71,8 @@ See also [`RequestGenerator`](@ref), [`RequestTracker`](@ref) net::RegisterNet """The node in the network where the control protocol is physically located, ideally a centrally located node""" node::Int - """The object containing physical graph metadata for the network""" - phys_graph::PhysicalGraph + """A matrix for the object containing physical graph metadata for the network""" + path_mat::Matrix{Union{Float64, PathMetadata}} end @resumable function (prot::Controller)() @@ -81,10 +81,18 @@ end workwasdone = true while workwasdone workwasdone = false - msg = querydelete!(mb, DistributionRequest, ❓, ❓, ❓) + msg = querydelete!(mb, DistributionRequest, ❓, ❓) if !isnothing(msg) - (msg_src, (_, src, dst, path_ind)) = msg - path = prot.phys_graph.paths[path_ind] + (msg_src, (_, src, dst)) = msg + if typeof(prot.path_mat[src, dst]) <: Number + prot.path_mat[src, dst] = PathMetadata(prot.net.graph, src, dst, Int(length(prot.net[1].staterefs)/2)) + end + path_id = path_selection(prot.sim, prot.path_mat[src, dst]) + path = prot.path_mat[src, dst].paths[path_id] + if isnothing(path_id) + @debug "Request failed, all paths reserved" + end + @debug "Running Entanglement Distribution on path $(path) @ $(now(prot.sim))" for i in 1:length(path)-1 msg = Tag(EntanglementRequest, path[i], path[i+1], 1) @@ -104,10 +112,8 @@ end put!(channel(prot.net, prot.node=>msg[2];permit_forward=true), msg) end end - comp_msg = Tag(RequestCompletion, path_ind) - put!(channel(prot.net, prot.node=>src; permit_forward=true), comp_msg) end - @debug "Controller @$(prot.node): Starting message wait at $(now(prot.sim)) with MessageBuffer containing: $(mb.buffer)" + # @debug "Controller @$(prot.node): Starting message wait at $(now(prot.sim)) with MessageBuffer containing: $(mb.buffer)" @yield wait(mb) @debug "Controller @$(prot.node): Message wait ends at $(now(prot.sim))" end diff --git a/src/ProtocolZoo/utils.jl b/src/ProtocolZoo/utils.jl index 50061a53..2366daeb 100644 --- a/src/ProtocolZoo/utils.jl +++ b/src/ProtocolZoo/utils.jl @@ -7,7 +7,7 @@ passed through the `DistributionRequest` tag/message. $TYPEDFIELDS """ -@kwdef struct PhysicalGraph +@kwdef struct PathMetadata """The vector of paths between the user pair""" paths::Vector{Vector{Int}} """The vector containing the workload information of a path""" @@ -18,24 +18,33 @@ $TYPEDFIELDS failures::Ref{Int} end -function PhysicalGraph(graph::SimpleGraph{Int64}, src::Int, dst::Int, caps::Union{Vector{Int}, Int}; failures=Ref{Int}(0)) +function PathMetadata(graph::SimpleGraph{Int64}, src::Int, dst::Int, caps::Union{Vector{Int}, Int}; failures=Ref{Int}(0)) paths = sort(collect(all_simple_paths(graph, src, dst)); by = x->length(x)) workloads = zeros(length(paths)) - PhysicalGraph(paths, workloads, caps, failures) + PathMetadata(paths, workloads, caps, failures) end """ A simple path selection algorithm for connection oriented networks. """ -function path_selection(phys_graph::PhysicalGraph) - for i in 1:length(phys_graph.paths) - capacity = isa(phys_graph.capacity, Number) ? phys_graph.capacity : phys_graph.capacity[i] - if phys_graph.workloads[i]