Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove blossom does not compile on mac #147

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ ConcurrentSim = "6ed1e86c-fcaf-46a9-97e0-2b26a2cdb499"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
GraphsMatching = "c3af3a8c-b79e-4b01-bf44-c718d7e0e0d6"
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Expand All @@ -25,6 +23,7 @@ QuantumSymbolics = "efa7fd63-0460-4890-beb7-be1bbdfbaeae"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
SumTypes = "8e1ec7a9-0e02-4297-b0fe-6433085c89f2"

Expand All @@ -41,9 +40,7 @@ ConcurrentSim = "1.4.1"
Distributions = "0.25.90"
DocStringExtensions = "0.9"
Graphs = "1.9"
GraphsMatching = "0.2"
IterTools = "1.4.0"
JuMP = "1.21.1"
LinearAlgebra = "1"
Makie = "0.20, 0.21"
NetworkLayout = "0.4.4"
Expand Down
1 change: 1 addition & 0 deletions examples/simpleswitch/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ConcurrentSim = "6ed1e86c-fcaf-46a9-97e0-2b26a2cdb499"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
QuantumSavory = "2de2e421-972c-4cb5-a0c3-999c85908079"
QuantumSymbolics = "efa7fd63-0460-4890-beb7-be1bbdfbaeae"
ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"
Expand Down
83 changes: 83 additions & 0 deletions examples/simpleswitch_randomassign/1_interactive_visualization.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using GLMakie

include("setup.jl")

# Prepare all of the simulation components (while all visualization components are prepared in the rest of this file)
n, sim, net, switch_protocol, client_pairs, client_unordered_pairs, consumers, rates, rate_scale = prepare_simulation()


# Prepare the main figure
fig = Figure(size=(1600,800))
fig_plots = fig[1,1]

# Subfigure for the network visualization
_,ax,_,obs = registernetplot_axis(fig_plots[1:2,1],net)

# Subfigure for the "backlog over time"
backlog = Observable(Float64[0])
sim_time = Observable(Float64[0])
ax_backlog = Axis(fig_plots[1:2,2], xlabel="time", ylabel="average backlog")
stairs!(ax_backlog,sim_time,backlog)

# Subfigure for the "total successfully established and consumed Bell pairs for a pair of clients"
consumed = Observable(zeros(length(consumers)))
ax_consumed_ticks = ["$i-$j" for (i,j) in client_unordered_pairs]
ax_consumed = Axis(fig_plots[1,3], xlabel="pair", ylabel="consumed pairs", xticks=(1:length(consumers),ax_consumed_ticks))
barplot!(ax_consumed,1:length(consumers),consumed, color=Cycled(2))

# Subfigure for the "backlog for a given pair of clients"
backlog_perpair = Observable(zeros(length(consumers)))
ax_backlog_perpair = Axis(fig_plots[2,3], xlabel="pair", ylabel="backlog", xticks=(1:length(consumers),ax_consumed_ticks))
barplot!(ax_backlog_perpair,1:length(consumers),backlog_perpair)

# Sliders with which to control the request rates
sliderfig_ = fig[2,1]
sliderfig = sliderfig_[2,1]
sliders = []
for ((i,j), rate) in zip(client_pairs, rates)
slider = Slider(sliderfig[i,j], range=0.05:0.05:2, startvalue=1)
push!(sliders, slider)
on(slider.value) do val
rate[] = val*rate_scale
end
end
for i in 1:n
Label(sliderfig[1,i+1], "$(i+1)→", tellwidth=false)
Label(sliderfig[i+1,1], "→$(i+1)", tellwidth=true)
end
sliderfig_override = sliderfig_[3,1]
slider_override = Slider(sliderfig_override[1,2], range=0.05:0.05:2, startvalue=1)
on(slider_override.value) do val
for slider in sliders
@async begin
set_close_to!(slider, val)
end
end
end
Label(sliderfig_override[1,1], "global rate override:")
Label(sliderfig_[1,1], rich("Request Rate Controls:",fontsize=20), tellwidth=false)

# Display the figure...
display(fig)

# ... and run the simulation while updating plots as needed
step_ts = range(0, 2, step=0.1)
for t in step_ts
run(sim, t)
ax.title = "t=$(t)"
push!(sim_time[],t)
push!(backlog[], sum(switch_protocol.backlog)/(n-1)/(n-2)/2)
for (i, consumer) in enumerate(consumers)
consumed[][i] = length(consumer.log)
end
for (l,(i, j)) in enumerate(client_unordered_pairs)
backlog_perpair[][l] = switch_protocol.backlog[i-1,j-1]
end
notify(backlog)
notify(consumed)
notify(backlog_perpair)
notify(obs)
autolimits!(ax_backlog)
autolimits!(ax_consumed)
autolimits!(ax_backlog_perpair)
end
158 changes: 158 additions & 0 deletions examples/simpleswitch_randomassign/2_wglmakie_interactive.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using WGLMakie
WGLMakie.activate!()
import Bonito
using Markdown

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

