rusandris / StateTransitionNetworks.jl

Toolkit for dynamics on state transition networks
1 stars 0 forks source link

`lyapunov_measure` takes too long to compile (type instability) #16

Open rusandris opened 5 months ago

rusandris commented 5 months ago

The method lyapunov_measure(P::AbstractMatrix; x, alg, ϵ, maxiter) takes too long to compile, it is probably caused by a type instability.


@code_warntype lyapunov_measure(P)
MethodInstance for StateTransitionNetworks.lyapunov_measure(::SparseArrays.SparseMatrixCSC{Float64, Int64})
  from lyapunov_measure(P::AbstractMatrix; x, alg, ϵ, maxiter) @ StateTransitionNetworks ~/Documents/stn_research/StateTransitionNetworks.jl/src/network_measures.jl:84
Arguments
  #self#::Core.Const(StateTransitionNetworks.lyapunov_measure)
  P::SparseArrays.SparseMatrixCSC{Float64, Int64}
Body::Tuple{Any, Float64, Any, Symbol}
1 ─ %1 = StateTransitionNetworks.:(var"#lyapunov_measure#20")(StateTransitionNetworks.nothing, StateTransitionNetworks.hybrid_solve, 1.0e-12, 1000, #self#, P)::Tuple{Any, Float64, Any, Symbol}
└──      return %1

It also causes network_measures(P::AbstractMatrix; x, ϵ, maxiter, alg) to compile slowly.


@code_warntype network_measures(P)
MethodInstance for StateTransitionNetworks.network_measures(::SparseArrays.SparseMatrixCSC{Float64, Int64})
  from network_measures(P::AbstractMatrix; x, ϵ, maxiter, alg) @ StateTransitionNetworks ~/Documents/stn_research/StateTransitionNetworks.jl/src/network_measures.jl:15
Arguments
  #self#::Core.Const(StateTransitionNetworks.network_measures)
  P::SparseArrays.SparseMatrixCSC{Float64, Int64}
Body::Tuple{Float64, Any}
1 ─ %1 = StateTransitionNetworks.:(var"#network_measures#18")(StateTransitionNetworks.nothing, 1.0e-12, 1000, StateTransitionNetworks.hybrid_solve, #self#, P)::Tuple{Float64, Any}
└──      return %1
rusandris commented 5 months ago

For example, compiling network_measures the first time takes:

@time network_measures(P)
  5.208723 seconds (8.04 M allocations: 530.105 MiB, 4.73% gc time, 99.98% compilation time)
rusandris commented 5 months ago

Using non-abstract types in the PseudoDenseMatrix methods helps solving some of the problems.


@time lyapunov_measure(P;x=x,ϵ=1e-5,maxiter=10000)
  2.426644 seconds (2.17 M allocations: 147.874 MiB, 1.68% gc time, 99.98% compilation time)
(0.17603232681159775, 0.40545810980692853, -0.22942578299533078, :Success)

See fix here 7dd1d1b.

There are some variables that are still unstable, so it needs some more care.


julia> @code_warntype lyapunov_measure(P;x=x,ϵ=1e-5,maxiter=10000)
MethodInstance for Core.kwcall(::@NamedTuple{x::Vector{Float64}, ϵ::Float64, maxiter::Int64}, ::typeof(lyapunov_measure), ::SparseMatrixCSC{Float64, Int64})
  from kwcall(::NamedTuple, ::typeof(lyapunov_measure), P::SparseMatrixCSC) @ StateTransitionNetworks ~/Documents/stn_research/StateTransitionNetworks.jl/src/network_measures.jl:80
Arguments
  _::Core.Const(Core.kwcall)
  @_2::@NamedTuple{x::Vector{Float64}, ϵ::Float64, maxiter::Int64}
  @_3::Core.Const(StateTransitionNetworks.lyapunov_measure)
  P::SparseMatrixCSC{Float64, Int64}
Locals
  x::Union{}
  alg::Union{}
  ϵ::Union{}
  maxiter::Union{}
  @_9::Any