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

Add NetworkSimulation #128

Draft
wants to merge 4 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## v0.4.2 - dev

- Add a `NetworkSimulation` for accessing local entanglement id counter
- Bump QuantumSymbolics and QuantumOpticsBase compat bound and bump julia compat to 1.10.

## v0.4.1 - 2024-06-05
Expand Down
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version = "0.4.2-dev"
Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76"
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
ConcurrentSim = "6ed1e86c-fcaf-46a9-97e0-2b26a2cdb499"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
Expand Down Expand Up @@ -38,6 +39,7 @@ QuantumSavoryMakie = "Makie"
Cbc = "1.2"
Combinatorics = "1"
ConcurrentSim = "1.4.1"
DataStructures = "0.18.15"
Distributions = "0.25.90"
DocStringExtensions = "0.9"
Graphs = "1.9"
Expand Down
18 changes: 9 additions & 9 deletions src/ProtocolZoo/ProtocolZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap
using DocStringExtensions

using Distributions: Geometric
using ConcurrentSim: Simulation, @yield, timeout, @process, now
using ConcurrentSim: Environment, @yield, timeout, @process, now
import ConcurrentSim: Process
import ResumableFunctions
using ResumableFunctions: @resumable
Expand All @@ -26,7 +26,7 @@ abstract type AbstractProtocol end

get_time_tracker(prot::AbstractProtocol) = prot.sim

Process(prot::AbstractProtocol, args...; kwargs...) = Process((e,a...;k...)->prot(a...;k...), get_time_tracker(prot), args...; kwargs...)
Process(prot::AbstractProtocol, args...; kwargs...) = Process((e,a...;k...)->prot(a...;k...), get_time_tracker(prot).sim, args...; kwargs...)

"""
$TYPEDEF
Expand Down Expand Up @@ -132,7 +132,7 @@ $TYPEDFIELDS
"""
@kwdef struct EntanglerProt{LT} <: AbstractProtocol where {LT<:Union{Float64,Nothing}}
"""time-and-schedule-tracking instance from `ConcurrentSim`"""
sim::Simulation # TODO check that
sim::Environment # TODO check that
"""a network graph of registers"""
net::RegisterNet
"""the vertex index of node A"""
Expand Down Expand Up @@ -164,7 +164,7 @@ $TYPEDFIELDS
end

