Commit 961bab06 authored by Bentriou Mahmoud's avatar Bentriou Mahmoud

I've implemented another way of dispatching check_constraints and

update_state functions but performance gets worst.
With bench/pkg/abstract_arrays.jl i've highligthed each time a function
is in a collection performance gets worst.
parent 0ffb9f9d
This diff is collapsed.
using Profile
using StaticArrays
using BenchmarkTools
println("Cost of tests:")
f_test(a::Int) = a == 2
@btime for i = 1:20
f_test(3)
end
# First container type
abstract type SuperType end
for i = 1:10
include_string(Main, "struct Type$i <: SuperType v::Symbol end")
include_string(Main, "f(item::Type$i, a::Int) = a == $(i)")
end
vec_types = SuperType[]
for i = 1:20
rand_number_type = rand(1:10)
@eval item = $(Symbol("Type$(rand_number_type)"))(:test)
push!(vec_types, item)
end
println("First super type")
function read(vec_types::Vector{SuperType}, a::Int)
for item in vec_types
f(item, a)
end
end
@btime read(vec_types, 3)
# Second container type
struct AnotherSuperType{T<:Function}
v::Symbol
f::T
end
vec_others_types = AnotherSuperType[]
for i = 1:20
rand_number_type = rand(1:10)
include_string(Main, "f_other_$(i)(a::Int) = a == $(i)")
sym_func = Symbol("f_other_$i")
@eval push!(vec_others_types, AnotherSuperType(:test, $(sym_func)))
end
println("Second super type")
function read(vec_others_types::Vector{AnotherSuperType}, a::Int)
for item in vec_others_types
item.f(a)
end
end
@btime read(vec_others_types, 3)
# With vectors
println("Transitions first:")
vec_tr = Union{Nothing,Symbol}[]
vec_func = Function[]
for i = 1:20
rand_number_type = rand(1:10)
include_string(Main, "f_vec_$(i)(a::Int) = a == $(i)")
sym_func = Symbol("f_vec_$i")
push!(vec_tr, :test)
@eval push!(vec_func, $(sym_func))
end
function read(vec_tr::Vector{Union{Nothing,Symbol}}, vec_func::Vector{Function}, a::Int)
for i = eachindex(vec_tr)
my_func = vec_func[i]
my_func(a)
end
end
@btime read(vec_tr, vec_func, 3)
println("Transitions second:")
vec_tr = Union{Nothing,Symbol}[]
vec_func = Function[]
for i = 1:20
rand_number_type = rand(1:10)
name_func = Symbol("f_vec2_$(i)")
str_func = "$(name_func)(a::Int) = a == $(rand_number_type)"
include_string(Main, str_func)
push!(vec_tr, :test)
@eval push!(vec_func, $(name_func))
end
@btime read(vec_tr, vec_func, 3)
# How to store and read efficiently abstract types ?
d = Dict{Symbol,Dict{Symbol,Vector{Float64}}}()
for i = 1:10
sym_a = Symbol("a$i")
sym_b = Symbol("a$i")
d[sym_a] = Dict{Symbol,Vector{Float64}}()
d[sym_a][sym_b] = zeros(4)
end
function f(dict::Dict)
for key in keys(dict)
for key2 in keys(dict[key])
for i = eachindex(dict[key][key2])
dict[key][key2][i]
end
end
end
end
@btime f(d)
using StaticArrays
using BenchmarkTools
using MarkovProcesses
using Profile
load_model("ER")
observe_all!(ER)
set_param!(ER, [:k1, :k2], [0.2, 40.0])
set_time_bound!(ER, 0.9)
load_automaton("automaton_G_and_F")
x1, x2, t1, t2 = 50.0, 100.0, 0.0, 0.8
x3, x4, t3, t4 = 30.0, 100.0, 0.8, 0.9
A_G_F = create_automaton_G_and_F(ER, x1, x2, t1, t2, :E,
x3, x4, t3, t4, :P)
sync_ER = ER * A_G_F
S = init_state(A_G_F, ER.x0, ER.t0)
time = 0.1
values = S.values
x, p = ER.x0, ER.p
for loc_from in keys(A_G_F.map_edges)
for loc_to in keys(A_G_F.map_edges[loc_from])
println("$loc_from => $loc_to")
for i = eachindex(A_G_F.map_edges[loc_from][loc_to])
println("edge $i:")
global global_edge = A_G_F.map_edges[loc_from][loc_to][i]
#@btime check_constraints_AutomatonGandF(global_edge, time, $(copy(values)), x, p)
#b = @benchmark check_constraints_AutomatonGandF(global_edge, time, $(copy(values)), x, p)
#@show mean(b).time, mean(b).memory
end
end
end
function my_find_edge_candidates!(edge_candidates::Vector{EdgeAutomatonGandF},
edges_from_current_loc::Dict{Location,Vector{EdgeAutomatonGandF}},
Λ::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(edges_from_current_loc)
if !Λ[target_loc](x) continue end
for i = eachindex(edges_from_current_loc[target_loc])
edge = edges_from_current_loc[target_loc][i]
test_cc = check_constraints_AutomatonGandF(edge, S_time, S_values, x, p)
if test_cc
if edge.transitions == nothing
_push_edge!(edge_candidates, edge, nbr_candidates)
nbr_candidates += 1
return nbr_candidates
else
if !only_asynchronous
_push_edge!(edge_candidates, edge, nbr_candidates)
nbr_candidates += 1
end
end
end
end
end
return nbr_candidates
end
function svector_find_edge_candidates!(edge_candidates::Vector{EdgeAutomatonGandF},
edges_from_current_loc::Dict,
Λ::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(edges_from_current_loc)
if !Λ[target_loc](x) continue end
for edge in edges_from_current_loc[target_loc]
test_cc = check_constraints_AutomatonGandF(edge, S_time, S_values, x, p)
if test_cc
if edge.transitions == nothing
_push_edge!(edge_candidates, edge, nbr_candidates)
nbr_candidates += 1
return nbr_candidates
else
if !only_asynchronous
_push_edge!(edge_candidates, edge, nbr_candidates)
nbr_candidates += 1
end
end
end
end
end
return nbr_candidates
end
edge_candidates = Vector{EdgeAutomatonGandF}(undef, 2)
edges_from_current_loc = getfield(A_G_F, :map_edges)[:l1G]
Λ = A_G_F.Λ
function transform_dict_tuple(dict::Dict{Symbol,Dict{Symbol,Vector{EdgeAutomatonGandF}}})
new_dict = Dict()
for from_loc in keys(dict)
for to_loc in keys(dict[from_loc])
new_dict[from_loc] = (to_loc, dict[from_loc][to_loc])
end
end
return new_dict
end
function transform_dict_static(dict::Dict{Symbol,Dict{Symbol,Vector{EdgeAutomatonGandF}}})
new_dict = Dict{Symbol,Dict{Symbol,SVector}}()
for from_loc in keys(dict)
new_dict[from_loc] = Dict{Symbol,SVector}()
for to_loc in keys(dict[from_loc])
d = dict[from_loc][to_loc]
new_dict[from_loc][to_loc] = SVector{length(d)}(d)
end
end
return new_dict
end
new_map_edges = transform_dict_tuple(A_G_F.map_edges)
new_edges_from_current_loc = new_map_edges[:l1G]
vec_edges = new_map_edges[:l1G][2]
#concrete_vec_edges = Vector{typeof(vec_edges[1])}(vec_edges)
svector_map_edges = transform_dict_static(A_G_F.map_edges)
svector_edges_from_current_loc = svector_map_edges[:l1G]
static_vec_edges = SVector{length(vec_edges)}(vec_edges)
tuple_edges = Tuple(vec_edges)
println("Test of the current implementation")
@btime begin
for target_loc in keys(edges_from_current_loc)
for edge in edges_from_current_loc[target_loc]
test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p)
end
end
end
println("Test with pairs")
@btime begin
for pair_target_loc_edges in edges_from_current_loc
for edge in pair_target_loc_edges.second
test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p)
end
end
end
println("New map")
@btime begin
for target_loc_edges in new_edges_from_current_loc
for edge in new_edges_from_current_loc[2]
test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p)
end
end
end
println("Read of a edge vector 1 (collection iteration)")
@btime begin
for edge in vec_edges
test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p)
end
end
println("Read of a edge vector 2 (eachindex)")
@btime begin
for i = eachindex(vec_edges)
test_cc = check_constraints_AutomatonGandF(vec_edges[i], time, values, x, p)
end
end
println("Read of a edge vector 3 (steprange)")
@btime begin
for i = 1:length(vec_edges)
test_cc = check_constraints_AutomatonGandF(vec_edges[i], time, values, x, p)
end
end
println("Read of a edge vector 4 (steprange 2)")
nb_edges = length(vec_edges)
@btime begin
for i = 1:nb_edges
test_cc = check_constraints_AutomatonGandF(vec_edges[i], time, values, x, p)
end
end
println("Read of an edge vector 5 (static vectors)")
@btime begin
for i = eachindex(static_vec_edges)
test_cc = check_constraints_AutomatonGandF(static_vec_edges[i], time, values, x, p)
end
end
println("Read of an edge vector 6 (tuples)")
@show typeof(tuple_edges)
@btime begin
for i = eachindex(tuple_edges)
test_cc = check_constraints_AutomatonGandF(tuple_edges[i], time, values, x, p)
end
end
#=
println("Read of an edge vector 7 (concrete type)")
@show typeof(vec_edges)
@show typeof(concrete_vec_edges)
@btime begin
for edge in concrete_vec_edges
#test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p)
end
end
=#
println("Read of an edge vector 8 (concrete type v2)")
@show vec_edges
concrete_2_vec_edges = Vector{Union{Nothing,Vector{Symbol}}}([e.transitions for e in vec_edges])
@btime begin
for i = eachindex(concrete_2_vec_edges)
concrete_2_vec_edges[i]
#test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p)
end
end
b_find = @benchmark _find_edge_candidates!(edge_candidates, edges_from_current_loc, Λ, time, values, x, p, false)
@show mean(b_find).time, mean(b_find).memory
b_svector_find = @benchmark svector_find_edge_candidates!(edge_candidates, svector_edges_from_current_loc, Λ, time, values, x, p, false)
@show mean(b_svector_find).time, mean(b_svector_find).memory
Profile.clear_malloc_data()
b_myfind = @benchmark my_find_edge_candidates!(edge_candidates, edges_from_current_loc, Λ, time, values, x, p, false)
@show mean(b_myfind).time, mean(b_myfind).memory
#=
The problem is that in each step of these benchmarks, an abstract type is involved
=#
......@@ -18,7 +18,7 @@ export Distribution, Product, Uniform, Normal
# Common types and constructors
export Observations, AbstractTrajectory, Trajectory, SynchronizedTrajectory
export Model, ContinuousTimeModel, SynchronizedModel, ParametricModel
export VariableModel, ParameterModel, Transition
export VariableModel, ParameterModel, Transition, TransitionSet
export LHA, StateLHA, Edge, Location, VariableAutomaton
# Trajectory related methods
......
......@@ -11,6 +11,7 @@ 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
......@@ -55,6 +56,9 @@ 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
......
This diff is collapsed.
......@@ -145,7 +145,9 @@ 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_candidates = Vector{$(edge_type)}(undef, 2)
edge_id_candidates = zeros(Int, 2)
target_loc_candidates = Vector{Symbol}(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
......@@ -164,7 +166,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_candidates; verbose = verbose)
x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_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
......@@ -180,7 +182,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_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -195,7 +197,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_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_id_candidates, target_loc_candidates; verbose = verbose)
copyto!(xn, vec_x)
tn = l_t[1]
tr_n = l_tr[1]
......@@ -214,7 +216,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_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -239,7 +241,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_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_id_candidates, target_loc_candidates; verbose = verbose)
copyto!(xn, vec_x)
tn = l_t[1]
tr_n = l_tr[1]
......@@ -265,7 +267,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_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -280,13 +282,15 @@ 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_candidates = Vector{$(edge_type)}(undef, 2)
edge_id_candidates = zeros(Int, 2)
target_loc_candidates = Vector{Symbol}(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_candidates; verbose = verbose)
x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_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
......@@ -297,7 +301,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_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......@@ -314,7 +318,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_candidates; verbose = verbose)
vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
copyto!(xn, vec_x)
tn = l_t[1]
tr_n = l_tr[1]
......@@ -323,7 +327,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_candidates; verbose = verbose)
xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
end
setfield!(S, :loc, ptr_loc_state[1])
setfield!(S, :time, ptr_time_state[1])
......
Markdown is supported
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