In place Cholesky solve with zero allocation (simplical vs. supernodal)

I replaced CHOLMOD’s allocation routines with a self-managed buffer and can confirm that CHOLMOD is allocating. And yes, I am cognisant of the sanity (or lack thereof) of this debugging approach, I blame the ease of Julia’s C FFI!

cholmodptrs = Vector{Ptr{Cvoid}}()
cholmodheap = Vector{Vector{UInt8}}()

function logmalloc(size::Csize_t)
  mem = Vector{UInt8}(undef, size)
  ptr = Ptr{Cvoid}(pointer(mem))
  push!(cholmodheap, mem)
  push!(cholmodptrs, ptr)
  println("CHOLMOD requests malloc of $size bytes, given $ptr")
  return ptr
end

function logfree(ptr::Ptr{Cvoid})
  i = findall(x->x == ptr, cholmodptrs)
  if length(i) > 0
    sz = length(cholmodheap[i[1]])
    println("CHOLMOD requests free of $sz bytes from pointer $ptr")
  else
    println("CHOLMOD requests free of unmanaged pointer")
  end
  return nothing
end

logmalloc_ptr = @cfunction(logmalloc, Ptr{Cvoid}, (Csize_t,))
logfree_ptr = @cfunction(logfree, Cvoid, (Ptr{Cvoid},))

cnfg = cglobal((:SuiteSparse_config, :libsuitesparseconfig), Ptr{Cvoid})
unsafe_store!(cnfg, cglobal(logmalloc_ptr, Ptr{Cvoid}), 1)
unsafe_store!(cnfg, cglobal(logfree_ptr, Ptr{Cvoid}), 4)

This shows that:

julia> _solve!(X, Yref, Eref, F_simple, B);
CHOLMOD requests free of unmanaged pointer
CHOLMOD requests free of unmanaged pointer
CHOLMOD requests malloc of 56 bytes, given Ptr{Nothing} @0x0000000118c5c200
CHOLMOD requests malloc of 9600 bytes, given Ptr{Nothing} @0x00007fcff2a04c80

julia> _solve!(X, Yref, Eref, F_simple, B);
CHOLMOD requests free of 9600 bytes from pointer Ptr{Nothing} @0x00007fcff2a04c80
CHOLMOD requests free of 56 bytes from pointer Ptr{Nothing} @0x0000000118c5c200
CHOLMOD requests malloc of 56 bytes, given Ptr{Nothing} @0x0000000118c5c4d0
CHOLMOD requests malloc of 9600 bytes, given Ptr{Nothing} @0x00007fcff2af7680

Thus on each call a (perfectly valid AFAIK) buffer is released and reallocated. I note that 9600 bytes is (4 x sizeof(double) x N) where N is the size of the RHS in the solve. Off to read CHOLMOD’s source code to determine where this is happening.

1 Like