|
|
@@ -1,6 +1,8 @@
|
|
|
import DataStructures
|
|
|
using BenchmarkTools
|
|
|
using InteractiveUtils
|
|
|
+using TimerOutputs
|
|
|
+const Timer = TimerOutput()
|
|
|
|
|
|
@enum Transitions NONE INTERNAL EXTERNAL CONFLUENT
|
|
|
|
|
|
@@ -27,57 +29,64 @@ time_advance(agent, model) = error("time_advance not implemented for $(typeof(ag
|
|
|
output!(agent, model) = nothing
|
|
|
|
|
|
function simulate_devs!(model, duration::Float64=Inf)
|
|
|
- if model.logging !== nothing && isempty(model.event_logs)
|
|
|
- if model.logging == ""
|
|
|
- print_initial_conditions(model)
|
|
|
- else
|
|
|
- log_initial_conditions!(model)
|
|
|
+# @timeit Timer "Simulation Loop" begin
|
|
|
+ if model.logging !== nothing && isempty(model.event_logs)
|
|
|
+ if model.logging == ""
|
|
|
+ print_initial_conditions(model)
|
|
|
+ else
|
|
|
+ log_initial_conditions!(model)
|
|
|
+ end
|
|
|
end
|
|
|
- end
|
|
|
|
|
|
- function stop_condition(model, step_number)
|
|
|
- queue = getfield(model, :event_queue)
|
|
|
- isempty(queue) && return true
|
|
|
- next_time = first(queue)[2]
|
|
|
- return next_time > duration || next_time == Inf
|
|
|
- end
|
|
|
+ function stop_condition(model, step_number)
|
|
|
+ queue = getfield(model, :event_queue)
|
|
|
+ isempty(queue) && return true
|
|
|
+ next_time = first(queue)[2]
|
|
|
+ return next_time > duration || next_time == Inf
|
|
|
+ end
|
|
|
|
|
|
- step!(model, stop_condition)
|
|
|
+ step!(model, stop_condition)
|
|
|
|
|
|
- if model.logging !== nothing
|
|
|
- if model.logging == ""
|
|
|
- print_trace(model)
|
|
|
- else
|
|
|
- export_trace_to_csv(model, model.logging)
|
|
|
+ if model.logging !== nothing
|
|
|
+ if model.logging == ""
|
|
|
+ print_trace(model)
|
|
|
+ else
|
|
|
+ export_trace_to_csv(model, model.logging)
|
|
|
+ end
|
|
|
end
|
|
|
- end
|
|
|
+# end
|
|
|
+# show(Timer)
|
|
|
+# println()
|
|
|
+# reset_timer!(Timer)
|
|
|
end
|
|
|
|
|
|
function send_message!(agent, model, port::Symbol, msg)
|
|
|
- if model.logging !== nothing
|
|
|
- if !haskey(model.out_log, agent.id)
|
|
|
- model.out_log[agent.id] = Dict{Symbol, Vector{Any}}()
|
|
|
- end
|
|
|
- if !haskey(model.out_log[agent.id], port)
|
|
|
- model.out_log[agent.id][port] = Any[]
|
|
|
+# @timeit Timer "Send Message" begin
|
|
|
+ if model.logging !== nothing
|
|
|
+ if !haskey(model.out_log, agent.id)
|
|
|
+ model.out_log[agent.id] = Dict{Symbol, Vector{Any}}()
|
|
|
+ end
|
|
|
+ if !haskey(model.out_log[agent.id], port)
|
|
|
+ model.out_log[agent.id][port] = Any[]
|
|
|
+ end
|
|
|
+ push!(model.out_log[agent.id][port], msg)
|
|
|
end
|
|
|
- push!(model.out_log[agent.id][port], msg)
|
|
|
- end
|
|
|
|
|
|
- routes_tuple = getproperty(agent.out_ports, port)
|
|
|
- for route_vec in routes_tuple
|
|
|
- for (target_array, Z_func, target_id) in route_vec
|
|
|
+ routes_tuple = getproperty(agent.out_ports, port)
|
|
|
+ for route_vec in routes_tuple
|
|
|
+ for (target_array, Z_func, target_id) in route_vec
|
|
|
|
|
|
- translated_msg = Z_func(msg)
|
|
|
- push!(target_array, translated_msg)
|
|
|
+ translated_msg = Z_func(msg)
|
|
|
+ push!(target_array, translated_msg)
|
|
|
|
|
|
- target_agent = model[target_id]
|
|
|
- if !target_agent.is_receiving
|
|
|
- target_agent.is_receiving = true
|
|
|
- push!(model.active_receivers, target_id)
|
|
|
+ target_agent = model[target_id]
|
|
|
+ if !target_agent.is_receiving
|
|
|
+ target_agent.is_receiving = true
|
|
|
+ push!(model.active_receivers, target_id)
|
|
|
+ end
|
|
|
end
|
|
|
end
|
|
|
- end
|
|
|
+# end
|
|
|
end
|
|
|
|
|
|
function route_outputs!(model)
|
|
|
@@ -133,14 +142,12 @@ end
|
|
|
current_time,
|
|
|
triggering_agent_id
|
|
|
) where {A}
|
|
|
-
|
|
|
# imminent already handled
|
|
|
if a.is_imminent
|
|
|
return
|
|
|
end
|
|
|
|
|
|
e = current_time - a.last_event_time
|
|
|
-
|
|
|
external_transition!(a, model, e, a.inbox)
|
|
|
|
|
|
a.last_event_time = current_time
|
|
|
@@ -160,6 +167,12 @@ function transition!(model, current_time, triggering_agent_id)
|
|
|
empty!(model.requeue_buffer)
|
|
|
|
|
|
for id in model.imminent
|
|
|
+# @timeit Timer "Process Imminent" process_imminent!(
|
|
|
+# model[id],
|
|
|
+# model,
|
|
|
+# current_time,
|
|
|
+# triggering_agent_id
|
|
|
+# )
|
|
|
process_imminent!(
|
|
|
model[id],
|
|
|
model,
|
|
|
@@ -169,6 +182,12 @@ function transition!(model, current_time, triggering_agent_id)
|
|
|
end
|
|
|
|
|
|
for id in model.active_receivers
|
|
|
+# @timeit Timer "Process Receivers" process_receiver!(
|
|
|
+# model[id],
|
|
|
+# model,
|
|
|
+# current_time,
|
|
|
+# triggering_agent_id
|
|
|
+# )
|
|
|
process_receiver!(
|
|
|
model[id],
|
|
|
model,
|
|
|
@@ -188,10 +207,13 @@ function transition!(model, current_time, triggering_agent_id)
|
|
|
empty!(model.imminent)
|
|
|
empty!(model.active_receivers)
|
|
|
|
|
|
- for req_id in model.requeue_buffer
|
|
|
- agent = model[req_id]
|
|
|
- Agents.add_event!(agent, model)
|
|
|
- end
|
|
|
+# @timeit Timer "Requeue Events" begin
|
|
|
+ for req_id in model.requeue_buffer
|
|
|
+ agent = model[req_id]
|
|
|
+ Agents.add_event!(agent, model)
|
|
|
+# @timeit Timer "Agents.jl Add Event" Agents.add_event!(agent, model)
|
|
|
+ end
|
|
|
+# end
|
|
|
end
|
|
|
|
|
|
function devs_step!(agent, model)
|
|
|
@@ -224,10 +246,11 @@ function devs_step!(agent, model)
|
|
|
end
|
|
|
|
|
|
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)
|
|
|
end
|
|
|
-
|
|
|
end
|
|
|
|
|
|
function engine_timing(agent, model)
|