# Should an in-place FunctionOperator be totally allocation free?

**URL:** <https://discourse.julialang.org/t/should-an-in-place-functionoperator-be-totally-allocation-free/111219>\
**Category:** General Usage\
**Tags:** sciml\
**Created:** [March 5, 2024, 10:31pm UTC](https://discourse.julialang.org/t/should-an-in-place-functionoperator-be-totally-allocation-free/111219 "2024-03-05T22:31:27Z")\
**Posts on this page:** 3\
**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:** [March 5, 2024, 10:31pm UTC](https://discourse.julialang.org/t/should-an-in-place-functionoperator-be-totally-allocation-free/111219/1 "2024-03-05T22:31:27Z")

</div>

The code

```julia
    fop = FunctionOperator((v, u, p, t) -> mul!(v, K_ff, u), F_f, zeros(length(F_f)))
    prob = LinearProblem(fop, F_f)
    @time sol = solve(prob, ALG(), Pl=PRECOND, verbose=verbose)

```

reports allocations:

```julia
  7.333552 seconds (966 allocations: 25.764 MiB)

```

More than if I use MatrixOperator.

```julia
    mop = MatrixOperator(K_ff)
    prob = LinearProblem(mop, F_f)
    @time sol = solve(prob, ALG(), Pl=PRECOND, verbose=verbose)

```

yields

```julia
  7.140111 seconds (42 allocations: 25.693 MiB)

```

I am guessing the allocations must be some small change, given that the amount of allocated memory is nearly the same? But: is this as expected or am I doing something wrong?

---

<div class="post-metadata">

**Author:** ![Joris\_Pinkse](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joris_pinkse/32/216398_2.png) [@Joris\_Pinkse](https://discourse.julialang.org/u/Joris_Pinkse)\
**Post date:** [March 6, 2024, 3:24am UTC](https://discourse.julialang.org/t/should-an-in-place-functionoperator-be-totally-allocation-free/111219/2 "2024-03-06T03:24:59Z")

</div>

> [@PetrKryslUCSD](#):
>
> ```julia
> fop = FunctionOperator((v, u, p, t) -> mul!(v, K_ff, u), F_f, zeros(length(F_f)))
> prob = LinearProblem(fop, F_f)
> @time sol = solve(prob, ALG(), Pl=PRECOND, verbose=verbose)
> 
> ```

Could you please post some complete working code, so others can experiment?

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [March 6, 2024, 11:54am UTC](https://discourse.julialang.org/t/should-an-in-place-functionoperator-be-totally-allocation-free/111219/3 "2024-03-06T11:54:18Z")

</div>

To me, this smells like the usual issue of boxing in closures.

Try e.g.

```julia
fop = let K = K_ff, F = F_f
FunctionOperator((v, u, p, t) -> mul!(v, K, u), F, zeros(length(F)))
end

```

But ideally, don’t use closures – it sucks to audit them for boxing. Or are there good linters that reliably warn about closures that box? Then enable that for your project.

Instead define a nice type

```julia
struct Wrapper{KT, FT} <: Function
K::KT
F::FT
end
(w::Wrapper)(v, u, p, t) = (mul!(v, w.K, u), w.F, zeros(length(w.F)))
fop = FunctionOperator(Wrapper(K_ff, F_f))

```

In my view, capture-by-binding is a total language misfeature in julia; ideally we’d have capture-by-value.

Luckily you can have capture-by-value semantics in a well-defined subset of julia – you just need to stick to only capturing SSA values. Ideally with help of a linter that complains whenever you capture something that is not SSA.
