Skip to content

Commit

Permalink
Plots update
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrian Ariton committed Sep 6, 2023
1 parent ffd426c commit 25b2173
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 65 deletions.
File renamed without changes.
107 changes: 64 additions & 43 deletions examples/fullstack/Sim.jl → examples/fullstack/src/Sim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using CSSMakieLayout
include("setup.jl")
import JSServe.TailwindDashboard as D

retina_scale = 1
retina_scale = 2
config = Dict(
:resolution => (retina_scale*1400, retina_scale*700), #used for the main figures
:smallresolution => (280, 160), #used for the menufigures
Expand Down Expand Up @@ -65,13 +65,13 @@ idof = Dict(
"Double Selection"=>3
)

function plot_alphafig(F, meta="",mfig=nothing; hidedecor=false, observables=nothing)
function plot_alphafig(F, meta="",mfig=nothing, extrafig=nothing; hidedecor=false, observables=nothing)
if isnothing(observables)
return
end
obs_PURIFICATION, obs_time, obs_commtime,
obs_registersizes, obs_node_timedelay, obs_initial_prob,
obs_USE, obs_emitonpurifsuccess, logstring, showlog = observables
obs_USE, obs_emitonpurifsuccess, logstring, showlog, obs_sampledenttimes = observables

PURIFICATION = obs_PURIFICATION[]
time = obs_time[]
Expand All @@ -91,9 +91,11 @@ function plot_alphafig(F, meta="",mfig=nothing; hidedecor=false, observables=not
sim, network = simulation_setup(registersizes, commtimes, protocol)
_,ax,p,obs = registernetplot_axis(F[1:2,1:3],network; twoqubitobservable=projector(StabilizerState("XX ZZ")))
_,mfig_ax,mfig_p,mfig_obs = nothing, nothing, nothing, nothing
_,extrafig_ax,extrafig_p,extrafig_obs = nothing, nothing, nothing, nothing
(mfig !== nothing) && begin
_,mfig_ax,mfig_p,mfig_obs = registernetplot_axis(mfig[1, 1],network; twoqubitobservable=projector(StabilizerState("XX ZZ")))
end
_,mfig_ax,mfig_p,mfig_obs = registernetplot_axis(mfig[1, 1],network; twoqubitobservable=projector(StabilizerState("XX ZZ"))) end
(extrafig !==nothing) && begin
_,extrafig_ax,extrafig_p,extrafig_obs = registernetplot_axis(extrafig[1:2,1:3],network; twoqubitobservable=projector(StabilizerState("XX ZZ"))) end
hidedecor && return

F[3, 1:6] = buttongrid = GridLayout(tellwidth = false)
Expand All @@ -112,12 +114,9 @@ function plot_alphafig(F, meta="",mfig=nothing; hidedecor=false, observables=not

subfig = rightfig[1, 2:4]
sg = SliderGrid(subfig[1, 1],
(label="time", range=3:0.1:30, startvalue=20.3),
(label="1 - pauli error prob", range=0.5:0.1:0.9, startvalue=0.7),
(label="chanel delay", range=0.1:0.1:0.3, startvalue=0.1),
(label="recycle purif pairs", range=0:1, startvalue=0),
(label="register size", range=3:10, startvalue=6))
observable_params = [obs_time, obs_initial_prob, obs_commtime, obs_emitonpurifsuccess, obs_registersizes]
observable_params = [obs_emitonpurifsuccess, obs_registersizes]
m = Menu(subfig[2, 1], options = ["Single Selection", "Double Selection"], prompt="Purification circuit...", default="Double Selection")
on(m.selection) do sel
obs_USE[] = idof[sel]
Expand Down Expand Up @@ -163,13 +162,17 @@ function plot_alphafig(F, meta="",mfig=nothing; hidedecor=false, observables=not
empty!(mfig_ax)
_,mfig_ax,mfig_p,mfig_obs = registernetplot_axis(mfig[1, 1],network; twoqubitobservable=projector(StabilizerState("XX ZZ")))
end
if extrafig !== nothing
empty!(extrafig_ax)
_,extrafig_ax,extrafig_p,extrafig_obs = registernetplot_axis(extrafig[1:2,1:3],network; twoqubitobservable=projector(StabilizerState("XX ZZ")))
end

currenttime = Observable(0.0)
# Setting up the ENTANGMELENT protocol
for (;src, dst) in edges(network)
@process freequbit_trigger(sim, protocol, network, src, dst, showlog[] ? logstring : nothing)
@process entangle(sim, protocol, network, src, dst, noisy_pair, showlog[] ? logstring : nothing)
@process entangle(sim, protocol, network, dst, src, noisy_pair, showlog[] ? logstring : nothing)
@process entangle(sim, protocol, network, src, dst, noisy_pair, showlog[] ? logstring : nothing, [obs_sampledenttimes])
@process entangle(sim, protocol, network, dst, src, noisy_pair, showlog[] ? logstring : nothing, [obs_sampledenttimes])
end
# Setting up the purification protocol
if PURIFICATION
Expand All @@ -187,6 +190,8 @@ function plot_alphafig(F, meta="",mfig=nothing; hidedecor=false, observables=not
run(sim, t)
notify(obs)
notify(mfig_obs)
notify(extrafig_obs)
notify(obs_sampledenttimes)
ax.title = "t=$(t)"
if !running[]
break
Expand All @@ -202,48 +207,63 @@ function plot_alphafig(F, meta="",mfig=nothing; hidedecor=false, observables=not
end
end
end
return running
end

function plot_betafig(figure, meta=""; hidedecor=false)
# This is where we will do the receipe for the second figure (Entanglement Swap)
ax = Axis(figure[1, 1])
scatter!(ax, [1,2], [2,3], color=(:black, 0.2))
axx = Axis(figure[1, 2])
scatter!(axx, [1,2], [2,3], color=(:black, 0.2))
axxx = Axis(figure[2, 1:2])
scatter!(axxx, [1,2], [2,3], color=(:black, 0.2))

if hidedecor
hidedecorations!(ax)
hidedecorations!(axx)
hidedecorations!(axxx)
function plot_betafig(F, meta="",mfig=nothing; hidedecor=false, observables=nothing)
obs_PURIFICATION, obs_time, obs_commtime,
obs_registersizes, obs_node_timedelay, obs_initial_prob,
obs_USE, obs_emitonpurifsuccess, logstring, showlog, obs_sampledenttimes, running = observables
rightfig = F[1:2, 4:6]
plotfig = rightfig[2,1:4]
waittimeax = Axis(plotfig, title="Entanglement generation wait time")
subfig = rightfig[1, 2:4]
sg = SliderGrid(subfig[1, 1],
(label="time", range=3:0.1:30, startvalue=20.3),
(label="initial fidelity", range=0.5:0.1:0.9, startvalue=0.7),
(label="chanel delay", range=0.1:0.1:0.3, startvalue=0.1))
observable_params = [obs_time, obs_initial_prob, obs_commtime]
F[3, 1:6] = buttongrid = GridLayout(tellwidth = false)
buttongrid[1,1] = b = Makie.Button(F, label = @lift($running ? "Stop" : "Run"), fontsize=32)

for i in 1:length(observable_params)
on(sg.sliders[i].value) do val
if !running[]
observable_params[i][] = val
notify(observable_params[i])
end
end
end
on(b.clicks) do _
running[] = !running[]
end
distr = Exponential(0.4)
range = 0.05:0.1:4.95
lines!(waittimeax, range, 1/0.4 * exp.(-(collect(range) ./ 0.4)))
on(obs_sampledenttimes) do val
empty!(waittimeax)
lines!(waittimeax, range, 1/0.4 * exp.(-(collect(range) ./ 0.4)), color=:blue)
hist!(waittimeax, val, color=:blue)
end

end

function plot_gammafig(figure, meta=""; hidedecor=false)
# This is where we will do the receipe for the third figure (Entanglement Purif)

ax = Axis(figure[1, 1])
scatter!(ax, [1,2], [2,3], color=(:black, 0.2))

if hidedecor
hidedecorations!(ax)
end
function plot_gammafig(F, meta="",mfig=nothing; hidedecor=false, observables=nothing)

end

# The plot function is used to prepare the receipe (plots) for
# the mainfigures which get toggled by the identical figures in
# the menu (the menufigures), as well as for the menufigures themselves

function plot(figure_array, menufigs=[], metas=["", "", ""]; hidedecor=false, observables=[])
function plot(figure_array, menufigs=[], metas=["", "", ""]; hidedecor=false, observables=nothing)
if length(menufigs)==0
plot_alphafig(figure_array[1], metas[1]; hidedecor=hidedecor, observables=observables[1])
plot_betafig( figure_array[2], metas[2]; hidedecor=hidedecor)
plot_gammafig(figure_array[3], metas[3]; hidedecor=hidedecor)
plot_alphafig(figure_array[1], metas[1]; hidedecor=hidedecor, observables=observables)
plot_betafig( figure_array[2], metas[2]; hidedecor=hidedecor, observables=observables)
plot_gammafig(figure_array[3], metas[3]; hidedecor=hidedecor, observables=observables)
else
plot_alphafig(figure_array[1], metas[1], menufigs[1]; hidedecor=hidedecor, observables=observables[1])
plot_betafig( figure_array[2], metas[2]; hidedecor=hidedecor)
plot_gammafig(figure_array[3], metas[3]; hidedecor=hidedecor)
running = plot_alphafig(figure_array[2], metas[2], menufigs[2], figure_array[1]; hidedecor=hidedecor, observables=observables)
plot_betafig(figure_array[1]; observables=push!(observables, running))
end
end

Expand All @@ -260,9 +280,10 @@ landing = App() do session::Session
obs_emitonpurifsuccess = Observable(0)
logstring = Observable("")
showlog = Observable(false)
obs_sampledenttimes = Observable([0.0])
allobs = [obs_PURIFICATION, obs_time, obs_commtime,
obs_registersizes, obs_node_timedelay, obs_initial_prob,
obs_USE, obs_emitonpurifsuccess, logstring, showlog]
obs_USE, obs_emitonpurifsuccess, logstring, showlog, obs_sampledenttimes]
keepsame=true
# Create the menufigures and the mainfigures
mainfigures = [Figure(backgroundcolor=:white, resolution=config[:resolution]) for _ in 1:3]
Expand All @@ -285,7 +306,7 @@ landing = App() do session::Session
end

# Using the aforementioned plot function to plot for each figure array
plot(mainfigures, menufigures, observables=[allobs, nothing, nothing])
plot(mainfigures, menufigures, observables=allobs)

# Create ZStacks displayong titles below the menu graphs
titles_zstack = [zstack(wrap(DOM.h4(titles[i], class="upper")),
Expand Down Expand Up @@ -467,7 +488,7 @@ end
##
# Serve the Makie app
isdefined(Main, :server) && close(server);
port = parse(Int, get(ENV, "QS_COLORCENTERMODCLUSTER_PORT", "8888"))
port = parse(Int, get(ENV, "QS_COLORCENTERMODCLUSTER_PORT", "8889"))
interface = get(ENV, "QS_COLORCENTERMODCLUSTER_IP", "127.0.0.1")
proxy_url = get(ENV, "QS_COLORCENTERMODCLUSTER_PROXY", "")
server = JSServe.Server(interface, port; proxy_url);
Expand Down
Binary file added examples/fullstack/src/flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 18 additions & 22 deletions examples/fullstack/setup.jl → examples/fullstack/src/setup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,29 @@ using Crayons
using Crayons.Box
# For convenient graph data structures
using Graphs

# For discrete event simulation
using ResumableFunctions
using ConcurrentSim
import Base: put!, take!

# Useful for interactive work
# Enables automatic re-compilation of modified codes
using Revise

# The workhorse for the simulation
using QuantumSavory

# Predefined useful circuits
using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1Node, Purify3to1Node, AbstractCircuit
using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1Node, Purify3to1Node, AbstractCircuit, inputqubits
# Clean messages
using SumTypes
# Random stuff
using Random, Distributions
Random.seed!(123)

const perfect_pair = (Z1Z1 + Z2Z2) / sqrt(2)
const perfect_pair_dm = SProjector(perfect_pair)
const mixed_dm = MixedState(perfect_pair_dm)
noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm

struct FreeQubitTriggerProtocolSimulation
purifier_circuit_size
purifier_circuit
looptype
waittime
Expand All @@ -38,20 +37,12 @@ struct FreeQubitTriggerProtocolSimulation
emitonpurifsuccess
maxgeneration
end

function circuit_size(circ) # todo: replace with optio from circuit zoo once merged
sizes = Dict(
Purify2to1Node=>2,
Purify3to1Node=>3
)
return sizes[circ]
end
FreeQubitTriggerProtocolSimulation(circ;
looptype::Array{Symbol}=[:X, :Y, :Z],
waittime=0.4, busytime=0.3,
keywords=Dict(:simple_channel=>:fqtp_channel, :process_channel=>:fqtp_process_channel),
emitonpurifsuccess=false,
maxgeneration=10) = FreeQubitTriggerProtocolSimulation(circuit_size(circ), circ, looptype, waittime, busytime, keywords, emitonpurifsuccess, maxgeneration)
maxgeneration=10) = FreeQubitTriggerProtocolSimulation(circ, looptype, waittime, busytime, keywords, emitonpurifsuccess, maxgeneration)

# formatting the message string so it looks nice in browser
function slog!(s, msg, id)
Expand All @@ -72,7 +63,6 @@ function slog!(s, msg, id)
notify(s)
end
#=
https://github.com/MasonProtter/SumTypes.jl
We have 2 types of channels:
- normal channels (which perform basic operations)
- process channels (which need more than just qubits to perform actions)
Expand Down Expand Up @@ -152,7 +142,7 @@ end
end

@resumable function entangle(sim::Simulation, protocol::FreeQubitTriggerProtocolSimulation, network, node, remotenode, noisy_pair = noisy_pair_func(0.7)
, logfile=nothing)
, logfile=nothing, sampledentangledtimes=[nothing], entangletimedist=Exponential(0.4))
waittime = protocol.waittime
busytime = protocol.busytime
channel = network[node=>remotenode, protocol.keywords[:simple_channel]]
Expand Down Expand Up @@ -180,11 +170,16 @@ end
end

mINITIALIZE_STATE(remote_i, i) => begin
slog!(logfile, "$(now(sim)) :: $node > Waiting on entanglement generation between $node:$i and $remotenode:$remote_i ...", "$node:$i $remotenode:$remote_i")
entangletime = rand(entangletimedist)
@yield timeout(sim, entangletime)
(sampledentangledtimes[1] != false) && (push!(sampledentangledtimes[1][], entangletime))
println(sampledentangledtimes[1])
initialize!((network[node][i], network[remotenode][remote_i]),noisy_pair; time=now(sim))
slog!(logfile, "$(now(sim)) :: $node > Success! $node:$i and $remotenode:$remote_i are now entangled.", "$node:$i $remotenode:$remote_i")
unlock(network[node][i])
put!(channel, mUNLOCK(remote_i))
@yield timeout(sim, busytime)
# @yield timeout(sim, busytime)
# signal that entanglement got generated
put!(channel, mGENERATED_ENTANGLEMENT(i, remote_i, 1))
end
Expand Down Expand Up @@ -229,7 +224,7 @@ end
push!(indicesg, [])
push!(remoteindicesg, [])
end
purif_circuit_size = protocol.purifier_circuit_size
purif_circuit_size = inputqubits(protocol.purifier_circuit())
while true
message = @yield take!(remote_process_channel)
@cases message begin
Expand All @@ -249,7 +244,8 @@ end
@yield timeout(sim, busytime)

slots = [network[node][x] for x in indicesg[generation]]
local_measurement = protocol.purifier_circuit(protocol.looptype[generation % length(protocol.looptype) + 1])(slots[1], length(slots[2:end])==1 ? slots[2:end][1] : slots[2:end])
type = [protocol.looptype[(generation + i - 1) % length(protocol.looptype) + 1] for i in 1:inputqubits(protocol.purifier_circuit())-1]
local_measurement = protocol.purifier_circuit(type...)(slots...)
# send message to other node to apply purif side of circuit
put!(process_channel, mPURIFY(local_measurement, remoteindicesg[generation], indicesg[generation], generation))
indicesg[generation] = []
Expand All @@ -260,8 +256,8 @@ end
mPURIFY(remote_measurement, indices, remoteindices, generation) => begin
slots = [network[node][x] for x in indices]
@yield timeout(sim, busytime)

local_measurement = protocol.purifier_circuit(protocol.looptype[generation % length(protocol.looptype) + 1])(slots[1], length(slots[2:end])==1 ? slots[2:end][1] : slots[2:end])
type = [protocol.looptype[(generation + i - 1) % length(protocol.looptype) + 1] for i in 1:inputqubits(protocol.purifier_circuit())-1]
local_measurement = protocol.purifier_circuit(type...)(slots...)
success = local_measurement == remote_measurement
put!(process_channel, mREPORT_SUCCESS(success, remoteindices, indices, generation))
if !success
Expand Down

0 comments on commit 25b2173

Please sign in to comment.