# Mostly a copy of the 1_interactive_visualization.jl file, encapsulated here for convenient serving from inside a WGLMakie app
function prepare_singlerun()
# Prepare all of the simulation components (while all visualization components are prepared in the rest of this function)
n, sim, net, switch_protocol, client_pairs, client_unordered_pairs, consumers, rates, rate_scale = prepare_simulation()

# Prepare the main figure
fig = Figure(size=(1600,800))
fig_plots = fig[1,1]

# Subfigure for the network visualization
_,ax,_,obs = registernetplot_axis(fig_plots[1:2,1],net)

# Subfigure for the "backlog over time"
backlog = Observable(Float64[0])
sim_time = Observable(Float64[0])
ax_backlog = Axis(fig_plots[1:2,2], xlabel="time", ylabel="average backlog")
stairs!(ax_backlog,sim_time,backlog)

# Subfigure for the "total successfully established and consumed Bell pairs for a pair of clients"
consumed = Observable(zeros(length(consumers)))
ax_consumed_ticks = ["$i-$j" for (i,j) in client_unordered_pairs]
ax_consumed = Axis(fig_plots[1,3], xlabel="pair", ylabel="consumed pairs", xticks=(1:length(consumers),ax_consumed_ticks))
barplot!(ax_consumed,1:length(consumers),consumed, color=Cycled(2))

# Subfigure for the "backlog for a given pair of clients"
backlog_perpair = Observable(zeros(length(consumers)))
ax_backlog_perpair = Axis(fig_plots[2,3], xlabel="pair", ylabel="backlog", xticks=(1:length(consumers),ax_consumed_ticks))
barplot!(ax_backlog_perpair,1:length(consumers),backlog_perpair)

# Sliders with which to control the request rates
sliderfig_ = fig[2,1]
sliderfig = sliderfig_[2,1]
sliders = []
for ((i,j), rate) in zip(client_pairs, rates)
slider = Makie.Slider(sliderfig[i,j], range=0.05:0.05:2, startvalue=1)
push!(sliders, slider)
on(slider.value) do val
rate[] = val*rate_scale
end
end
for i in 1:n
Label(sliderfig[1,i+1], "$(i+1)→", tellwidth=false)
Label(sliderfig[i+1,1], "→$(i+1)", tellwidth=true)
end
sliderfig_override = sliderfig_[3,1]
slider_override = Makie.Slider(sliderfig_override[1,2], range=0.05:0.05:2, startvalue=1)
on(slider_override.value) do val
for slider in sliders
Threads.@spawn begin
set_close_to!(slider, val)
end
end
end
Label(sliderfig_override[1,1], "global rate override:")
Label(sliderfig_[1,1], rich("Request Rate Controls:",fontsize=20), tellwidth=false)

axes = (;ax_backlog, ax_consumed, ax_backlog_perpair)
observables = (;backlog, consumed, backlog_perpair, obs)

return n, sim, net, switch_protocol, client_pairs, client_unordered_pairs, consumers, rates, rate_scale, sim_time, fig, observables, axes
end

# All the calls that happen in the main event loop of the simulation,
# encapsulated here so that we can conveniently pause the simulation from the WGLMakie app.
function continue_singlerun!(n, fig, sim, sim_time, switch_protocol, client_unordered_pairs, consumers,
observables, axes, running
)
backlog = observables.backlog
consumed = observables.consumed
backlog_perpair = observables.backlog_perpair
step_ts = range(0, 1000, step=0.1)
for t in step_ts
run(sim, t)
#ax.title = "t=$(t)"
push!(sim_time[],t)
push!(backlog[], sum(switch_protocol.backlog)/(n-1)/(n-2)/2)
for (i, consumer) in enumerate(consumers)
consumed[][i] = length(consumer.log)
end
for (l,(i, j)) in enumerate(client_unordered_pairs)
backlog_perpair[][l] = switch_protocol.backlog[i-1,j-1]
end
notify.(tuple(observables...))
autolimits!.(tuple(axes...))
end
running[] = nothing
end

#
landing = Bonito.App() do

n, sim, net, switch_protocol, client_pairs, client_unordered_pairs, consumers, rates, rate_scale, sim_time, fig, observables, axes = prepare_singlerun()

running = Observable{Any}(false)
fig[3,1] = buttongrid = GridLayout(tellwidth = false)
buttongrid[1,1] = b = Makie.Button(fig, label = @lift(isnothing($running) ? "Done" : $running ? "Running..." : "Run once"), height=30, tellwidth=false)

on(b.clicks) do _
if !running[]
running[] = true
end
end
on(running) do r
if r
Threads.@spawn begin
continue_singlerun!(
n, fig, sim, sim_time, switch_protocol, client_unordered_pairs, consumers,
observables, axes, running)
end
end
end


