Uno icon indicating copy to clipboard operation
Uno copied to clipboard

Segfaults or mysterious `trunc` crashes with `UnoSolver.jl` in a custom `NLPModel`

Open cgeoga opened this issue 1 month ago • 15 comments

Hi @cvanaret

First, thanks so much again for creating such an exciting new solver and releasing it as libre software. I'm very deeply grateful.

TL;DR: I have a custom NLPModel with only box constraints that I can hand to NLPModelsIpopt.ipopt that works fine, but does not work when I hand it to UnoSolver via uno(nlp, false; preset="filtersqp") because I get a method error about not implementing hess_coord! in the constrained case. Considering that that method shouldn't (?) be called in a purely box-constrained case, I think there is some kind of communication issue between my NLPModel-type object and uno, but I can't quite figure out what it is.

Longer story:

I am trying to incorporate UnoSolver.jl as the de facto standard optimizer in my Gaussian process model fitting package Vecchia.jl using the extension system. At the moment, the solution that I am trying is to write an extension for NLPModels.jl, implement my <: AbstractNLPModel struct with the appropriate methods, and then have users pass in the necessary fields. This object of mine does not implement NLPModels.hess_prod! with the extra argument for the case of having constraints, although I have added a dummy version for now as I try to track down the issue here.

In the process of implementing the UnoSolver.jl bindings, however, I'm hitting some funny segfaults or mysterious method errors. To start, the following code snippet works:

# full file of Vecchia.jl/example/example_estimate_ipopt.jl (comments removed)
using ForwardDiff, NLPModels, NLPModelsIpopt

include("example_setup.jl")
const cfg = Vecchia.knnconfig(sim, pts, 10, matern)
solver    = NLPModelsSolver(ipopt, Dict(:tol=>1e-4))
estimator = vecchia_estimate(cfg, init[1:3], solver) 

And vecchia_estimate internally calls Vecchia.optimize in the VecchiaNLPModelsExt code here. So I think my NLPModel object is not (completely) inappropriately designed.

My problems are low-dimensional with very expensive gradients and Hessians, and so I wish to disallow using Hvps. After chatting with @amontoison I understand that I need to communicate that as follows (code link here):

    # snippet from Vecchia.jl/ext/VecchiaUnoSolverExt.jl
    nlp = Vecchia.nlp(obj, init, box_lower=box_lower, box_upper=box_upper)
    (model, solver) = uno(nlp, false; preset="filtersqp", 
                          print_solution=false, operator_available=false)
    UnoSolver.uno_get_primal_solution(solver, zeros(length(init)))
  end

But here is the rub: when I run this example code with

# full file of Vecchia.jl/example_estimate_uno.jl
using NLPModels, ForwardDiff, UnoSolver

include("example_setup.jl")
const cfg = knnconfig(sim, pts, 10, matern)

# this code triggers the function I'm showing a snippet of from Vecchia.jl/ext/VecchiaUnoSolverExt.jl
est = Vecchia.optimize(cfg, init[1:3], Vecchia.UnoNLPSolver();
                       box_lower=[1e-8, 1e-8, 0.25], 
                       box_upper=[10.0, 10.0, 5.0])

I crash with a segfault or get an error of trunc(UInt64, -138[...]) in uno_objective_gradient. However, if I add an early return to the snippet from the VecchiaUnoSolverExt.jl file linked above and then separately hand that to uno with

(model, solver) = uno(est, false; preset="filtersqp", print_solution=false)

Everything runs great so long as I have the dummy method for hess_prod! that takes the extra variable but does nothing with it.

I have a theory about what's going on, but I would not say I am very confident. I think that maybe the way that NLPModels.jl is communicating about box constraints with Uno is not quite working right. In my case where I am just box constrained, for example, I don't think I should have to implement NLPModels.hess_coord! with the extra argument y for constraints. But if I don't do that, even in the manual process of returning nlp and then handing it to uno throws a method error of

ERROR: MethodError: no method matching hess_coord!(::VecchiaNLPModelsExt.VecchiaNLPModel{…}, ::Vector{…}, ::Vector{…}, ::Vector{…}; obj_weight::Float64)

I would appreciate any thoughts or suggestions! Thank you again for the wonderful software.

cgeoga avatar Nov 18 '25 00:11 cgeoga

Can you provide your file example_setup.jl? Otherwise, we can't reproduce anything.

amontoison avatar Nov 18 '25 01:11 amontoison

@amontoison, apologies---all of the scripts are in Vecchia.jl/examples/, so if you git clone the repository (these things are pushed up to the main branch but not a tagged release, so ]add-ing won't work). But here is an easier MWE you can run after ]add-ing the other pacakges listed.

# mwe.jl
using LinearAlgebra, StaticArrays, Vecchia, BesselK, NLPModels, ForwardDiff, UnoSolver

function matern_simulate(pts, params)
  S = Symmetric([matern(x,y,params) for x in pts, y in pts])
  cholesky!(S).U'*randn(length(pts))
end

pts  = rand(SVector{2,Float64}, 1_000)
init = [2.5, 0.1, 1.1]
sim  = matern_simulate(pts, [5.0, 0.1, 2.25])

const cfg = knnconfig(sim, pts, 10, matern)

est = Vecchia.optimize(cfg, init[1:3], Vecchia.UnoNLPSolver();
                       box_lower=[1e-8, 1e-8, 0.25], 
                       box_upper=[10.0, 10.0, 5.0])

So if you checkout the main branch and comment out this line that just returns the nlp object in the extension code, running the MWE gives:

