All those allocations are from the x = A\b:
──────────────────────────────────────────────────────────────────
Time Allocations
────────────────────── ───────────────────────
Tot / % measured: 415ms / 0.01% 60.9MiB / 0.11%
Section ncalls time %tot avg alloc %tot avg
──────────────────────────────────────────────────────────────────
solve 1 26.0μs 90.2% 26.0μs 69.1KiB 100% 69.1KiB
loop 1 2.82μs 9.76% 2.82μs 0.00B 0.00% 0.00B
──────────────────────────────────────────────────────────────────
This is the output of:
Code
using StaticArrays
using LinearAlgebra
using BenchmarkTools
using TimerOutputs
function LS5(p,points,values,neighbours)
numNeighbours = length(neighbours[p])::Int;
vec1=SA_F64[1.0,2.0,3.0]; vec2=SA_F64[2.0,3.0,4.0];
A=zeros(MMatrix{7,2});
b=zeros(MVector{7});
@timeit tmr "loop" for n in 1:numNeighbours
neighbour = neighbours[p][n]::Int;
A[n,1] = dot(vec1,points[neighbour]-points[p]);
A[n,2] = dot(vec2,points[neighbour]-points[p]);
b[n] = values[neighbour]-values[p];
end
@timeit tmr "solve" x = A \ b
return x[1]*vec1 + x[2]*vec2;
end
const tmr=TimerOutput()
points = [SVector{3}(rand(3)) for _ in 1:100];
neighbours = []
for i in 1:100
numNeighbours = rand(4:7);
push!(neighbours,(rand(1:100,numNeighbours)));
end
values = rand(100);
LS5(1,points,values,neighbours)
@show tmr
Indeed, I don’t know why is that. Maybe a separate thread to understand that is important. Minimal working example:
Example
julia> A = MMatrix{2,2,Float64}(rand(2,2))
2×2 MMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
0.768859 0.337918
0.338688 0.791925
julia> b = MVector{2,Float64}(rand(2))
2-element MVector{2, Float64} with indices SOneTo(2):
0.23421653608437043
0.4320080108699409
julia> A\b
2-element MVector{2, Float64} with indices SOneTo(2):
0.07988759245908458
0.5113500762999404
julia> ldiv!(qr(A),b)
ERROR: MethodError: no method matching ldiv!(::StaticArrays.QR{MMatrix{2, 2, Float64, 4}, MMatrix{2, 2, Float64, 4}, MVector{2, Int64}}
, ::MVector{2, Float64})
Closest candidates are:
Yes, indeed. With variable sizes you will have problems in general. Particularly, since static arrays have the size in their type, variables sizes means variable types. Data structures like that one I think are better approached with different strategies (vectors containing all data, and linked lists to point where each set starts, and the number of elements of each one).
(also it is a good idea to use neighbours = Vector{Int}[], so that this is not a vector of Any)