It looks like Matrix operations while using StaticArrays in a struct is causing allocations. I am using StaticArrays.jl for Julia 0.6. I created a foobar example to illustrate what I encountered. Hopefully, someone can shed some light on what is happening and how to make the code allocation free.
using StaticArrays
struct Foo{N,T}
x::SMatrix{N,N,T}
y::SVector{N,T}
Foo{N,T}(x::SMatrix{N,N,T}, y::SVector{N,T}) where {N,T} = new(x, y)
end
function mult{N,T}(x::Foo{N,T})
z = x.x * x.y
z
end
function measure_mult(x)
@allocated mult(x)
end
function profilemult()
x = SMatrix{2,2,Float32}(rand(2,2))
y = SVector{2,Float32}(rand(2))
f = Foo{2,Float32}(x,y)
println("mult", '\t', measure_mult(f))
end
profilemult() # prints "mult 32"
function mult1{N,T}(x::SMatrix{N,N,T}, y::SVector{N,T})
z = x * y
z
end
function measure_mult1(x, y)
@allocated mult1(x, y)
end
function profilemult1()
x = SMatrix{2,2,Float32}(rand(2,2))
y = SVector{2,Float32}(rand(2))
println("mult1", '\t', measure_mult1(x,y))
end
profilemult1() # prints "mult1 0"
I am new to Julia but using @code_warntype
on mult
seems to indicate some kind of type stability.
Variables:
#self# <optimized out>
x::Foo{2,Float32}
z::Any
Body:
begin
SSAValue(0) = (Core.getfield)(x::Foo{2,Float32}, :x)::StaticArrays.SArray{Tuple{2,2},Float32,2,L} where L
z::Any = (StaticArrays._mul)((StaticArrays.Size)(SSAValue(0))::StaticArrays.Size{(2, 2)}, $(QuoteNode(Size(2,))), SSAValue(0), (Core.getfield)(x::Foo{2,Float32}, :y)::StaticArrays.SArray{Tuple{2},Float32,1,2})::Any # line 99:
return z::Any
end::Any
Any inputs are appreciated. I am working on an application that requires to keep state using static arrays which cannot have any allocations.