cg:example> julia --project mwe.jl 
Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation
ERROR: LoadError: TypeError: 
[69874] signal 11 (1): Segmentation fault
in expression starting at none:0
arg_tuple at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/builtins.c:940
print_to_string at ./strings/io.jl:140
string at ./strings/io.jl:193 [inlined]
showerror at ./errorshow.jl:90
#showerror#822 at ./errorshow.jl:109
showerror at ./errorshow.jl:107
unknown function (ip: 0x76bb27f58922) at (unknown file)
#showerror#823 at ./errorshow.jl:117
showerror at ./errorshow.jl:115
unknown function (ip: 0x76bb27f585f8) at (unknown file)
show_exception_stack at ./errorshow.jl:1016
display_error at ./client.jl:110
unknown function (ip: 0x76bb27f55416) at (unknown file)
display_error at ./client.jl:113
jfptr_display_error_59160.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
jl_f_invokelatest at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/builtins.c:881
exec_options at ./client.jl:320
_start at ./client.jl:550
jfptr__start_31204.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
true_main at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/jlapi.c:971
jl_repl_entrypoint at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/jlapi.c:1139
main at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/cli/loader_exe.c:58
unknown function (ip: 0x76bb3d827634) at /usr/lib/libc.so.6
__libc_start_main at /usr/lib/libc.so.6 (unknown line)
unknown function (ip: 0x4010b8) at /workspace/srcdir/glibc-2.17/csu/../sysdeps/x86_64/start.S
Allocations: 18914449 (Pool: 18914116; Big: 333); GC: 13
Segmentation fault         (core dumped) julia --project mwe.jl

If you keep the return nlp in the extension file, this MWE now runs:


using LinearAlgebra, StaticArrays, Vecchia, BesselK, NLPModels, ForwardDiff, UnoSolver

function matern_simulate(pts, params)
  S = Symmetric([matern(x,y,params) for x in pts, y in pts])
  cholesky!(S).U'*randn(length(pts))
end

pts  = rand(SVector{2,Float64}, 1_000)
init = [2.5, 0.1, 1.1]
sim  = matern_simulate(pts, [5.0, 0.1, 2.25])

const cfg = knnconfig(sim, pts, 10, matern)

# This now returns an <:AbstractNLPModel object
est = Vecchia.optimize(cfg, init[1:3], Vecchia.UnoNLPSolver();
                       box_lower=[1e-8, 1e-8, 0.25], 
                       box_upper=[10.0, 10.0, 5.0])

# This now runs fine.
(model, solver) = uno(est, false; preset="filtersqp")

For the final wrinkle, if you comment out this dummy method, you get the following error:

cg:example> julia --project mwe.jl 
Precompiling VecchiaUnoSolverExt finished.
  1 dependency successfully precompiled in 2 seconds. 85 already precompiled.
Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation

Used overwritten options:
- QP_solver = BQPD

────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter   TR iter  penalty    TR radius  step norm  objective  stationarity complementarity status        
────────────────────────────────────────────────────────────────────────────────────────────────────────
 0      -        -          1.000e+01  -          9.287e+01  1.904e+03    0.000e+00       initial point 
ERROR: LoadError: MethodError: no method matching hess_coord!(::VecchiaNLPModelsExt.VecchiaNLPModel{Vecchia.VecchiaConfig{Float64, 2, typeof(matern)}, Float64, Vector{Float64}}, ::Vector{Float64}, ::Vector{Float64}, ::Vector{Float64}; obj_weight::Float64)
The function `hess_coord!` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  hess_coord!(::VecchiaNLPModelsExt.VecchiaNLPModel{C, T, S}, ::AbstractVector{Float64}, ::AbstractVector{Float64}; obj_weight) where {C, T, S}
   @ VecchiaNLPModelsExt ~/[path_to_]Vecchia.jl/ext/VecchiaNLPModelsExt.jl:52
  hess_coord!(::AbstractNLPModel{T, S}, ::AbstractVector{T}, ::AbstractVector; obj_weight) where {T, S}
   @ NLPModels ~/.julia/packages/NLPModels/HVa0b/src/nlp/api.jl:1028

Stacktrace:
 [1] nlpmodels_lagrangian_hessian(nlp::VecchiaNLPModelsExt.VecchiaNLPModel{Vecchia.VecchiaConfig{Float64, 2, typeof(matern)}, Float64, Vector{Float64}}, hvals::Vector{Float64}, x::Vector{Float64}, multipliers::Vector{Float64}, objective_multiplier::Float64)
   @ UnoSolverNLPModelsExt ~/.julia/packages/UnoSolver/KSmNB/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:29
 [2] uno_lagrangian_hessian(number_variables::Int32, number_constraints::Int32, number_hessian_nonzeros::Int32, x::Ptr{Float64}, objective_multiplier::Float64, multipliers::Ptr{Float64}, hessian::Ptr{Float64}, user_data::Ptr{Nothing})
   @ UnoSolver ~/.julia/packages/UnoSolver/KSmNB/src/C_wrapper.jl:70
 [3] uno_optimize
   @ ~/.julia/packages/UnoSolver/KSmNB/src/libuno.jl:180 [inlined]
 [4] uno_optimize
   @ ~/.julia/packages/UnoSolver/KSmNB/src/C_wrapper.jl:336 [inlined]
 [5] #uno#1
   @ ~/.julia/packages/UnoSolver/KSmNB/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:91 [inlined]
 [6] top-level scope
[...]

cgeoga avatar Nov 18 '25 04:11 cgeoga

Hi @cgeoga,

I will take the time to read the whole thread and test the MWE, but as a first approximation: you have an objective function so the Hessian exists :) Whether or not you decide to provide it is up to you, of course. At the moment, we accept only one signature for the Hessian evaluation function, whether the problem is constrained or not:

