|
@@ -4,6 +4,8 @@ using InteractiveUtils
|
|
|
using TimerOutputs
|
|
using TimerOutputs
|
|
|
const Timer = TimerOutput()
|
|
const Timer = TimerOutput()
|
|
|
|
|
|
|
|
|
|
+PRECISION::Float64 = 1e-6
|
|
|
|
|
+
|
|
|
@enum Transitions NONE INTERNAL EXTERNAL CONFLUENT
|
|
@enum Transitions NONE INTERNAL EXTERNAL CONFLUENT
|
|
|
|
|
|
|
|
@agent struct AtomicDEVS{I, O}(NoSpaceAgent)
|
|
@agent struct AtomicDEVS{I, O}(NoSpaceAgent)
|
|
@@ -11,13 +13,28 @@ const Timer = TimerOutput()
|
|
|
out_ports::O = NamedTuple()
|
|
out_ports::O = NamedTuple()
|
|
|
|
|
|
|
|
last_event_time::Float64 = 0.0
|
|
last_event_time::Float64 = 0.0
|
|
|
- next_ta::Float64 = -1.0 # -1, initialization needed
|
|
|
|
|
|
|
+ next_ta::Float64 = -1.0 # -1, initialisation needed
|
|
|
|
|
|
|
|
is_imminent::Bool = false
|
|
is_imminent::Bool = false
|
|
|
is_receiving::Bool = false
|
|
is_receiving::Bool = false
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
# DEVS Interface (To be extended by the modeler)
|
|
# DEVS Interface (To be extended by the modeler)
|
|
|
|
|
+function confluent_transition! end
|
|
|
|
|
+const conf_transition! = confluent_transition!
|
|
|
|
|
+
|
|
|
|
|
+function external_transition! end
|
|
|
|
|
+const ext_transition! = external_transition!
|
|
|
|
|
+
|
|
|
|
|
+function internal_transition! end
|
|
|
|
|
+const int_transition! = internal_transition!
|
|
|
|
|
+
|
|
|
|
|
+function time_advance end
|
|
|
|
|
+const ta = time_advance
|
|
|
|
|
+
|
|
|
|
|
+function output! end
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
function confluent_transition!(agent, model, bag)
|
|
function confluent_transition!(agent, model, bag)
|
|
|
internal_transition!(agent, model)
|
|
internal_transition!(agent, model)
|
|
|
external_transition!(agent, model, 0.0, bag)
|
|
external_transition!(agent, model, 0.0, bag)
|
|
@@ -28,7 +45,7 @@ time_advance(agent, model) = error("time_advance not implemented for $(typeof(ag
|
|
|
output!(agent, model) = nothing
|
|
output!(agent, model) = nothing
|
|
|
|
|
|
|
|
function simulate_devs!(model, duration::Float64=Inf)
|
|
function simulate_devs!(model, duration::Float64=Inf)
|
|
|
- @timeit Timer "Simulation Loop" begin
|
|
|
|
|
|
|
+# @timeit Timer "Simulation Loop" begin
|
|
|
if model.logging !== nothing && isempty(model.event_logs)
|
|
if model.logging !== nothing && isempty(model.event_logs)
|
|
|
if model.logging == ""
|
|
if model.logging == ""
|
|
|
print_initial_conditions(model)
|
|
print_initial_conditions(model)
|
|
@@ -58,14 +75,16 @@ function simulate_devs!(model, duration::Float64=Inf)
|
|
|
export_trace_to_csv(model, model.logging)
|
|
export_trace_to_csv(model, model.logging)
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
- end
|
|
|
|
|
- show(Timer)
|
|
|
|
|
- println()
|
|
|
|
|
- reset_timer!(Timer)
|
|
|
|
|
|
|
+# end
|
|
|
|
|
+# show(Timer)
|
|
|
|
|
+# println()
|
|
|
|
|
+# reset_timer!(Timer)
|
|
|
end
|
|
end
|
|
|
|
|
+const simulate_devs!(model, duration::Integer) = simulate_devs!(model, Float64(duration))
|
|
|
|
|
+
|
|
|
|
|
|
|
|
function send_message!(agent, model, port::Symbol, msg)
|
|
function send_message!(agent, model, port::Symbol, msg)
|
|
|
- @timeit Timer "Send Message" begin
|
|
|
|
|
|
|
+# @timeit Timer "Send Message" begin
|
|
|
if model.logging !== nothing
|
|
if model.logging !== nothing
|
|
|
if !haskey(model.out_log, agent.id)
|
|
if !haskey(model.out_log, agent.id)
|
|
|
model.out_log[agent.id] = Dict{Symbol, Vector{Any}}()
|
|
model.out_log[agent.id] = Dict{Symbol, Vector{Any}}()
|
|
@@ -90,7 +109,7 @@ function send_message!(agent, model, port::Symbol, msg)
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
- end
|
|
|
|
|
|
|
+# end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function route_outputs!(model)
|
|
function route_outputs!(model)
|
|
@@ -171,33 +190,33 @@ function transition!(model, current_time, triggering_agent_id)
|
|
|
empty!(model.requeue_buffer)
|
|
empty!(model.requeue_buffer)
|
|
|
|
|
|
|
|
for id in model.imminent
|
|
for id in model.imminent
|
|
|
- @timeit Timer "Process Imminent" process_imminent!(
|
|
|
|
|
- model[id],
|
|
|
|
|
- model,
|
|
|
|
|
- current_time,
|
|
|
|
|
- triggering_agent_id
|
|
|
|
|
- )
|
|
|
|
|
-# process_imminent!(
|
|
|
|
|
|
|
+# @timeit Timer "Process Imminent" process_imminent!(
|
|
|
# model[id],
|
|
# model[id],
|
|
|
# model,
|
|
# model,
|
|
|
# current_time,
|
|
# current_time,
|
|
|
# triggering_agent_id
|
|
# triggering_agent_id
|
|
|
# )
|
|
# )
|
|
|
- end
|
|
|
|
|
-
|
|
|
|
|
- for id in model.active_receivers
|
|
|
|
|
- @timeit Timer "Process Receivers" process_receiver!(
|
|
|
|
|
|
|
+ process_imminent!(
|
|
|
model[id],
|
|
model[id],
|
|
|
model,
|
|
model,
|
|
|
current_time,
|
|
current_time,
|
|
|
triggering_agent_id
|
|
triggering_agent_id
|
|
|
)
|
|
)
|
|
|
-# process_receiver!(
|
|
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+ for id in model.active_receivers
|
|
|
|
|
+# @timeit Timer "Process Receivers" process_receiver!(
|
|
|
# model[id],
|
|
# model[id],
|
|
|
# model,
|
|
# model,
|
|
|
# current_time,
|
|
# current_time,
|
|
|
# triggering_agent_id
|
|
# triggering_agent_id
|
|
|
# )
|
|
# )
|
|
|
|
|
+ process_receiver!(
|
|
|
|
|
+ model[id],
|
|
|
|
|
+ model,
|
|
|
|
|
+ current_time,
|
|
|
|
|
+ triggering_agent_id
|
|
|
|
|
+ )
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
for id in model.imminent
|
|
for id in model.imminent
|
|
@@ -211,13 +230,13 @@ function transition!(model, current_time, triggering_agent_id)
|
|
|
empty!(model.imminent)
|
|
empty!(model.imminent)
|
|
|
empty!(model.active_receivers)
|
|
empty!(model.active_receivers)
|
|
|
|
|
|
|
|
- @timeit Timer "Requeue Events" begin
|
|
|
|
|
|
|
+# @timeit Timer "Requeue Events" begin
|
|
|
for req_id in model.requeue_buffer
|
|
for req_id in model.requeue_buffer
|
|
|
agent = model[req_id]
|
|
agent = model[req_id]
|
|
|
-# Agents.add_event!(agent, model)
|
|
|
|
|
- @timeit Timer "Agents.jl Add Event" Agents.add_event!(agent, model)
|
|
|
|
|
|
|
+ Agents.add_event!(agent, model)
|
|
|
|
|
+# @timeit Timer "Agents.jl Add Event" Agents.add_event!(agent, model)
|
|
|
end
|
|
end
|
|
|
- end
|
|
|
|
|
|
|
+# end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function devs_step!(agent, model)
|
|
function devs_step!(agent, model)
|
|
@@ -229,7 +248,7 @@ function devs_step!(agent, model)
|
|
|
|
|
|
|
|
target_time = agent.last_event_time + agent.next_ta
|
|
target_time = agent.last_event_time + agent.next_ta
|
|
|
|
|
|
|
|
- if abs(current_time - target_time) <= 1e-9
|
|
|
|
|
|
|
+ if abs(current_time - target_time) <= PRECISION
|
|
|
if !agent.is_imminent
|
|
if !agent.is_imminent
|
|
|
agent.is_imminent = true
|
|
agent.is_imminent = true
|
|
|
push!(model.imminent, agent.id)
|
|
push!(model.imminent, agent.id)
|
|
@@ -241,16 +260,16 @@ function devs_step!(agent, model)
|
|
|
is_last_in_batch = true
|
|
is_last_in_batch = true
|
|
|
if !isempty(queue)
|
|
if !isempty(queue)
|
|
|
next_time = first(queue)[2]
|
|
next_time = first(queue)[2]
|
|
|
- if abs(next_time - current_time) <= 1e-9
|
|
|
|
|
|
|
+ if abs(next_time - current_time) <= PRECISION
|
|
|
is_last_in_batch = false
|
|
is_last_in_batch = false
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
if is_last_in_batch && !isempty(model.imminent)
|
|
if is_last_in_batch && !isempty(model.imminent)
|
|
|
- @timeit Timer "Route Outputs" route_outputs!(model)
|
|
|
|
|
- @timeit Timer "Transitions" transition!(model, current_time, agent.id)
|
|
|
|
|
-# route_outputs!(model)
|
|
|
|
|
-# transition!(model, current_time, agent.id)
|
|
|
|
|
|
|
+# @timeit Timer "Route Outputs" route_outputs!(model)
|
|
|
|
|
+# @timeit Timer "Transitions" transition!(model, current_time, agent.id)
|
|
|
|
|
+ route_outputs!(model)
|
|
|
|
|
+ transition!(model, current_time, agent.id)
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|