content = md"""
Pick simulation settings and hit run (see below for technical details).

$(fig.scene)

# Simulations of a simple entanglement switch

The switch is in the center of a star network of clients.
Each client can request to be connected to another client.
The rate of requests can be configured for each pair through the sliders.

After the switch successfully connects two clients, they share an entangled pair which is consumed shortly thereafter -- the total number of consumed pairs is tracked in one of the bar plots.

The backlog of requests is tracked in the other set of plots.

The switch runs one of the scheduling algorithms from "Maximizing Entanglement Rates via Efficient Memory Management in Flexible Quantum Switches" by Promponas et al (2024).

[See and modify the code for this simulation on github.](https://github.com/QuantumSavory/QuantumSavory.jl/tree/master/examples/simpleswitch)
"""
return Bonito.DOM.div(Bonito.MarkdownCSS, Bonito.Styling, custom_css, content)
end;

#
# Serve the Makie app

isdefined(Main, :server) && close(server);
port = parse(Int, get(ENV, "QS_SIMPLESWITCH_PORT", "8888"))
interface = get(ENV, "QS_SIMPLESWITCH_IP", "127.0.0.1")
proxy_url = get(ENV, "QS_SIMPLESWITCH_PROXY", "")
server = Bonito.Server(interface, port; proxy_url);
Bonito.HTTPServer.start(server)
Bonito.route!(server, "/" => landing);

##

wait(server)
9 changes: 9 additions & 0 deletions examples/simpleswitch_randomassign/3_simple_run.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
include("setup.jl")

# Prepare all of the simulation components
n, sim = prepare_simulation()

step_ts = range(0, 12, step=0.1)
for t in step_ts
run(sim, t)
end
11 changes: 11 additions & 0 deletions examples/simpleswitch_randomassign/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[deps]
Bonito = "824d6782-a2ef-11e9-3a09-e5662e0c26f8"
ConcurrentSim = "6ed1e86c-fcaf-46a9-97e0-2b26a2cdb499"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
QuantumSavory = "2de2e421-972c-4cb5-a0c3-999c85908079"
QuantumSymbolics = "efa7fd63-0460-4890-beb7-be1bbdfbaeae"
ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"
12 changes: 12 additions & 0 deletions examples/simpleswitch_randomassign/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# A Simulation of the Simple Entanglement Switch with random assignment

The switch is connected to n clients.
The switch has m qubit slots and the clients have a single qubit slot.
The switch initiates m entanglement attempts per clock tick with m clients uniformly at random.
Once entangled links are established among the qubits at the switch and its clients, the switch performs entanglement swaps on the respective links. Note: As the switch randomly selects pairs of clients to entangle, the protocol operates without user requests / backlog priorisation.

<!-- The `setup.jl` file implements all necessary base functionality.
The other files run the simulation and generate visuals in a number of different circumstances:
1. An interactive simulation with GLMakie visualization;
2. A web-app version of the simulation. -->

74 changes: 74 additions & 0 deletions examples/simpleswitch_randomassign/setup.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using QuantumSavory
using QuantumSavory.ProtocolZoo
using Graphs
using ConcurrentSim
using ResumableFunctions
using Distributions

"""A helper function to repeatedly make requests from a client to the switch to be connected to another client."""
@resumable function make_request(sim, net, client, other_client, rate_observable)
while true
wait_time = rand(Exponential(1/rate_observable[]))
@yield timeout(sim, wait_time)
put!(channel(net, client=>1), Tag(SwitchRequest(client, other_client)))
end
end

@resumable function init_piecemaker(sim, net, m)
while true
# init piecemaker slot in |+>
@yield lock(net[1][m])
if !isassigned(net[1][m])
#@info "Init piecemaker!"
initialize!(net[1][m], X1)
tag!(net[1][m], Piecemaker, 1, m)
unlock(net[1][m])
@yield timeout(sim, 0.1)
else
unlock(net[1][m])
@yield timeout(sim, 0.1)
end
end
end


function prepare_simulation()
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.
graph = star_graph(n+1)

switch_register = Register(m) # the first slot is reserved for the 'piecemaker' qubit used as fusion qubit
client_registers = [Register(1) for _ in 1:n]
net = RegisterNet(graph, [switch_register, client_registers...])
sim = get_time_tracker(net)


@process init_piecemaker(sim, net, m)

# Set up the request-making processes
# between each ordered pair of clients
# client_pairs = [(k1,k2) for k1 in 2:n+1 for k2 in 2:n+1 if k2!=k1]
# rate_scale = 1/length(client_pairs)
# rates = [Ref(rate_scale) for _ in client_pairs]
# for ((client1, client2), rate) in zip(client_pairs, rates)
# @process make_request(sim, net, client1, client2, rate)
# end

# Set up the entanglement trackers at each client
trackers = [EntanglementTracker(sim, net, k) for k in 2:n+1]
for tracker in trackers
@process tracker()
end

# Set up an entanglement consumer between each unordered pair of clients
consumer = GHZConsumer(net, net[1][m])
@process consumer()

# Finally, set up the switch without assignments
switch_protocol = SimpleSwitchDiscreteProt(net, 1, 2:n+1, fill(0.7, n), assignment_algorithm=nothing)
@process switch_protocol()

return n, sim
end
Loading
Loading