typedef uno_int (*Hessian)(uno_int number_variables, uno_int number_constraints, uno_int number_hessian_nonzeros,
      const double* x, double objective_multiplier, const double* multipliers, double* hessian, void* user_data);

You most likely have something unconstrained such as:

hessian(uno_int number_variables, uno_int number_hessian_nonzeros, const double* x, double objective_multiplier, double* hessian, void* user_data);

correct?

@amontoison should we allow another Hessian signature for unconstrained problems in the Julia interface, and we call the Uno function with NULL multipliers under the hood?

cvanaret avatar Nov 18 '25 08:11 cvanaret

@cgeoga We expect the user to implement hess_coord! with both x and y for Uno. When the problem is unconstrained, hess_coord! without y calls hess_coord! with an empty y by default in NLPModels.jl. -> https://github.com/JuliaSmoothOptimizers/NLPModels.jl/blob/main/src/nlp/api.jl#L1054-L1082

I can modify the Julia interface to call the hess_coord! with y for people that only solve bound-constrained problems.

amontoison avatar Nov 18 '25 08:11 amontoison

@cgeoga @cvanaret I don't have any issue on my side when I run the code:

julia> (model, solver) = uno(est, false; preset="filtersqp")
Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation

Used overwritten options:
- QP_solver = BQPD

────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter   TR iter  penalty    TR radius  step norm  objective  stationarity complementarity status        
────────────────────────────────────────────────────────────────────────────────────────────────────────
 0      -        -          1.000e+01  -          2.302e+02  1.001e+03    0.000e+00       initial point 
 1      1        1.000e+00  1.000e+01  9.298e-01  1.928e+01  4.442e+03    0.000e+00       ✔ (Armijo)    
 2      1        1.000e+00  1.000e+01  1.741e+00  2.602e+03  -            -               ✘ (Armijo)    
 -      2        1.000e+00  8.705e-01  8.705e-01  5.989e+02  -            -               ✘ (Armijo)    
 -      3        1.000e+00  4.353e-01  4.353e-01  4.029e+00  7.530e+03    0.000e+00       ✔ (Armijo)    
 3      1        1.000e+00  8.705e-01  8.705e-01  -4.576e+01 4.901e+03    0.000e+00       ✔ (Armijo)    
 4      1        1.000e+00  1.741e+00  1.741e+00  5.752e+02  -            -               ✘ (Armijo)    
 -      2        1.000e+00  8.705e-01  8.705e-01  -1.285e+01 -            -               ✘ (Armijo)    
 -      3        1.000e+00  4.353e-01  4.353e-01  -6.199e+01 7.103e+02    0.000e+00       ✔ (Armijo)    
 5      1        1.000e+00  8.705e-01  8.320e-01  -6.728e+01 5.005e+02    0.000e+00       ✔ (Armijo)    
 6      1        1.000e+00  8.705e-01  4.694e-01  -6.792e+01 5.631e+01    0.000e+00       ✔ (Armijo)    
 7      1        1.000e+00  8.705e-01  8.579e-02  -6.798e+01 3.638e+00    0.000e+00       ✔ (Armijo)    
 8      1        1.000e+00  8.705e-01  2.036e-03  -6.798e+01 1.276e-02    0.000e+00       ✔ (Armijo)    
 9      1        1.000e+00  8.705e-01  8.943e-06  -6.798e+01 -            -               ✘ (Armijo)    
 -      2        1.000e+00  4.471e-06  4.471e-06  -6.798e+01 -            -               ✘ (Armijo)    
 -      3        1.000e+00  2.236e-06  2.236e-06  -6.798e+01 -            -               ✘ (Armijo)    
 -      4        1.000e+00  1.118e-06  1.118e-06  -6.798e+01 -            -               ✘ (Armijo)    
 -      5        1.000e+00  5.589e-07  5.589e-07  -6.798e+01 6.121e-05    0.000e+00       ✔ (Armijo)    
 10     1        1.000e+00  1.000e-04  8.384e-06  -6.798e+01 4.397e-08    0.000e+00       ✔ (Armijo)    
────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter   TR iter  penalty    TR radius  step norm  objective  stationarity complementarity status        
────────────────────────────────────────────────────────────────────────────────────────────────────────

Uno 2.3.1 (TR l1-merit inequality-constrained method with exact Hessian and no regularization)
Tue Nov 18 21:51:25 2025
────────────────────────────────────────
Optimization status:			Success
Solution status:			Feasible KKT point
Objective value:			-67.98349
Primal feasibility:			0
┌ Stationarity residual:		4.397406e-08
│ Primal feasibility:			0
└ Complementarity residual:		0
CPU time:				27.77381s
Iterations:				10
Objective evaluations:			19
Constraints evaluations:		0
Objective gradient evaluations:		19
Jacobian evaluations:			0
Hessian evaluations:			10
Number of subproblems solved:		18

amontoison avatar Nov 18 '25 08:11 amontoison

@amontoison should we allow another Hessian signature for unconstrained problems in the Julia interface, and we call the Uno function with NULL multipliers under the hood?

We should change nothing for the C interface. We already handle it automatically for MOI, and for NLPModels.jl I worked on a modification for Chris in #444.

amontoison avatar Nov 18 '25 09:11 amontoison

@cgeoga I did a new patch release 0.1.4 of UnoSolver.jl. I close the issue.

amontoison avatar Nov 18 '25 09:11 amontoison

@amontoison, I'm sorry but the issue is not fixed and so this issue should not be closed. The code that you ran that you observe runs fine is also the thing that I said runs fine, but I provided it as a data point to help isolate the source of the segfault, which still happens if you simply move the uno call inside the extension.

