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