Allocation with in-place sum of a transposed matrix

I need to do in-place summations of a transposed matrix and I get memory allocation in the process. For example, running function test of the following code

function test_sum_transpose(b, a)
    sum!(b, a')
end

function test_sum(b, a)
    sum!(b, a)
end

function test()
    a = [1 2 3; 3 4 5]
    b = [0.0, 0.0, 0.0]; @time test_sum_transpose(b, a)
    b = [0.0, 0.0]; @time test_sum(b, a)
    return nothing
end

I get

  0.000001 seconds (1 allocation: 16 bytes)
  0.000001 seconds

Is there any way to achieve this summation (sum the columns of a) and assign the result to b without allocations?

The @time macro isn’t suitable for microbenchmarks. The allocation numbers are not reliable. Use the BenchmarkTools package instead.

2 Likes

Also, you don’t have to create all these functions to test simple things like this. In this case it seems that there is an allocation from forming the adjoint:

julia> using BenchmarkTools

julia> a = [1 2 3; 3 4 5]; b = [0.0, 0.0];

julia> @btime sum!($b, $a);
  24.024 ns (0 allocations: 0 bytes)

julia> b = [0.0, 0.0, 0.0];

julia> @btime sum!($b, $a');
  31.165 ns (1 allocation: 16 bytes)

julia> @btime $a';
  6.489 ns (1 allocation: 16 bytes)

And, like the allocations for views, this goes away in Julia 1.5:

julia> @btime sum!($b, $a);
  19.287 ns (0 allocations: 0 bytes)

julia> @btime sum!($b, $a');
  22.419 ns (0 allocations: 0 bytes)

julia> VERSION
v"1.5.0-rc1.0"
4 Likes

“And, like the allocations for views, this goes away in Julia 1.5”

After watching a JuliaCon20 video on the new v1.5 features, It came to my mind that this problem could probably go away with the new version.

Thank you all for the replies.

Another thing I’ve noticed is that @. c = (b - a)' also allocates memory. Is this going to change in v1.5 as well?

julia> @btime @. $c = ($b - $a)'
  69.017 ns (2 allocations: 144 bytes)
2×3 Array{Int64,2}:
 9  9  11
 9  9  11