I've updated the code so that you don't have to touch any files at all to run the MWE and see the segfault. It is Vecchia.jl/examples/uno_segfault_mwe.jl, or you can just copy-paste it here:

using LinearAlgebra, StaticArrays, Vecchia, BesselK, NLPModels, ForwardDiff, UnoSolver

function matern_simulate(pts, params)
  S = Symmetric([matern(x,y,params) for x in pts, y in pts])
  cholesky!(S).U'*randn(length(pts))
end

pts  = rand(SVector{2,Float64}, 1_000)
init = [2.5, 0.1, 1.1]
sim  = matern_simulate(pts, [5.0, 0.1, 2.25])

const cfg = knnconfig(sim, pts, 10, matern)

est = Vecchia.optimize(cfg, init[1:3], Vecchia.UnoNLPSolver();
                       box_lower=[1e-8, 1e-8, 0.25], 
                       box_upper=[10.0, 10.0, 5.0])

If you look at the extension file, you can see that I've just simply moved the (model, solver) = (....) into Vecchia.optimize function. I don't know why that causes a segfault and maybe it is not related to the extra hess_coord! method. But something is still going wrong here.

cgeoga avatar Nov 18 '25 15:11 cgeoga

Okay, I have yet another confusing data point. It occurred to me that maybe the issue had to do with needing to load an NLPModels extension and then use that in the UnoSolver extension, so I jammed everything into one extension for now (pushed up on main). I now get a different segfault, that may be more informative! If you run

julia --project uno_segfault_mwe.jl

or run the script in the above comment on the main branch, you get a handful of different errors or segfaults. There are a handful of variations of the segfaults, but hopefully this is informative enough. I now think what's going on is that some integer value relating to a length or something is getting read by Uno before it is getting instantiated by julia. Does that seem plausible?

Option 1:

cg:example> julia --project uno_segfault_mwe.jl 
Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation
ERROR: LoadError: InexactError: trunc(UInt64, -1822389104)
Stacktrace:
  [1] throw_inexacterror(func::Symbol, to::Type, val::Int32)
    @ Core ./boot.jl:815
  [2] check_sign_bit
    @ ./boot.jl:821 [inlined]
  [3] toUInt64
    @ ./boot.jl:931 [inlined]
  [4] UInt64
    @ ./boot.jl:962 [inlined]
  [5] convert
    @ ./number.jl:7 [inlined]
  [6] cconvert
    @ ./essentials.jl:687 [inlined]
  [7] #unsafe_wrap#60
    @ ./pointer.jl:113 [inlined]
  [8] unsafe_wrap
    @ ./pointer.jl:111 [inlined]
  [9] uno_objective_gradient(number_variables::Int32, x::Ptr{Float64}, gradient::Ptr{Float64}, user_data::Ptr{Nothing})
    @ UnoSolver ~/.julia/packages/UnoSolver/tRcxS/src/C_wrapper.jl:39

Option 2:

Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation
ERROR: LoadError: TypeError: 
[10031] signal 11 (1): Segmentation fault
in expression starting at none:0
arg_tuple at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/builtins.c:940
print_to_string at ./strings/io.jl:140
string at ./strings/io.jl:193 [inlined]
showerror at ./errorshow.jl:90
#showerror#822 at ./errorshow.jl:109
showerror at ./errorshow.jl:107
unknown function (ip: 0x70155ab58ee2) at (unknown file)
#showerror#823 at ./errorshow.jl:117
showerror at ./errorshow.jl:115
unknown function (ip: 0x70155ab58868) at (unknown file)
show_exception_stack at ./errorshow.jl:1016
display_error at ./client.jl:110
unknown function (ip: 0x70155ab553d6) at (unknown file)
display_error at ./client.jl:113
jfptr_display_error_59160.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
jl_f_invokelatest at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/builtins.c:881
exec_options at ./client.jl:320
_start at ./client.jl:550
jfptr__start_31204.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
true_main at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/jlapi.c:971
jl_repl_entrypoint at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/jlapi.c:1139
main at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/cli/loader_exe.c:58
unknown function (ip: 0x701570427634) at /usr/lib/libc.so.6
__libc_start_main at /usr/lib/libc.so.6 (unknown line)
unknown function (ip: 0x4010b8) at /workspace/srcdir/glibc-2.17/csu/../sysdeps/x86_64/start.S
Allocations: 18881628 (Pool: 18881295; Big: 333); GC: 13
Segmentation fault         (core dumped) julia --project uno_segfault_mwe.jl

Option 3 (REPL only): This one gives me an entry point to Uno! It looks like evaluate_objective_gradient is the bottom of the call stack for the crash.

cg:example> julia --project

julia> include("uno_segfault_mwe.jl")
Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation

[10722] signal 11 (1): Segmentation fault
in expression starting at /home/cg/Personal/Repos/Vecchia.jl/example/uno_segfault_mwe.jl:15
unknown function (ip: 0x200000000) at (unknown file)
_ZNK8UnoModel27evaluate_objective_gradientERKN3uno6VectorIdEERS2_ at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno7Iterate27evaluate_objective_gradientERKNS_5ModelE at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno12NoRelaxation10initializeERNS_10StatisticsERKNS_5ModelERNS_7IterateERNS_9DirectionEdRKNS_7OptionsE at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno19TrustRegionStrategy10initializeERNS_10StatisticsERKNS_5ModelERNS_7IterateERNS_9DirectionERKNS_7OptionsE at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno3Uno10initializeERNS_10StatisticsERKNS_5ModelERNS_7IterateERKNS_7OptionsE at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno3Uno9uno_solveERKNS_5ModelERKNS_7OptionsERNS_13UserCallbacksE at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno3Uno5solveERKNS_5ModelERKNS_7OptionsERNS_13UserCallbacksE at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
uno_optimize at /home/cg/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
uno_optimize at /home/cg/.julia/packages/UnoSolver/tRcxS/src/libuno.jl:180 [inlined]
uno_optimize at /home/cg/.julia/packages/UnoSolver/tRcxS/src/C_wrapper.jl:336 [inlined]
#uno#1 at /home/cg/.julia/packages/UnoSolver/tRcxS/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:99 [inlined]
uno at /home/cg/.julia/packages/UnoSolver/tRcxS/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:96 [inlined]
#optimize#2 at /home/cg/Personal/Repos/Vecchia.jl/ext/VecchiaUnoSolverExt.jl:75
optimize at /home/cg/Personal/Repos/Vecchia.jl/ext/VecchiaUnoSolverExt.jl:71
unknown function (ip: 0x7c59b6f66012) at (unknown file)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
do_call at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:123
eval_value at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:243
eval_stmt_value at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:194 [inlined]
eval_body at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:707
jl_interpret_toplevel_thunk at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:898
jl_toplevel_eval_flex at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/toplevel.c:1035
jl_toplevel_eval_flex at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/toplevel.c:975
ijl_toplevel_eval at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/toplevel.c:1047
ijl_toplevel_eval_in at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/toplevel.c:1092
eval at ./boot.jl:489
include_string at ./loading.jl:2842
_include at ./loading.jl:2902
include at ./Base.jl:307
IncludeInto at ./Base.jl:308
jfptr_IncludeInto_58274.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
do_call at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:123
eval_value at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:243
eval_stmt_value at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:194 [inlined]
eval_body at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:707
jl_interpret_toplevel_thunk at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/interpreter.c:898
jl_toplevel_eval_flex at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/toplevel.c:1035
__repl_entry_eval_expanded_with_loc at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:301
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
jl_f_invokelatest at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/builtins.c:881
toplevel_eval_with_hooks at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:308
toplevel_eval_with_hooks at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:312
toplevel_eval_with_hooks at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:312
toplevel_eval_with_hooks at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:312
toplevel_eval_with_hooks at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:305 [inlined]
eval_user_input at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:330
repl_backend_loop at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:452
#start_repl_backend#41 at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:427
start_repl_backend at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:424 [inlined]
#run_repl#50 at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:653
run_repl at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:639
unknown function (ip: 0x7c59b6f04cd6) at (unknown file)
run_std_repl at ./client.jl:478
jfptr_run_std_repl_62877.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
jl_f_invokelatest at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/builtins.c:881
run_main_repl at ./client.jl:499
repl_main at ./client.jl:586 [inlined]
_start at ./client.jl:561
jfptr__start_31204.1 at /home/cg/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
true_main at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/jlapi.c:971
jl_repl_entrypoint at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/src/jlapi.c:1139
main at /cache/build/tester-amdci4-14/julialang/julia-release-1-dot-12/cli/loader_exe.c:58
unknown function (ip: 0x7c59cc827634) at /usr/lib/libc.so.6
__libc_start_main at /usr/lib/libc.so.6 (unknown line)
unknown function (ip: 0x4010b8) at /workspace/srcdir/glibc-2.17/csu/../sysdeps/x86_64/start.S
Allocations: 24288101 (Pool: 24287728; Big: 373); GC: 17
Segmentation fault         (core dumped) julia --project

cgeoga avatar Nov 18 '25 16:11 cgeoga

Last data point before I start going back to things I should have started doing hours ago: if I replace

  function Vecchia.optimize(obj::C, init, solver::Vecchia.UnoNLPSolver;
                            box_lower=fill(1e-5, length(init)),
                            box_upper=fill(100.0,length(init))) where{C}
    nlp = Vecchia.nlp(obj, init, box_lower, box_upper)
    (model, solver) = uno(nlp, false; preset="filtersqp", 
                          print_solution=false)
    UnoSolver.uno_get_primal_solution(solver, zeros(length(init)))
  end

with

  function Vecchia.optimize(obj::C, init, solver::Vecchia.UnoNLPSolver;
                            box_lower=fill(1e-5, length(init)),
                            box_upper=fill(100.0,length(init))) where{C}
    nlp = Vecchia.nlp(obj, init, box_lower, box_upper)
    # Testing: evaluate all NLPModels functions first.
    @show init
    _o  = NLPModels.obj(nlp, init)
    @show _o
    _g  = zeros(3)
    NLPModels.grad!(nlp, init, _g)
    @show _g
    _r, _c = (zeros(Int64, 6), zeros(Int64, 6))
    NLPModels.hess_structure!(nlp, _r, _c)
    @show (_r, _c)
    _h = zeros(6)
    NLPModels.hess_coord!(nlp, init, _h)
    @show _h
    (model, solver) = uno(nlp, false; preset="filtersqp", 
                          print_solution=false)
    UnoSolver.uno_get_primal_solution(solver, zeros(length(init)))
  end

and add the type annotation

  function NLPModels.hess_structure!(vnlp::VecchiaNLPModel{C,T,S}, 
                                     hrows::AbstractVector{Int}, # added this type constraint
                                     hcols::AbstractVector{Int}) where{C,T,S}  # and this one on hcols
    idx = 1
    for row in 1:vnlp.p
      for col in 1:row
        hrows[idx] = row
        hcols[idx] = col
        idx       += 1
      end
    end
    (hrows, hcols)
  end

then sometimes the MWE code works! And in most cases, it at least starts to run. But even if it starts to run, I still get segfaults like this sometimes:

cg:example> julia --project uno_segfault_mwe.jl 
Precompiling VecchiaUnoSolverExt finished.
  1 dependency successfully precompiled in 2 seconds. 84 already precompiled.
init = [2.5, 0.1, 1.1]
_o = 112.53846811000858
_g = [-18.70754039287857, -1278.271135310135, -463.8990040324635]
(_r, _c) = ([1, 2, 2, 3, 3, 3], [1, 1, 2, 1, 2, 3])
_h = [342.4490484714512, -6514.571429453283, 182477.4398024949, -395.06074485439973, 8635.590888324188, 1145.358383173676]
Original model C model
3 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation

Used overwritten options:
- QP_solver = BQPD

────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter   TR iter  penalty    TR radius  step norm  objective  stationarity complementarity status        
────────────────────────────────────────────────────────────────────────────────────────────────────────
 0      -        -          1.000e+01  -          1.125e+02  1.360e+03    0.000e+00       initial point 
 1      1        1.000e+00  1.000e+01  1.122e+00  -3.132e+01 7.332e+03    0.000e+00       ✔ (Armijo)    
 2      1        1.000e+00  1.000e+01  1.748e+00  1.837e+03  -            -               ✘ (Armijo)    
 -      2        1.000e+00  8.742e-01  8.742e-01  1.140e+03  -            -               ✘ (Armijo)    
 -      3        1.000e+00  4.371e-01  4.371e-01  4.809e+01  -            -               ✘ (Armijo)    
 -      4        1.000e+00  2.186e-01  2.186e-01  -8.103e+01 4.968e+03    0.000e+00       ✔ (Armijo)    
 3      1        1.000e+00  4.371e-01  4.371e-01  -1.103e+02 2.565e+03    0.000e+00       ✔ (Armijo)    
 4      1        1.000e+00  8.742e-01  8.742e-01  6.817e+01  -            -               ✘ (Armijo)    
 -      2        1.000e+00  4.371e-01  4.371e-01  -9.363e+01 -            -               ✘ (Armijo)    
 -      3        1.000e+00  2.186e-01  2.186e-01  -1.113e+02 1.834e+03    0.000e+00       ✔ (Armijo)    
 5      1        1.000e+00  4.371e-01  1.466e-01  -1.137e+02 3.025e+02    0.000e+00       ✔ (Armijo)    
 6      1        1.000e+00  4.371e-01  1.172e-01  -1.140e+02 1.182e+02    0.000e+00       ✔ (Armijo)    
 7      1        1.000e+00  4.371e-01  2.231e-02  -1.140e+02 1.941e+00    0.000e+00       ✔ (Armijo)    
 8      1        1.000e+00  4.371e-01  1.050e-03  -1.140e+02 7.847e-03    0.000e+00       ✔ (Armijo)    
 9      1        1.000e+00  4.371e-01  1.426e-06  -1.140e+02 -            -               ✘ (Armijo)    
 -      2        1.000e+00  7.130e-07  7.130e-07  -1.140e+02 -            -               ✘ (Armijo)    
 -      3        1.000e+00  3.565e-07  3.565e-07  -1.140e+02 -            -               ✘ (Armijo)    
malloc(): unaligned tcache chunk detected
malloc(): unaligned tcache chunk detected
Aborted                    (core dumped) julia --project uno_segfault_mwe.jl

So that again makes me think that somehow Julia or the NLPModelsMeta has some things that get lazily instantiated, and maybe Uno tries to read them before they have been instantiated (or something)?

Anyways. Sorry for all the chatter here. I'm not good at tracking down segfaults, but I want to be as respectful of your time as possible so just trying to give any data I can put together in case it saves you time.

cgeoga avatar Nov 18 '25 16:11 cgeoga

Hi @cgeoga, I'm not familiar enough with Julia to be sure, but could the line g .= _g in the definition of NLPModels.grad! in VecchiaUnoSolverExt.jl be a source of trouble? Is it just copying the elements 1 by 1?

cvanaret avatar Nov 19 '25 14:11 cvanaret

@amontoison ~~probably a red herring, but in UnoSolverNLPModelsExt.nlpmodels_objective_gradient and C_wrapper.jl's uno_objective_gradient, the parameters x and g are in different orders. Then nlpmodels_objective_gradient is passed to uno_model. Could that be a bug?~~ Edit: the order is switched back in uno_objective_gradient. Looks ok to me...

cvanaret avatar Nov 19 '25 15:11 cvanaret

@cvanaret @amontoison, thanks again for your time here. And Charlie, I appreciate the suggestion about g versus _g. Unfortunately doing that update in a for loop or something with more explicit syntax doesn't change anything.

I think I've been making this MWE much more complicated than it has to be though, and this has nothing to do with my package or extension. Check this out.

This code runs fine:

using ADNLPModels, UnoSolver

#function testme()
  v        = rand(10)
  obj(t)   = sum(abs2, t)/2 + dot(t,v)

  nlp      = ADNLPModel(obj, ones(10); backend=:generic)
  (model, solver) = uno(nlp, false; preset="filtersqp", print_solution=false)
  solution = UnoSolver.uno_get_primal_solution(solver, zeros(length(v)))
#end

#testme()

But if you un-comment the lines that wrap it in a function, you get a segfault. That is seriously puzzling and I don't really even have a guess about the issue. But it sure is a more minimal MWE?

cgeoga avatar Nov 19 '25 19:11 cgeoga

I can reproduce. This rules out your package indeed. The segfaults happen mostly in UnoModel (during the evaluation of the objective gradient or the Jacobian, or accessing some variable bounds), or in BQPD's gdotx_ (this uses the user Hessian). Clearly there's something wrong with the creation of UnoModel.

