# Confusing memory allocations when using the integrator of DifferentialEquations.jl

**URL:** https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436
**Category:** Performance
**Tags:** question, diffeq, memory-allocation
**Created:** [January 11, 2022, 9:31pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436 "2022-01-11T21:31:53Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![duan](https://avatars.discourse-cdn.com/v4/letter/d/a9adbd/32.png) [@duan](https://discourse.julialang.org/u/duan)
#### Post date: [January 11, 2022, 9:31pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/1 "2022-01-11T21:31:53Z")

</div>

Here is a prototype of my problem:

```julia
using OrdinaryDiffEq
n = 2^18;
u0 = rand(ComplexF64, n);

function f(du, u, p, t)
    for i in 1:length(u)
        du[i] = -1.0im * u[i]
    end
    return
end

mutable struct A
    u0::Vector{ComplexF64}
    integrator

    function A(u0)
        a = new()
        a.u0 = u0
        prob = ODEProblem(f, u0, (0, 1), nothing)
        a.integrator = init(prob, Tsit5(), save_on=false, save_start=false, save_end=false, calck=false, alias_u0=true, abstol=1e-8, reltol=1e-8);
        return a
    end
end

function g(u1, u2)
    x = 0.0im
    for i in 1:length(u1)
        x += u1[i] * conj(u2[i])
    end
    return x
end

function g2(a::A)
    u1 = a.u0
    u2 = a.integrator.u
    x = 0.0im
    for i in 1:length(u1)
        x += u1[i] * conj(u2[i])
    end
    return x
end

a = A(u0);
step!(a.integrator, 1, true)

```

Basically, `g()` and `g2()` calculate the dot product of the initial and final states. (Yes, I could have used `dot()`, but this is a prototype.) Naively, I expect they behave similarly. It turns out that `g2()` allocates extra memory in each call. Can someone please give me some insight? Thanks!

```nohighlight
julia> @time g(a.u0, a.integrator.u)
  0.000627 seconds (1 allocation: 32 bytes)
174863.6176038208 + 0.0im

julia> @time g2(a)
  0.042788 seconds (1.57 M allocations: 43.992 MiB, 36.44% gc time)
174863.6176038208 + 0.0im

```

---

<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: [January 11, 2022, 9:42pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/2 "2022-01-11T21:42:57Z")

</div>

Your struct isn’t type stable. Specifically, the compiler can’t figure out what the type of `a.integrator` is.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 11, 2022, 9:50pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/3 "2022-01-11T21:50:30Z")

</div>

```julia
mutable struct A{I}
    u0::Vector{ComplexF64}
    integrator::I

```

---

<div class="post-metadata">

### Author: ![duan](https://avatars.discourse-cdn.com/v4/letter/d/a9adbd/32.png) [@duan](https://discourse.julialang.org/u/duan)
#### Post date: [January 11, 2022, 11:13pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/4 "2022-01-11T23:13:31Z")

</div>

Indeed. Since I know the type of a.integrator.u, the problem is fixed by redefining `g2()`.

```julia
function g2(a::A)
    u1 = a.u0
    u2 = a.integrator.u::Vector{ComplexF64}
    x = 0.0im
    for i in 1:length(u1)
        x += u1[i] * conj(u2[i])
    end
    return x
end

```

---

<div class="post-metadata">

### Author: ![duan](https://avatars.discourse-cdn.com/v4/letter/d/a9adbd/32.png) [@duan](https://discourse.julialang.org/u/duan)
#### Post date: [January 11, 2022, 11:16pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/5 "2022-01-11T23:16:10Z")

</div>

It would work except that the concrete type of an ODE integrator is very complicated 😓

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 11, 2022, 11:18pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/6 "2022-01-11T23:18:48Z")

</div>

That’s why you just parameterize it as `I`.

---

<div class="post-metadata">

### Author: ![duan](https://avatars.discourse-cdn.com/v4/letter/d/a9adbd/32.png) [@duan](https://discourse.julialang.org/u/duan)
#### Post date: [January 11, 2022, 11:22pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/7 "2022-01-11T23:22:07Z")

</div>

In my problem I don’t know the concrete type of the integrator until during the construction of the structure …

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 11, 2022, 11:29pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/8 "2022-01-11T23:29:20Z")

</div>

You don’t need to. Use parametric typing.

```julia
struct A{T}
  x::T
end

A(2.0) # A{Float64}(2.0)
A(2) # A{Int}(2)

```

---

<div class="post-metadata">

### Author: ![duan](https://avatars.discourse-cdn.com/v4/letter/d/a9adbd/32.png) [@duan](https://discourse.julialang.org/u/duan)
#### Post date: [January 11, 2022, 11:35pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/9 "2022-01-11T23:35:19Z")

</div>

In the code example I posted, the type of `a.integrator` is known inside the constructor. It is given by `init()`depending on the parameters I chose.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 11, 2022, 11:52pm UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/10 "2022-01-11T23:52:58Z")

</div>

```julia
mutable struct A{I}
    u0::Vector{ComplexF64}
    integrator::I

    function A(u0)
        u0 = u0
        prob = ODEProblem(f, u0, (0, 1), nothing)
        integrator = init(prob, Tsit5(), save_on=false, save_start=false, save_end=false, calck=false, alias_u0=true, abstol=1e-8, reltol=1e-8);
        return new(u0,integrator)
    end
end

```

---

<div class="post-metadata">

### Author: ![duan](https://avatars.discourse-cdn.com/v4/letter/d/a9adbd/32.png) [@duan](https://discourse.julialang.org/u/duan)
#### Post date: [January 12, 2022, 12:28am UTC](https://discourse.julialang.org/t/confusing-memory-allocations-when-using-the-integrator-of-differentialequations-jl/74436/11 "2022-01-12T00:28:46Z")

</div>

Thanks for the suggestions @ChrisRackauckas. I misremembered. I actually passed `a` as the last parameter to `ODEProblem()` (replacing `nothing`) in the real code. Because Julia doesn’t support mutual reference, I defined `a.integrator` not in the constructor but in a separate function.
