HiGHS instance and model when used in a shared library

I use JuMP.jl with HiGHS.jl to solve an optimisation problem, then generate a shared library for this using JuliaC.jl. The shared library is used within a larger software. It is loaded once (at startup), and then always the same Base.@ccallable function is called, which executes the optimisation.

It does the usual stuff, i.e.

model = Model(HiGHS.Optimizer)
# add variables, constraints, and an objective
optimize!(model)
# get values of some variables, termination status, etc.
# return extracted information

Now, we’re dealing with segfault issues.

It came to my mind that HiGHS itself again loads (via HiGHS_jll.jl) a library. Then, probably when creating the julia-level model, it creates a HiGHS instance via Highs_create. The usual C-API workflow would then be to call Highs_destroy once everything is done. Otherwise, one would just leak memory by keeping all those old HiGHS instances around, right?

How is this handled throughout the chain from JuMP.jl through MathOptInterface.jl and HiGHS.jl, down to HiGHS_jll.jl? Is there a high-level interface to free allocated memory (by destroying the HiGHS instance) before I return from the function in the shared library I create?

Thanks for any help in advance!

What I found so far:

There is a finalizer for the Optimizer (that is used from the MOI): HiGHS.jl/src/MOI_wrapper.jl at master · jump-dev/HiGHS.jl · GitHub

Some tests indicate that the finalizers are run once the GC collected (or while it is doing so) all references. The description in the docs is not very detailed / explicit about it (Essentials · The Julia Language).

The question still remains when that might happen if all is in a shared library that is kept loaded. Would it, in that case, be advisable to manually call Base.finalize on the model (or alternatively forcing the garbage collector to run via GC.gc()), before returning from the current call into the library, to make sure there is no unused, allocated memory possibly stacking up before the next automatic run of the GC?

Hi @asprionj, I’ve moved this to the optimization section of the forum.

Yes, Highs_destroy is called during the GC finaliser. You should almost certainly not call finalise yourself.

What’s the segfault? Do you have a reproducible example? I’ve never tried JuliaC with JuMP or HiGHS. (I’ve added this as an item to next week’s JuMP-dev hackathon)