# Why are there allocations in my loop depending upon how I set a variable?

**URL:** <https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819>\
**Category:** General Usage\
**Tags:** memory-allocation, type-stability\
**Created:** [January 18, 2022, 5:32pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819 "2022-01-18T17:32:45Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 5:32pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/1 "2022-01-18T17:32:45Z")

</div>

A little demo:  
 ![s](https://global.discourse-cdn.com/julialang/original/3X/3/c/3ccd16b10ef41c945a50d92e3d2be142536446d4.gif)

The thing I am trying to wrap my head around is that I observed that a broadcast to combine three vectors would allocate in a loop:

```julia
@time for step in 1:nsteps
        @. U1 = U0 + dt*V0 + ((dt^2)/2)*A0; 
end

```

yields

```julia
  3.080494 seconds (130.00 k allocations: 4.883 MiB)    

```

The number of allocations grows linearly with the upper bound of the range (`nsteps`).  
The code is not global, the loop exists inside of function.

The problem is that this doesn’t show in a trivial code, only in my original code.

I made these observations: Recall that the loop refers to the variable `dt`. The allocation trigger is this: If I compute `omega_max` from the solution of an eigenvalue problem, the loop would allocate.

```julia
    evals, evecs, nconv = eigs(K, M; nev=1, which=:LM, explicittransform=:none)
    @show omega_max = sqrt(evals[1])
    # omega_max = 2.76450e+06 
    @show dt = Float64(0.99* 2/omega_max)
    @show typeof(dt)

```

On the other hand, if I set `omega_max` to a fixed value, the loop does not allocate.

```julia
    evals, evecs, nconv = eigs(K, M; nev=1, which=:LM, explicittransform=:none)
    # @show omega_max = sqrt(evals[1])
    omega_max = 2.76450e+06 
    @show dt = Float64(0.99* 2/omega_max)
    @show typeof(dt)

```

Did I mention that it was weird?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 18, 2022, 5:34pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/2 "2022-01-18T17:34:49Z")

</div>

> [@PetrKryslUCSD](#):
>
> The code is not global, the loop exists inside of function.

Are any of the variables in the loop globals?

In general, please post minimal working examples (runnable code), not snippets.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 5:37pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/3 "2022-01-18T17:37:28Z")

</div>

No globals anywhere. The problem with MWE is that the behavior I observe is very sensitive. I tried to create a synthetic MWE, but the behavior disappeared.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 18, 2022, 5:39pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/4 "2022-01-18T17:39:08Z")

</div>

Start with a working example and start deleting things until the problem disappears …

Unless you make something that others can reproduce it’s going to be extremely hard to help you.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 5:45pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/5 "2022-01-18T17:45:48Z")

</div>

Here is the minimal working example. Unfortunately, it can’t be totally minimal, the problem would disappear.

Clone [https://github.com/PetrKryslUCSD/FinEtoolsFlexStructuresTutorials.jl](https://github.com/PetrKryslUCSD/FinEtoolsFlexStructuresTutorials.jl).  
I use Julia 1.6.5 here, but the same problem manifests with 1.7.1.  
Activate, instantiate the project, run the file [https://github.com/PetrKryslUCSD/FinEtoolsFlexStructuresTutorials.jl/blob/main/docs/src/tutorials/puzzle.jl](https://github.com/PetrKryslUCSD/FinEtoolsFlexStructuresTutorials.jl/blob/main/docs/src/tutorials/puzzle.jl)

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 18, 2022, 6:38pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/6 "2022-01-18T18:38:29Z")

</div>

This isn’t so strange: it looks like a type instability. I bet `@code_warntype` would show `omega_max::Any` when you’re computing it from `sqrt(evals[1])` (likely because `evals::Any` and likely because one of those args to `eigs` is unstable).

When you just hardcode it to be `omega_max = 2.76450e+06`, of course Julia knows it’s a `Float64` and thus can optimize it appropriately.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 7:19pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/7 "2022-01-18T19:19:48Z")

</div>

Wouldn’t be nice if it was so simple. `evals`’s type is `Vector{Float64}`.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 18, 2022, 7:21pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/8 "2022-01-18T19:21:29Z")

</div>

Are you looking at `@code_typed`? Or that `typeof` that you print out? I’m talking about the former.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 7:29pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/9 "2022-01-18T19:29:21Z")

</div>

I checked `@code_warntype`:

