In the following code, I was surprised that the pointer for L.L.data isn’t the same as the pointer to B, L.UL.data, L.U.data.
using LinearAlgebra, Random, BenchmarkTools
T = Float64
D = 3
rng = Random.Xoshiro(0)
function myfunc!(B, A)
copy!(B, A)
L = cholesky!(B)
return L
end
A = randn(T, D, D)
A = A'*A
B = copy(A)
@btime myfunc!($B, $A)
L = myfunc!(B, A)
pointer_vec = [pointer(L.U.data); pointer(L.L.data); pointer(L.UL.data); pointer(B)]
display(pointer_vec)
My REPL showed:
162.419 ns (0 allocations: 0 bytes)
4-element Vector{Ptr{Float64}}:
Ptr{Float64} @0x00007f93a66647a0
Ptr{Float64} @0x00007f9428ff5b20
Ptr{Float64} @0x00007f93a66647a0
Ptr{Float64} @0x00007f93a66647a0
The timing is from @btime, and indicates no allocation. The L.L.data seems to be referencing the transpose of the same matrix as B:
julia> norm(L.L.data - B')
0.0
It is true that a pointer to B transposed can be a different value than B? If so, why does it seem that myfun! avoided (heap) allocation for the new address of L.L.data?
Ultimately, I’m trying to figure out if cholesky! allocates if I pre-allocated all its arguments. AllocCheck.jl seems to pass just fine:
using AllocCheck
@check_allocs testfunc!(a,b) = myfunc!(a,b)
testfunc!(B, A) # no errors when I run this line in the REPL