"""Convenience constructor for specifying `rate` of generation instead of success probability and time"""
function EntanglerProt(sim::Simulation, net::RegisterNet, nodeA::Int, nodeB::Int; rate::Union{Nothing,Float64}=nothing, kwargs...)
function EntanglerProt(sim::Environment, net::RegisterNet, nodeA::Int, nodeB::Int; rate::Union{Nothing,Float64}=nothing, kwargs...)
if isnothing(rate)
return EntanglerProt(;sim, net, nodeA, nodeB, kwargs...)
else
Expand Down Expand Up @@ -233,7 +233,7 @@ $TYPEDFIELDS
"""
@kwdef struct SwapperProt{NL,NH,CL,CH,LT} <: AbstractProtocol where {NL<:Union{Int,<:Function,Wildcard}, NH<:Union{Int,<:Function,Wildcard}, CL<:Function, CH<:Function, LT<:Union{Float64,Nothing}}
"""time-and-schedule-tracking instance from `ConcurrentSim`"""
sim::Simulation
sim::Environment
"""a network graph of registers"""
net::RegisterNet
"""the vertex of the node where swapping is happening"""
Expand All @@ -255,7 +255,7 @@ $TYPEDFIELDS
end

#TODO "convenience constructor for the missing things and finish this docstring"
function SwapperProt(sim::Simulation, net::RegisterNet, node::Int; kwargs...)
function SwapperProt(sim::Environment, net::RegisterNet, node::Int; kwargs...)
return SwapperProt(;sim, net, node, kwargs...)
end

Expand Down Expand Up @@ -326,7 +326,7 @@ $TYPEDFIELDS
"""
@kwdef struct EntanglementTracker <: AbstractProtocol
"""time-and-schedule-tracking instance from `ConcurrentSim`"""
sim::Simulation
sim::Environment
"""a network graph of registers"""
net::RegisterNet
"""the vertex of the node where the tracker is working"""
Expand Down Expand Up @@ -405,7 +405,7 @@ $FIELDS
"""
@kwdef struct EntanglementConsumer{LT} <: AbstractProtocol where {LT<:Union{Float64,Nothing}}
"""time-and-schedule-tracking instance from `ConcurrentSim`"""
sim::Simulation
sim::Environment
"""a network graph of registers"""
net::RegisterNet
"""the vertex index of node A"""
Expand All @@ -418,7 +418,7 @@ $FIELDS
log::Vector{Tuple{Float64, Float64, Float64}} = Tuple{Float64, Float64, Float64}[]
end

function EntanglementConsumer(sim::Simulation, net::RegisterNet, nodeA::Int, nodeB::Int; kwargs...)
function EntanglementConsumer(sim::Environment, net::RegisterNet, nodeA::Int, nodeB::Int; kwargs...)
return EntanglementConsumer(;sim, net, nodeA, nodeB, kwargs...)
end
function EntanglementConsumer(net::RegisterNet, nodeA::Int, nodeB::Int; kwargs...)
Expand Down
5 changes: 2 additions & 3 deletions src/QuantumSavory.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module QuantumSavory

const glcnt = Ref{Int128}(0)

glcnt = Ref{Int128}(0)
function guid()
glcnt[] += 1
end
Expand All @@ -25,7 +24,7 @@ import SumTypes
using SumTypes: @sum_type, isvariant, @cases
import Combinatorics
using Combinatorics: powerset

import DataStructures
import QuantumInterface: basis, tensor, ⊗, apply!, traceout!, nsubsystems,
AbstractOperator, AbstractKet, AbstractSuperOperator, Basis, SpinBasis

Expand Down
54 changes: 54 additions & 0 deletions src/concurrentsim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,57 @@ end
Base.islocked(r::RegRef) = islocked(r.reg.locks[r.idx])
ConcurrentSim.request(r::RegRef) = request(r.reg.locks[r.idx])
Base.unlock(r::RegRef) = unlock(r.reg.locks[r.idx])

##

struct NetworkSimulation <: ConcurrentSim.Environment
sim::Simulation
glcnt::Ref{Int128}
end

function NetworkSimulation()
return NetworkSimulation(Simulation(), Ref{Int128}(0))
end

function Base.show(io::IO, env::NetworkSimulation)
if env.sim.active_proc === nothing
print(io, "$(typeof(env)) time: $(now(env.sim)) active_process: nothing")
else
print(io, "$(typeof(env)) time: $(now(env.sim)) active_process: $(env.sim.active_proc)")
end
end

function ConcurrentSim.now(env::NetworkSimulation)
env.sim.time
end

function ConcurrentSim.put!(con::ConcurrentSim.Container{N, T}, amount::N; priority=zero(T)) where {N<:Real, T<:Number}
put_ev = ConcurrentSim.Put(con.env.sim)
con.put_queue[put_ev] = ConcurrentSim.ContainerKey{N,T}(con.seid+=one(UInt), amount, T(priority))
ConcurrentSim.@callback ConcurrentSim.trigger_get(put_ev, con)
ConcurrentSim.trigger_put(put_ev, con)
put_ev
end

function ConcurrentSim.get(con::ConcurrentSim.Container{N, T}, amount::N; priority=zero(T)) where {N<:Real, T<:Number}
get_ev = ConcurrentSim.Get(con.env.sim)
con.get_queue[get_ev] = ConcurrentSim.ContainerKey(con.seid+=one(UInt), amount, T(priority))
ConcurrentSim.@callback ConcurrentSim.trigger_put(get_ev, con)
ConcurrentSim.trigger_get(get_ev, con)
get_ev
end

function ConcurrentSim.timeout(env::Environment, delay::Number=0; priority=0, value::Any=nothing)
ConcurrentSim.schedule(ConcurrentSim.Timeout(env.sim), delay; priority=Int(priority), value)
end

function ConcurrentSim.step(netsim::NetworkSimulation)
isempty(netsim.sim.heap) && throw(ConcurrentSim.EmptySchedule())
(bev, key) = DataStructures.peek(netsim.sim.heap)
DataStructures.dequeue!(netsim.sim.heap)
netsim.sim.time = key.time
bev.state = ConcurrentSim.processed
for callback in bev.callbacks
callback()
end
end
4 changes: 2 additions & 2 deletions src/messagebuffer.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
struct MessageBuffer{T}
sim::Simulation
sim::Environment
net # TODO ::RegisterNet -- this can not be typed due to circular dependency, see https://github.com/JuliaLang/julia/issues/269
node::Int
buffer::Vector{NamedTuple{(:src,:tag), Tuple{Union{Nothing, Int},T}}}
Expand Down Expand Up @@ -61,7 +61,7 @@ end
end

function MessageBuffer(net, node::Int, qs::Vector{NamedTuple{(:src,:channel), Tuple{Int, DelayQueue{T}}}}) where {T}
sim = get_time_tracker(net)
sim = get_time_tracker(net).sim
signal = IdDict{Resource,Resource}()
no_wait = Ref{Int}(0)
mb = MessageBuffer{T}(sim, net, node, Tuple{Int,T}[], signal, no_wait)
Expand Down
10 changes: 5 additions & 5 deletions src/networks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ end
function RegisterNet(graph::SimpleGraph, registers, vertex_metadata, edge_metadata, directed_edge_metadata)
env = get_time_tracker(registers[1])

all_are_at_zero = all(iszero(ConcurrentSim.now(get_time_tracker(r))) && isempty(get_time_tracker(r).heap) && isnothing(get_time_tracker(r).active_proc) for r in registers)
all_are_at_zero = all(iszero(ConcurrentSim.now(get_time_tracker(r))) && isempty(get_time_tracker(r).sim.heap) && isnothing(get_time_tracker(r).sim.active_proc) for r in registers)
all_are_same = all(env === get_time_tracker(r) for r in registers)
if !all_are_same
if all_are_at_zero
Expand All @@ -42,10 +42,10 @@ function RegisterNet(graph::SimpleGraph, registers, vertex_metadata, edge_metada
end

for (;src,dst) in edges(graph)
cchannels[src=>dst] = DelayQueue{Tag}(env, 0)
qchannels[src=>dst] = QuantumChannel(env, 0)
cchannels[dst=>src] = DelayQueue{Tag}(env, 0)
qchannels[dst=>src] = QuantumChannel(env, 0)
cchannels[src=>dst] = DelayQueue{Tag}(env.sim, 0)
qchannels[src=>dst] = QuantumChannel(env.sim, 0)
cchannels[dst=>src] = DelayQueue{Tag}(env.sim, 0)
qchannels[dst=>src] = QuantumChannel(env.sim, 0)
end
for (v,r) in zip(vertices(graph), registers)
channels = [(;src=w, channel=cchannels[w=>v]) for w in neighbors(graph, v)]
Expand Down
2 changes: 1 addition & 1 deletion src/states_registers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct Register # TODO better type description
end

function Register(traits, reprs, bg, sr, si, at)
env = ConcurrentSim.Simulation()
env = NetworkSimulation()
Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], Dict{Int128, Tuple{Tag, Int64, Float64}}(), [], nothing)
end
Register(traits,reprs,bg,sr,si) = Register(traits,reprs,bg,sr,si,zeros(length(traits)))
Expand Down
Loading