cvanaret avatar Nov 19 '25 20:11 cvanaret

Hum, it seems to break the memory alignement.

julia> using UnoSolver, ADNLPModels

julia> function testme()
         v        = rand(10)
         obj(t)   = sum(abs2, t)/2 + dot(t,v)

         nlp      = ADNLPModel(obj, ones(10); backend=:generic)
         (model, solver) = uno(nlp, false; preset="filtersqp", print_solution=false)
         solution = UnoSolver.uno_get_primal_solution(solver, zeros(length(v)))
       end
testme (generic function with 1 method)

julia> testme()
Original model C model
10 variables, 0 constraints (0 equality, 0 inequality)
The model is unconstrained, picking no relaxation

Used overwritten options:
- QP_solver = BQPD

────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter   TR iter  penalty    TR radius  step norm  objective  stationarity complementarity status        
────────────────────────────────────────────────────────────────────────────────────────────────────────
 0      -        -          1.000e+01  -          9.115e+00  4.548e+00    0.000e+00       initial point 
ERROR: DimensionError: Input x should have length 10 not 174173408
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/NLPModels/HVa0b/src/nlp/utils.jl:37 [inlined]
  [2] hess_coord!(nlp::ADNLPModel{…}, x::Vector{…}, y::Vector{…}, vals::Vector{…}; obj_weight::Float64)
    @ ADNLPModels ~/.julia/packages/ADNLPModels/N6grE/src/nlp.jl:702
  [3] hess_coord!
    @ ~/.julia/packages/ADNLPModels/N6grE/src/nlp.jl:695 [inlined]
  [4] nlpmodels_lagrangian_hessian(nlp::ADNLPModel{…}, hvals::Vector{…}, x::Vector{…}, multipliers::Vector{…}, objective_multiplier::Float64)
    @ UnoSolverNLPModelsExt ~/.julia/packages/UnoSolver/KSmNB/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:29
  [5] uno_lagrangian_hessian(number_variables::Int32, number_constraints::Int32, number_hessian_nonzeros::Int32, x::Ptr{…}, objective_multiplier::Float64, multipliers::Ptr{…}, hessian::Ptr{…}, user_data::Ptr{…})
    @ UnoSolver ~/.julia/packages/UnoSolver/KSmNB/src/C_wrapper.jl:70
  [6] uno_optimize
    @ ~/.julia/packages/UnoSolver/KSmNB/src/libuno.jl:180 [inlined]
  [7] uno_optimize
    @ ~/.julia/packages/UnoSolver/KSmNB/src/C_wrapper.jl:336 [inlined]
  [8] #uno#1
    @ ~/.julia/packages/UnoSolver/KSmNB/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:91 [inlined]
  [9] uno
    @ ~/.julia/packages/UnoSolver/KSmNB/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:88 [inlined]
 [10] testme()
    @ Main ./REPL[4]:6
 [11] top-level scope
    @ REPL[5]:1
Some type information was truncated. Use `show(err)` to see complete types.

amontoison avatar Nov 20 '25 00:11 amontoison

For me, every single call to UnoSolver.uno results in a segfault when using the latest version 0.1.5.

MWE

import Pkg
Pkg.activate(temp=true)
Pkg.add([
    Pkg.PackageSpec("SpecialFunctions"),
    Pkg.PackageSpec(name="ADNLPModels", version="0.8.13"),
    Pkg.PackageSpec(name="UnoSolver", version="0.1.5"),
])
Pkg.status()

using SparseArrays, Distributions
import UnoSolver, ADNLPModels
import SpecialFunctions: erf

struct MyMix{T<:Real, V<:AbstractVector{T}} <: ContinuousUnivariateDistribution
    ps::V
    ms::V
    log_squared_scales::V # sigma = exp(l / 2)
end

function Distributions.cdf(d::MyMix, x::Real)
    ncdf(z::Real) = (1 + erf(z / sqrt(2)))/2
    sum(
        p * ncdf((x - m) / exp(l / 2))
        for (p, m, l) in zip(d.ps, d.ms, d.log_squared_scales)
    )
end

function loss_CramerMises(d::MyMix, xs::AbstractVector{<:Real}, sorted::Bool=false)
    xs = sorted ? xs : sort(xs)
    N = length(xs)
    1/(12N) + sum(
        ((2n - 1)/N - cdf(d, x))^2
        for (n, x) in enumerate(xs)
    )
end

function fit_CM(d::MyMix, data::AbstractVector{<:Real}, sorted::Bool=false; logger::AbstractString="INFO")
    data = sorted ? data : sort(data)
    K = length(d.ps)
    @assert length(d.ps) == length(d.ms) == length(d.log_squared_scales) == K

    loss(par::AbstractVector{<:Real}) = @views loss_CramerMises(
        MyMix(par[1:K], par[K+1:2K], par[2K+1:end]), data, true
    )

    A = zeros(1, 3K)
    A[1, 1:K] .= 1.0
    @info "Building model..."
    model = @time ADNLPModels.ADNLPModel(
        loss,
        [d.ps; d.ms; d.log_squared_scales],
        [zeros(K); fill(-Inf, 2K)],
        fill(Inf, 3K),
        sparse(A), [1.], [1.]
    )
    @info "Running Uno..."
    model, solver = @time UnoSolver.uno(model; preset="filtersqp", logger)
    par = Vector{Float64}(undef, 3K)
    UnoSolver.uno_get_primal_solution(solver, par)
    MyMix(par[1:K], par[K+1:2K], par[2K+1:end])
end

