StaticArrays.jl
StaticArrays.jl copied to clipboard
`mapreduce`/`mapfoldl` unrolls fully, failing to compile for large static sizes
MWE:
julia> x = SizedVector{30000}(randn(30000));
julia> 0.5 in x
ERROR: syntax: invalid syntax (memory-error out of gc handles)
Stacktrace:
[1] top-level scope
@ REPL[4]:1
[2] _mapreduce
@ ~/.julia/packages/StaticArrays/58yy1/src/mapreduce.jl:113 [inlined]
[3] in(x::Float64, a::SizedVector{30000, Float64, Vector{Float64}})
@ StaticArrays ~/.julia/packages/StaticArrays/58yy1/src/mapreduce.jl:267
[4] top-level scope
@ REPL[4]:1
[5] top-level scope
This happens because Base.in is forwarded to _mapreduce, which in turn is forwarded to _mapfoldl which is fully unrolled without any size cut-off. I.e., the current implementation does a full unroll of the loop so the code size is out of hand for S = 30000.
The broader problem is discussed in https://github.com/JuliaArrays/StaticArrays.jl/issues/439.
I see. BTW, I turn into using findfirst as a replacement and it doesn't seem to be forwarded to _mapreduce. I'm curious about would these "find" function also benefit from unrolling?
When you have more than 1000 elements in an array, then I doubt there is any function in StaticArrays.jl that would be actually faster than the plain Array implementation. Are you sure you actually need SizedVector?
I use SizedVector merely for having the length value as type parameter and avoiding push!/pop! operations at the surface level. Maybe there is a better choice for this need?
SizedArray would be fine if you accessed the data field, for example 0.5 in x.data instead of 0.5 in x. I don't really know any other types that would work better.