Commit c5af570e authored by Bentriou Mahmoud's avatar Bentriou Mahmoud
Browse files

Go back to the best performance version of bench/pkg/sim_sync_R6.jl

parent 961bab06
This diff is collapsed.
......@@ -11,7 +11,6 @@ abstract type Edge end
const VariableModel = Symbol
const ParameterModel = Symbol
const Transition = Union{Symbol,Nothing}
const TransitionSet = Union{Vector{Symbol},Nothing}
const Location = Symbol
const VariableAutomaton = Symbol
......@@ -56,9 +55,6 @@ function generate_code_lha_type_def(lha_name::Symbol, edge_type::Symbol)
map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in values
flow::Dict{Location,Vector{Float64}} # output of length nvar
map_edges::Dict{Location, Dict{Location,Vector{$(edge_type)}}}
map_edges_transitions::Dict{Location, Dict{Location,Vector{TransitionSet}}}
map_edges_check_constraints::Dict{Location, Dict{Location,Vector{Function}}}
map_edges_update_state::Dict{Location, Dict{Location,Vector{Function}}}
constants::Dict{Symbol,Float64}
map_var_model_idx::Dict{VariableModel,Int} # of dim d (of a model)
end
......
......@@ -90,234 +90,8 @@ function init_state(A::LHA, x0::Vector{Int}, t0::Float64)
return S0
end
function generate_code_next_state_with_dicts_lha(lha_name::Symbol, edge_type::Symbol)
return quote
# A push! method implementend by myself because of preallocation of edge_candidates
function _push_edge!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol},
edge_id::Int, target_loc::Symbol, nbr_candidates::Int)
if nbr_candidates < length(edge_id_candidates)
edge_id_candidates[nbr_candidates+1] = edge_id
target_loc_candidates[nbr_candidates+1] = target_loc
else
push!(edge_id_candidates, edge_id)
push!(target_loc_candidates, target_loc)
end
end
function _find_edge_candidates!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol},
dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}},
dict_check_constraints_from_current_loc::Dict{Location,Vector{Function}},
Λ::Dict{Location,Function},
S_time::Float64, S_values::Vector{Float64},
x::Vector{Int}, p::Vector{Float64},
only_asynchronous::Bool)
nbr_candidates = 0
for target_loc in keys(dict_transitions_from_current_loc)
if !Λ[target_loc](x) continue end
for i = eachindex(dict_transitions_from_current_loc[target_loc])
check_constraints_edge = dict_check_constraints_from_current_loc[target_loc][i]
if check_constraints_edge(S_time, S_values, x, p)
transitions = dict_transitions_from_current_loc[target_loc][i]
if transitions == nothing
_push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates)
nbr_candidates += 1
return nbr_candidates
else
if !only_asynchronous
_push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates)
nbr_candidates += 1
end
end
end
end
end
return nbr_candidates
end
function _get_edge_index(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, nbr_candidates::Int,
dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}},
detected_event::Bool, tr_nplus1::Transition)
ind_edge = 0
bool_event = detected_event
for i = 1:nbr_candidates
target_loc = target_loc_candidates[i]
edge_id = edge_id_candidates[i]
transitions = dict_transitions_from_current_loc[target_loc][edge_id]
# Asynchronous edge detection: we fire it
if transitions == nothing
return (i, detected_event)
end
# Synchronous detection
if !detected_event && tr_nplus1 != nothing
if (transitions[1] == :ALL) || (tr_nplus1 in transitions)
ind_edge = i
bool_event = true
end
end
end
return (ind_edge, bool_event)
end
function next_state!(A::$(lha_name),
ptr_loc_state::Vector{Symbol}, values_state::Vector{Float64}, ptr_time_state::Vector{Float64},
xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition,
xn::Vector{Int}, p::Vector{Float64},
edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}; verbose::Bool = false)
# En fait d'apres observation de Cosmos, après qu'on ait lu la transition on devrait stop.
detected_event::Bool = false
turns = 0
Λ = getfield(A, :Λ)
flow = getfield(A, :flow)
map_edges = A.map_edges
map_edges_transitions = A.map_edges_transitions
map_edges_check_constraints = A.map_edges_check_constraints
map_edges_update_state = A.map_edges_update_state
if verbose
println("##### Begin next_state!")
@show xnplus1, tnplus1, tr_nplus1
end
# First, we check the asynchronous transitions
while true
turns += 1
if verbose @show turns end
#edge_candidates = empty!(edge_candidates)
dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]]
dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]]
# Save all edges that satisfies transition predicate (asynchronous ones)
nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates,
dict_transitions_from_current_loc, dict_check_constraints_from_current_loc,
Λ, ptr_time_state[1], values_state, xn, p, true)
# Search the one we must chose, here the event is nothing because
# we're not processing yet the next event
ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates,
dict_transitions_from_current_loc,
detected_event, nothing)
# Update the state with the chosen one (if it exists)
# Should be xn here
#first_round = false
if ind_edge > 0
edge_target_loc = target_loc_candidates[ind_edge]
edge_id = edge_id_candidates[ind_edge]
firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id]
ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xn, p)
else
if verbose
println("No edge fired:")
@show ind_edge, detected_event, nbr_candidates
end
break
end
if verbose
println("Edge fired:")
@show edge_id_candidates, target_loc_candidates
@show ind_edge, detected_event, nbr_candidates
@show ptr_loc_state[1]
@show ptr_time_state[1]
@show values_state
if turns == 500
@warn "We've reached 500 turns"
end
end
# For debug
#=
if turns > 100
println("Number of turns in next_state! is suspicious")
@show first_round, detected_event
@show length(edge_candidates)
@show tnplus1, tr_nplus1, xnplus1
@show edge_candidates
error("Unpredicted behavior automaton")
end
=#
end
if verbose
println("Time flies with the flow...")
end
# Now time flies according to the flow
for i in eachindex(values_state)
coeff_deriv = flow[ptr_loc_state[1]][i]
if coeff_deriv > 0
values_state[i] += coeff_deriv*(tnplus1 - ptr_time_state[1])
end
end
ptr_time_state[1] = tnplus1
if verbose
@show ptr_loc_state[1]
@show ptr_time_state[1]
@show values_state
end
# Now firing an edge according to the event
while true
turns += 1
if verbose @show turns end
edges_from_current_loc = map_edges[ptr_loc_state[1]]
dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]]
dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]]
# Save all edges that satisfies transition predicate (synchronous ones)
nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates,
dict_transitions_from_current_loc, dict_check_constraints_from_current_loc,
Λ, ptr_time_state[1], values_state, xnplus1, p, false)
# Search the one we must chose
ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates,
dict_transitions_from_current_loc,
detected_event, tr_nplus1)
# Update the state with the chosen one (if it exists)
if ind_edge > 0
edge_target_loc = target_loc_candidates[ind_edge]
edge_id = edge_id_candidates[ind_edge]
firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id]
ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xnplus1, p)
end
if ind_edge == 0 || detected_event
if verbose
if detected_event
println("Synchronized with $(tr_nplus1)")
@show edge_id_candidates, target_loc_candidates
@show ind_edge, detected_event, nbr_candidates
@show detected_event
@show ptr_loc_state[1]
@show ptr_time_state[1]
@show values_state
else
println("No edge fired")
end
end
break
end
if verbose
@show edge_id_candidates, target_loc_candidates
@show ind_edge, detected_event, nbr_candidates
@show detected_event
@show ptr_loc_state[1]
@show ptr_time_state[1]
@show values_state
if turns == 500
@warn "We've reached 500 turns"
end
end
# For debug
#=
if turns > 100
println("Number of turns in next_state! is suspicious")
@show detected_event
@show length(edge_candidates)
@show tnplus1, tr_nplus1, xnplus1
@show edge_candidates
error("Unpredicted behavior automaton")
end
=#
end
if verbose
println("##### End next_state!")
end
end
end
end
############################################################################################################
function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
function generate_code_next_state(lha_name::Symbol, edge_type::Symbol,
check_constraints::Symbol, update_state!::Symbol)
return quote
# A push! method implementend by myself because of preallocation of edge_candidates
......@@ -339,8 +113,8 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
for target_loc in keys(edges_from_current_loc)
if !Λ[target_loc](x) continue end
for edge in edges_from_current_loc[target_loc]
if edge.check_constraints(S_time, S_values, x, p)
if edge.transitions == nothing
if $(check_constraints)(edge, S_time, S_values, x, p)
if getfield(edge, :transitions) == nothing
_push_edge!(edge_candidates, edge, nbr_candidates)
nbr_candidates += 1
return nbr_candidates
......@@ -363,12 +137,13 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
for i = 1:nbr_candidates
edge = edge_candidates[i]
# Asynchronous edge detection: we fire it
if edge.transitions == nothing
if getfield(edge, :transitions) == nothing
return (i, detected_event)
end
# Synchronous detection
if !detected_event && tr_nplus1 != nothing
if (edge.transitions[1] == :ALL) || (tr_nplus1 in edge.transitions)
if (getfield(edge, :transitions)[1] == :ALL) ||
(tr_nplus1 in getfield(edge, :transitions))
ind_edge = i
bool_event = true
end
......@@ -409,7 +184,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
#first_round = false
if ind_edge > 0
firing_edge = edge_candidates[ind_edge]
ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xn, p)
ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xn, p)
else
if verbose println("No edge fired") end
break
......@@ -465,7 +240,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
# Update the state with the chosen one (if it exists)
if ind_edge > 0
firing_edge = edge_candidates[ind_edge]
ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xnplus1, p)
ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xnplus1, p)
end
if ind_edge == 0 || detected_event
if verbose
......
......@@ -145,9 +145,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
time_bound = getfield(m, :time_bound)
buffer_size = getfield(m, :buffer_size)
estim_min_states = getfield(m, :estim_min_states)
#edge_candidates = Vector{$(edge_type)}(undef, 2)
edge_id_candidates = zeros(Int, 2)
target_loc_candidates = Vector{Symbol}(undef, 2)
edge_candidates = Vector{$(edge_type)}(undef, 2)
# First alloc
full_values = Vector{Vector{Int}}(undef, getfield(m, :dim_state))
for i = eachindex(full_values) full_values[i] = zeros(Int, estim_min_states) end
......@@ -166,7 +164,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
xn = copy(x0)
tn = copy(t0)
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose)
isabsorbing::Bool = $(isabsorbing)(p_sim,xn)
isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A)
# Alloc of vectors where we stock n+1 values
......@@ -182,7 +180,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
end
if isabsorbing && !isacceptedLHA
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -197,7 +195,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
break
end
n += 1
next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose)
copyto!(xn, vec_x)
tn = l_t[1]
tr_n = l_tr[1]
......@@ -216,7 +214,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
end
if isabsorbing && !isacceptedLHA
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -241,7 +239,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
i -= 1
break
end
next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose)
copyto!(xn, vec_x)
tn = l_t[1]
tr_n = l_tr[1]
......@@ -267,7 +265,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
end
if isabsorbing && !isacceptedLHA
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -282,15 +280,13 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
ptr_loc_state = [S.loc]
values_state = S.values
ptr_time_state = [S.time]
#edge_candidates = Vector{$(edge_type)}(undef, 2)
edge_id_candidates = zeros(Int, 2)
target_loc_candidates = Vector{Symbol}(undef, 2)
edge_candidates = Vector{$(edge_type)}(undef, 2)
# Values at time n
n = 1
xn = copy(x0)
tn = copy(t0)
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose)
isabsorbing::Bool = $(isabsorbing)(p_sim,xn)
isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A)
# Alloc of vectors where we stock n+1 values
......@@ -301,7 +297,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
if isabsorbing || isacceptedLHA
if !isacceptedLHA
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -318,7 +314,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
break
end
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose)
copyto!(xn, vec_x)
tn = l_t[1]
tr_n = l_tr[1]
......@@ -327,7 +323,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
end
if isabsorbing && !isacceptedLHA
next_state!(A, ptr_loc_state, values_state, ptr_time_state,
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment