allocation with v.*="x"on SparseArrays
The following code allocates 128 bytes in julia 1.9 & 1.10 (also in previous julia versions). However, when using dense vectors, it doesn't allocate.
using SparseArrays
const v=spzeros(10)
v[1]=4
f(v) = v.*=4
@allocated f(v)
Currently the workaround is using map!(f, v,v)
Do note that another solution is nonzeros(v) .*= 4.
The culprit is that broadcast is only for unaliased vector (unalised refers to the left and right-hand side sharing memory, here both matrices are the same, so they naturally share vector) because it may or may not change the structure. map! on the other hand only works on the nonzero elements so it is safe to apply to aliased vector
using SparseArrays
function f(x, y)
for i in 1:10000
y .= x .* 1.1
x .= y .* (1 / 1.1)
end
x
end
x = spzeros(10)
x[1] = 3
y = copy(x)
@time f(x, y)
@time f(x, y)
gives
0.094615 seconds (271.80 k allocations: 18.823 MiB, 99.75% compilation time)
0.000205 seconds
@ViralBShah we could optimize this for fixed sparse matrices, what do you think?
I suppose that makes sense. @Wimmerer ?
I'm not convinced we can't optimize this within the semantics of sparse broadcast.
So we only trigger a copy if the structure changes or just do it inplace?