PRs adding docs or relevant information from here are welcome.
Hi @Elrod, amazing package as usual!
I’m just wondering, what do you mean by @gc_preserved being required? Is that an alternative to using @inline, or is @inline required anyway?
It is an alternative.
Julia can stack allocate mutable struct
s such as MArray
or StaticStrideArray
s, but (currently) only if they aren’t returned or passed to a non-inlined function.
So either you can inline everything, or you can use @gc_preserve
to circumvent that.
@gc_preserve
uses GC.@preserve
to protect the memory, and calls PtrArray
on the arrays, so that you have a non-owning view (regular view
s in Julia are owning).
So @gc_preserve
appears to be a decisive.
From my tests, MArray
with @inline
, and even with cutting and pasting the code to be inlined does create allocations (I need an allocation-free solve of a small linear system). So my experience with MArray
in this respect is shaky.
OTOH, with @gc_preserve
this problem goes away, and it seems that for my use case, the choice between MArray
and StridedArray
ends up as a matter of taste.
However @gc_preserve
is not exported. Would you mind a PR to StrideArraysCore to elevate @gc_preserve
to stable API status ?
As for MMatrix
: see inconsistent MArray allocation behavior with @inbounds, loop order · Issue #874 · JuliaArrays/StaticArrays.jl · GitHub
In addition to @inline
one needs to have @inbounds
at loops with nonstandard access (e.g. reverse order) to allow for allocation free behaviour.
@j-fu and @Elrod, do you guys have a minimal working example of how to use @gc_preserve instead of @inline?
So far, I’m able to run some simple tests with @inline, but can’t port that to my real code.
Thanks!
I have a working example here. Being non-allocating is absolutely mandatory, as this function may be called 100_000s of times, sometimes with eltype Float64, sometimes with eltype ForwardiDiff.Dual{…}.