```julia-repl
    %216 = Main.typeof(evals)::DataType                                                                  
│ %217 = Core.tuple(%216, evals)::Tuple{DataType, Any}                                                 
│ (value@_11 = %217)                                                                            
│ %219 = Base.repr(%217)::String                                                                       
│ Base.println("(typeof(evals), evals) = ", %219)                                               
│ value@_11                                                                                     
│ (evals = Base.vect(7.64248e+12))                                                              
│ %223 = Base.getindex(evals::Vector{Float64}, 1)::Float64                                             
│ %224 = Main.sqrt(%223)::Float64                                                                      
│ (omega_max = %224)                                                                            
│ (value@_10 = %224)                                                                            
│ %227 = Base.repr(%224)::String                                                                       
│ Base.println("omega_max = sqrt(evals[1]) = ", %227)                                           
│ value@_10                                                                                     
│ %230 = (9.90000e-01 * 2)::Core.Const(1.98000e+00)                                                    
│ %231 = (%230 / omega_max)::Float64                                                                   
│ %232 = Main.Float64(%231)::Float64                                                                   
│ (dt = %232)                                                                                   
│ (value@_9 = %232)                  

```

`dt`’s type is known.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 18, 2022, 7:39pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/10 "2022-01-18T19:39:09Z")

</div>

This is all just shots in the dark because there’s not an MWE. Does `@code_warntype` give you any red flags?

It still may be something similar with constant propagation, wherein Julia can optimize with a known constant and remove a downstream type instability.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 7:40pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/11 "2022-01-18T19:40:08Z")

</div>

Sorry, the “minimal” WE is mentioned above. I have nothing leaner. And, yes, you were right about `evals`: `%217 = Core.tuple(%216, evals)::Tuple{DataType, Any}`.

---

<div class="post-metadata">

**Author:** ![raminammour](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raminammour/32/13572_2.png) [@raminammour](https://discourse.julialang.org/u/raminammour)\
**Post date:** [January 18, 2022, 8:02pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/12 "2022-01-18T20:02:24Z")

</div>

```julia
function f()
    evals, evecs, nconv = eigs(rand(10,10), rand(10,10); nev=1, which=:LM, explicittransform=:none)
end

@code_warntype optimize=true f()
Variables
  #self#::Core.Const(f)
  @_2::Int64
  nconv::Any
  evecs::Any
  evals::Any

```

`eigs` return type only infers as `Tuple`, that is your culprit.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 8:04pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/13 "2022-01-18T20:04:24Z")

</div>

Hmm, not convinced. `dt` is used inside the loop, and its type is known.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [January 18, 2022, 8:08pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/14 "2022-01-18T20:08:36Z")

</div>

What happens if you introduce a function barrier, i.e. separate the eigenvalue solving from the loop?

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 8:10pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/15 "2022-01-18T20:10:03Z")

</div>

> [@mbauman](#):
>
> It still may be something similar with constant propagation, wherein Julia can optimize with a known constant and remove a downstream type instability.

Created a function barrier: the allocations are gone. But how they originate it in the first place is a mystery to me.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 8:10pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/16 "2022-01-18T20:10:17Z")

</div>

Please see above.

---

<div class="post-metadata">

**Author:** ![raminammour](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raminammour/32/13572_2.png) [@raminammour](https://discourse.julialang.org/u/raminammour)\
**Post date:** [January 18, 2022, 8:16pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/17 "2022-01-18T20:16:23Z")

</div>

You see a similar type instability in a function that mimics your code, a type assertion (commented out), or a function barrier, helps:

```julia
function f()
    evals, evecs, nconv = eigs(rand(10,10), rand(10,10); nev=1, which=:LM, explicittransform=:none)
    dt=sqrt(evals[1])
    #dt::ComplexF64=sqrt(evals[1])
    s=zero(dt)
    for i in 1:1000
        s+=dt
    end
    s
end

@code_warntype optimize=true f()
Variables
  #self#::Core.Const(f)
  @_2::Union{Nothing, Tuple{Int64, Int64}}
  @_3::Int64
  s::Any
  dt::Any
  nconv::Any
  evecs::Any
  evals::Any
  i::Int64

Body::Any

```

Also, the the return of `evals[1]` from `eigs` would be either `Float64` or `ComplexF64` depending on whether the matrix is symmetric. So unless the symmetry information is communicated correctly in the type system `evals` would not infer correctly, which it doesn’t.

Hope this helps…

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 8:24pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/18 "2022-01-18T20:24:07Z")

</div>

Good point. Not sure why in my case `dt` is reported as a float by `@code_warntype`…?

Edit: I must have confused the code versions that I was running: when `dt` is evaluated from the eigenvalue solution, the correct `Any` type is deduced by `@code_warntype`. @raminammour , @mbauman were right.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 18, 2022, 11:32pm UTC](https://discourse.julialang.org/t/why-are-there-allocations-in-my-loop-depending-upon-how-i-set-a-variable/74819/19 "2022-01-18T23:32:46Z")

</div>

Thank you all helping me get to the bottom of the issue.
