Skip to content

Commit

Permalink
move path selection to controller and related modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ba2tripleO committed Nov 4, 2024
1 parent b78d288 commit 88ec49d
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 61 deletions.
5 changes: 2 additions & 3 deletions examples/controlplane/2a_cnc_interactive.jl
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
5 changes: 2 additions & 3 deletions examples/controlplane/2b_cnc_wglmakie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
46 changes: 7 additions & 39 deletions src/ProtocolZoo/ProtocolZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export
# controllers
NetController, Controller,
#utils
PhysicalGraph, path_selection
PathMetadata, path_selection

abstract type AbstractProtocol end

Expand Down Expand Up @@ -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)


"""
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
22 changes: 14 additions & 8 deletions src/ProtocolZoo/controllers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)()
Expand All @@ -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)
Expand All @@ -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
Expand Down
25 changes: 17 additions & 8 deletions src/ProtocolZoo/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand All @@ -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]<capacity
phys_graph.workloads[i] += 1
function path_selection(sim, pathobj::PathMetadata)
for i in 1:length(pathobj.paths)
capacity = isa(pathobj.capacity, Number) ? pathobj.capacity : pathobj.capacity[i]
if pathobj.workloads[i]<capacity
pathobj.workloads[i] += 1
@process unreserve_path(sim, pathobj, i)
return i
end
end
pathobj.failures +=1
return nothing
end

@resumable function unreserve_path(sim, pathobj::PathMetadata, i)
@yield timeout(sim, 0.5)
@debug "Path $(pathobj.paths[i]) workload reduced"
pathobj.workloads[i] -= 1
end


Expand Down

0 comments on commit 88ec49d

Please sign in to comment.