# Are there ways to preallocate memory via structs for JuMP autodiff?

**URL:** <https://discourse.julialang.org/t/are-there-ways-to-preallocate-memory-via-structs-for-jump-autodiff/102945>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, memory-allocation, forwarddiff, autodiff\
**Created:** [August 18, 2023, 12:09pm UTC](https://discourse.julialang.org/t/are-there-ways-to-preallocate-memory-via-structs-for-jump-autodiff/102945 "2023-08-18T12:09:46Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![told](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/told/32/17083_2.png) [@told](https://discourse.julialang.org/u/told)\
**Post date:** [August 18, 2023, 12:09pm UTC](https://discourse.julialang.org/t/are-there-ways-to-preallocate-memory-via-structs-for-jump-autodiff/102945/1 "2023-08-18T12:09:46Z")

</div>

I’m very aware of the limitations of ForwardDiff.jl that code has to be written general enough to accept `{T<:Real}`. The JuMP docs [suggest](https://jump.dev/JuMP.jl/stable/manual/nlp/#Common-mistakes-when-writing-a-user-defined-function) to write target functions like

```julia
function good_f(x::T...) where {T<:Real}
    y = zeros(T, length(x)) # Construct an array of type `T` instead!
    for i = 1:length(x)
        y[i] = x[i]^i
    end
    return sum(y)
end

```

I want to try to optimize a huge system where the target function will depend on varying combination of structs where type and needed allocations are known before optimization. Therefore, preallocation would be highly desired, e.g. I want to achieve something like:

```julia

struct PreAlloc
    y::Vector{<:Real}
end

Y = PreAlloc(zeros(T, length(x)))

function good_f(x::T, Y::PreAlloc) where {T<:Real}
    for i = 1:length(x)
        Y.y[i] = x[i]^i
    end
    return sum(Y.y)
end

```

Now this will fail to allocate into `Y.y` because the types won’t match during the autodiff pass. I know that SciML solves this problem via [PreallocationTools.jl](https://docs.sciml.ai/PreallocationTools/stable/).

Is there a way to achieve something similar within the JuMP framework?

---

<div class="post-metadata">

**Author:** ![ccoffrin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ccoffrin/32/400_2.png) [@ccoffrin](https://discourse.julialang.org/u/ccoffrin)\
**Post date:** [August 19, 2023, 3:00pm UTC](https://discourse.julialang.org/t/are-there-ways-to-preallocate-memory-via-structs-for-jump-autodiff/102945/2 "2023-08-19T15:00:20Z")

</div>

This is side stepping your question a little bit, but why not just put your expression into JuMP directly? Like this,

```julia
@NLobjective(m, Min, sum(x[i]^i for i in 1:length(x)))

```

In this case JuMP will handle the memory for you and it is quite efficient about it.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [August 20, 2023, 8:58pm UTC](https://discourse.julialang.org/t/are-there-ways-to-preallocate-memory-via-structs-for-jump-autodiff/102945/3 "2023-08-20T20:58:20Z")

</div>

I haven’t tried, but presumably you can use `PreallocationTools` directly. There’s nothing special about JuMP’s use of ForwardDiff.

You could always just do something like this:

```julia
julia> cache = Dict{Any,Any}()
Dict{Any, Any}()

julia> function good_f(x::T...) where {T}
           if !haskey(cache, T)
               cache[T] = zeros(T, length(x))
           end
           y = cache[T]::Vector{T}
           for i = 1:length(x)
               y[i] = x[i]^i
           end
           return sum(y)
       end
good_f (generic function with 1 method)

julia> 

julia> good_f(1, 2)
5

julia> good_f(1.0, 2.0)
5.0

julia> cache
Dict{Any, Any} with 2 entries:
  Int64 => [1, 4]
  Float64 => [1.0, 4.0]

julia> good_f(1.0, 3.0)
10.0

julia> cache
Dict{Any, Any} with 2 entries:
  Int64 => [1, 4]
  Float64 => [1.0, 9.0]

```