let
    sample = randn(100)#;  -1 .+ 0.3randn(200)]
    mix = @time fit_CM(
        MyMix([0.5, 0.5], [-0.1, 0.1], log.([1.,2.])), sample
    )
    @show mix
end

Output

> julia bug_uno.jl
  ...
Status `/tmp/jl_M69xBb/Project.toml`
  [54578032] ADNLPModels v0.8.13
  [276daf66] SpecialFunctions v2.6.1
  [1baa60ac] UnoSolver v0.1.5
[ Info: Building model...
  4.957199 seconds (4.45 M allocations: 223.423 MiB, 1.28% gc time, 99.90% compilation time)
[ Info: Running Uno...
Original model C model
6 variables, 1 constraints (1 equality, 0 inequality)

[12401] signal 11 (2): Segmentation fault
in expression starting at bug_uno.jl:63
unknown function (ip: 0x3d2c9b50)
unknown function (ip: 0x5)
Allocations: 30747091 (Pool: 30744687; Big: 2404); GC: 21
fish: Job 1, 'julia bug_uno.jl' terminated by signal SIGSEGV (Address boundary error)
> julia --version
julia version 1.11.7

The error message can be different and more descriptive when I run the same code a second time:

> julia bug_uno.jl
Status `/tmp/jl_Ieh7G7/Project.toml`
  [54578032] ADNLPModels v0.8.13
  [276daf66] SpecialFunctions v2.6.1
  [1baa60ac] UnoSolver v0.1.5
[ Info: Building model...
  4.597091 seconds (4.45 M allocations: 223.423 MiB, 1.17% gc time, 99.90% compilation time)
[ Info: Running Uno...
Original model C model
6 variables, 1 constraints (1 equality, 0 inequality)

[12577] signal 11 (128): Segmentation fault
in expression starting at bug_uno.jl:63
_ZNK8UnoModel28evaluate_constraint_jacobianERKN3uno6VectorIdEEPd at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno19BQPDEvaluationSpace28evaluate_constraint_jacobianERKNS_19OptimizationProblemERNS_7IterateE at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno22FeasibilityRestoration10initializeERNS_10StatisticsERKNS_5ModelERNS_7IterateERNS_9DirectionEdRKNS_7OptionsE at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno19TrustRegionStrategy10initializeERNS_10StatisticsERKNS_5ModelERNS_7IterateERNS_9DirectionERKNS_7OptionsE at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno3Uno10initializeERNS_10StatisticsERKNS_5ModelERNS_7IterateERKNS_7OptionsE at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno3Uno9uno_solveERKNS_5ModelERKNS_7OptionsERNS_13UserCallbacksE at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
_ZN3uno3Uno5solveERKNS_5ModelERKNS_7OptionsERNS_13UserCallbacksE at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
uno_optimize at /home/user/.julia/artifacts/14bf89827e95e4f7f4c613c31da23f388a220d2c/lib/libuno.so (unknown line)
uno_optimize at /home/user/.julia/packages/UnoSolver/mtE1n/src/libuno.jl:180 [inlined]
uno_optimize at /home/user/.julia/packages/UnoSolver/mtE1n/src/C_wrapper.jl:336 [inlined]
#uno#1 at /home/user/.julia/packages/UnoSolver/mtE1n/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:99 [inlined]
uno at /home/user/.julia/packages/UnoSolver/mtE1n/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:96 [inlined]
uno at /home/user/.julia/packages/UnoSolver/mtE1n/ext/UnoSolverNLPModelsExt/UnoSolverNLPModelsExt.jl:96 [inlined]
macro expansion at ./timing.jl:581 [inlined]
#fit_CM#6 atbug_uno.jl:57
fit_CM at bug_uno.jl:37 [inlined]
fit_CM at bug_uno.jl:37 [inlined]
macro expansion at ./timing.jl:581 [inlined]
top-level scope at bug_uno.jl:65
jl_toplevel_eval_flex at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/src/toplevel.c:934
jl_toplevel_eval_flex at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/src/toplevel.c:886
ijl_toplevel_eval_in at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/src/toplevel.c:994
eval at ./boot.jl:430 [inlined]
include_string at ./loading.jl:2734
_include at ./loading.jl:2794
include at ./Base.jl:562
jfptr_include_46986.1 at /home/user/.julia/juliaup/julia-1.11.7+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
exec_options at ./client.jl:323
_start at ./client.jl:531
jfptr__start_73684.1 at /home/user/.julia/juliaup/julia-1.11.7+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/src/julia.h:2157 [inlined]
true_main at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/src/jlapi.c:900
jl_repl_entrypoint at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/src/jlapi.c:1059
main at /cache/build/builder-demeter6-3/julialang/julia-release-1-dot-11/cli/loader_exe.c:58
unknown function (ip: 0x75a888e2a574)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x4010b8)
Allocations: 30695644 (Pool: 30693240; Big: 2404); GC: 20
fish: Job 1, 'julia bug_uno.jl' terminated by signal SIGSEGV (Address boundary error)
>

ForceBru avatar Nov 24 '25 13:11 ForceBru

Thanks @ForceBru, I also got something like your second stacktrace. It could be that we have a dangling reference when the user model is passed to the C interface.

cvanaret avatar Nov 24 '25 13:11 cvanaret

This is now fixed in UnoSolver.jl v0.1.6 :)

cvanaret avatar Nov 26 '25 15:11 cvanaret

Can confirm, everything is great and I'm taking a new release of Vecchia.jl that documents and implements Uno as the direct solver!

Thanks again to you and @amontoison for your work making this so easy to enjoy.

cgeoga avatar Nov 27 '25 23:11 cgeoga

Thanks Chris, great to hear!

cvanaret avatar Nov 28 '25 07:11 cvanaret