# IDA is allocating a lot

**URL:** <https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383>\
**Category:** Modelling & Simulations\
**Tags:** question, package, sundials\
**Created:** [April 1, 2024, 5:59pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383 "2024-04-01T17:59:54Z")\
**Posts on this page:** 9\
**Page:** 2

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [April 2, 2024, 6:08pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/21 "2024-04-02T18:08:24Z")

</div>

What if you manually trigger the gc at every iteration so that garbage is not piling up and each invokation becomes faster?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:10pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/22 "2024-04-02T18:10:40Z")

</div>

I tried that, with Julia 1.10 and multi-threaded garbage collection it makes things worse…

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 7:09pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/23 "2024-04-02T19:09:53Z")

</div>

I am trying to use the `integrator` interface with the DFBDF solver. Is that supposed to work?

I have the following code:  
Source: [KiteModels.jl/mwes/mwe\_09.jl at main · ufechner7/KiteModels.jl · GitHub](https://github.com/ufechner7/KiteModels.jl/blob/main/mwes/mwe_09.jl)

which fails with the following error message:

```julia
ERROR: LoadError: MethodError: Cannot `convert` an object of type Float64 to an object of type Vector{Vector{Float64}}

Closest candidates are:
  convert(::Type{Array{T, N}}, ::StaticArraysCore.SizedArray{S, T, N, N, Array{T, N}}) where {S, T, N}
   @ StaticArrays ~/.julia/packages/StaticArrays/EHHaF/src/SizedArray.jl:88
  convert(::Type{Array{T, N}}, ::StaticArraysCore.SizedArray{S, T, N, M, TData} where {M, TData<:AbstractArray{T, M}}) where {T, S, N}
   @ StaticArrays ~/.julia/packages/StaticArrays/EHHaF/src/SizedArray.jl:82
  convert(::Type{T}, ::T) where T
   @ Base Base.jl:84
  ...

Stacktrace:
 [1] __init(prob::DAEProblem{…}, alg::DFBDF{…}, timeseries_init::Float64, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{…}; saveat::Tuple{}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, save_on::Bool, save_start::Bool, save_end::Nothing, callback::Nothing, dense::Bool, calck::Bool, dt::Float64, dtmin::Float64, dtmax::Float64, force_dtmin::Bool, adaptive::Bool, gamma::Rational{…}, abstol::Nothing, reltol::Float64, qmin::Rational{…}, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, beta1::Nothing, beta2::Nothing, qoldinit::Rational{…}, controller::Nothing, fullnormalize::Bool, failfactor::Int64, maxiters::Int64, internalnorm::typeof(DiffEqBase.ODE_DEFAULT_NORM), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), progress_id::Symbol, userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::@Kwargs{})
   @ OrdinaryDiffEq ~/.julia/packages/OrdinaryDiffEq/ZbQoo/src/solve.jl:268
 [2] init_call(::DAEProblem{…}, ::DFBDF{…}, ::Vararg{…}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::@Kwargs{…})
   @ DiffEqBase ~/.julia/packages/DiffEqBase/O8cUq/src/solve.jl:530
 [3] init_up(::DAEProblem{…}, ::Nothing, ::Vector{…}, ::Nothing, ::DFBDF{…}, ::Vararg{…}; kwargs::@Kwargs{…})
   @ DiffEqBase ~/.julia/packages/DiffEqBase/O8cUq/src/solve.jl:562
 [4] init(::DAEProblem{…}, ::DFBDF{…}, ::Vararg{…}; sensealg::Nothing, u0::Nothing, p::Nothing, kwargs::@Kwargs{…})
   @ DiffEqBase ~/.julia/packages/DiffEqBase/O8cUq/src/solve.jl:544
 [5] init()
   @ Main ~/repos/KiteModels.jl/mwes/mwe_09.jl:62
 [6] top-level scope
   @ ~/repos/KiteModels.jl/mwes/mwe_09.jl:76
 [7] include(fname::String)
   @ Base.MainInclude ./client.jl:489
 [8] top-level scope
   @ REPL[1]:1
in expression starting at /home/ufechner/repos/KiteModels.jl/mwes/mwe_09.jl:76
Some type information was truncated. Use `show(err)` to see complete types.

```

This line fails:

```julia
  integrator = OrdinaryDiffEq.init(prob, solver, abstol, reltol=0.001)

```

Any idea?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [April 2, 2024, 7:56pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/24 "2024-04-02T19:56:42Z")

</div>

In general, for `DAE`s, `IDA` is the only solver that actually works (e.g. callback support).

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 7:59pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/25 "2024-04-02T19:59:40Z")

</div>

Well, then we need to fix this. IDA cannot be the answer. We cannot make it allocation free.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 8:00pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/26 "2024-04-02T20:00:30Z")

</div>

I fixed this by writing:

```julia
reltol = 0.001 * ones(length(y0))

```

Is this a bug? Should it be allowed to pass a real value instead of an array as reltol?

And I achieved a new minimum for the number of allocations:

```julia
Allocated 575 bytes per iteration!

```

Current status:

| Solver | Allocations | Time [ms] |
| --- | --- | --- |
| IDA | 938 | 0.423 |
| DFBDF | 575 | 0.620 |
| DFBDF2 | 598 | 0.652 |

Timing on Linux laptop running on battery, using a `Ryzen 7 7840u` CPU.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 8:17pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/27 "2024-04-02T20:17:27Z")

</div>

> [@Oscar\_Smith](#):
>
> e.g. callback support

I am using the `integrator` interface, therefore I do not need callback support…

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 9:54pm UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/28 "2024-04-02T21:54:55Z")

</div>

Now using the DFBDF solver… It works so much better than IDA!

 ![timing](https://global.discourse-cdn.com/julialang/original/3X/f/7/f73323fc7ed803d80da8e76195c5834d2183b612.png)

About 2.4 times less memory usage than IDA and much faster AND much more accurate!

**Testcase:** Run a flight simulation for 460s using 50ms time steps. The time in ms below is the time for finding a solution for one time step. The relative error was set to 0.0005 for both solvers. The state vector had 66 elements, a Ryzen 7950X CPU was used.

| Solver | Mem usage [GB] | Time in ms (av/max) |
| --- | --- | --- |
| DFBDF | 11.3 | 0.78 / 8.1 |
| IDA | 27.0 | 3.55 / 13.8 |

The IDA solver was - in difficult situations - unstable, resulting in an additional error of about 1.8~\% for the tether force, the DFBDF solver is perfectly stable.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 4, 2024, 10:06am UTC](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383/29 "2024-04-04T10:06:24Z")

</div>

I added the parameter `save_everystep=false` to the init() function,  
an now get even less allocations:

| Solver | Allocations | Time [ms] |
| --- | --- | --- |
| IDA | 525 | 0.165 |
| DImplicitEuler | 1 | 0.225 |
| DFBDF | 87 | 0.261 |
| DFBDF2 | 1 | 0.246 |

I also use `autodiff=false`.

Timing on Linux desktop, using a `Ryzen 7 7950X` CPU.

[Previous page](https://discourse.julialang.org/t/ida-is-allocating-a-lot/112383.md?page=1)
