UnoSolver.jl

UnoSolver.jl is a Julia wrapper for Uno. The package has three components:

  • a thin wrapper around the complete C API,
  • an interface to NLPModels.jl for solving any optimization problem following the API, such as CUTEst problems,
  • an interface to MathOptInterface.jl for handling JuMP models.

This Julia interface is developed and maintained by Alexis Montoison and Charlie Vanaret.

Installation

UnoSolver.jl is a registered Julia package, it can be installed and tested through the Julia package manager.

julia> using Pkgjulia> Pkg.add("UnoSolver")julia> Pkg.test("UnoSolver")

Getting started

To get started with Uno, check out the official documentation.

Examples

Below are examples showing how to use UnoSolver.jl with the interfaces for NLPModels.jl and MathOptInterface.jl.

using UnoSolver, CUTEstnlp = CUTEstModel{Float64}("HS15")stats = uno(nlp, preset="filtersqp", print_solution=true, logger="INFO")model, solver = stats.model, stats.solverprimal_solution = stats.solutionconstraint_dual_solution = stats.multiplierslower_bound_dual_solution = stats.multipliers_Lupper_bound_dual_solution = stats.multipliers_Utimer = stats.elapsed_timesolution_objective = stats.objectivesolution_primal_feasibility = stats.primal_feassolution_stationarity = stats.dual_feassolution_complementarity = stats.complementarity_feasniter = stats.iternsub = stats.number_subproblem_solved_evaluationsoptimization_status = stats.optimization_statussolution_status = stats.solution_statusnumber_objective_evaluations = stats.number_objective_evaluationsnumber_constraint_evaluations = stats.number_constraint_evaluationsnumber_objective_gradient_evaluations = stats.number_objective_gradient_evaluationsnumber_jacobian_evaluations = stats.number_jacobian_evaluationsnumber_hessian_evaluations = stats.number_hessian_evaluations
using UnoSolver, JuMPjump_model = Model(() -> UnoSolver.Optimizer(preset="filtersqp"))x0 = [-2, 1]uvar = [0.5, Inf]@variable(jump_model, x[i = 1:2]  uvar[i], start = x0[i])@objective(jump_model, Min, 100 * (x[2] - x[1]^2)^2 + (1 - x[1])^2)@constraint(jump_model, x[1] * x[2] - 1  0)@constraint(jump_model, x[1] + x[2]^2  0)optimize!(jump_model)termination_status(jump_model)  # solver termination statusobjective_value(jump_model)     # objective valuevalue.(x)                       # primal solution

If you encounter any issues with the interface for JuMP problems, please open an issue so we can fix it. As a temporary workaround, you can use NLPModelsJuMP.jl to wrap a JuMP model into a MathOptNLPModel:

using UnoSolver, NLPModelsJuMPnlp = MathOptNLPModel(jump_model)model = uno_model(nlp)solver = uno_solver()uno_set_solver_preset(solver, "filtersqp")uno_set_solver_bool_option(solver, "print_solution", true)uno_optimize(solver, model)stats = uno_statistics(solver, model)

Linear solvers

UnoSolver.jl supports a number of linear solvers. If not specified by the user, the default linear solver is picked in this order (if available): MA57, MA27, MA86, MUMPS, SSIDS.

LibHSL

We highly recommend downloading the latest release of libHSL and installing the official version of HSL_jll.jl into your current environment using:

import PkgPkg.develop(path = "/full/path/to/HSL_jll.jl")

This optional dependency provides access to more reliable and powerful linear solvers. Currently, UnoSolver.jl supports MA27, MA57, and MA86. Pick a linear solver by setting the linear_solver attribute:

using JuMP, UnoSolverimport HSL_jllmodel = Model(() -> UnoSolver.Optimizer(preset="ipopt"))set_attribute(model, "linear_solver", "MA57")

MUMPS

MUMPS can be used by setting the linear_solver attribute:

using JuMP, UnoSolvermodel = Model(() -> UnoSolver.Optimizer(preset="ipopt"))set_attribute(model, "linear_solver", "MUMPS")

QP solvers

If not specified by the user, the default QP solver is BQPD.

BQPD

BQPD can be used by setting the QP_solver attribute:

using JuMP, UnoSolvermodel = Model(() -> UnoSolver.Optimizer(preset="filtersqp"))set_attribute(model, "QP_solver", "BQPD")

LP solvers

If not specified by the user, the default LP solver is BQPD.

BQPD

BQPD can be used by setting the LP_solver attribute:

using JuMP, UnoSolvermodel = Model(() -> UnoSolver.Optimizer(preset="filterslp"))set_attribute(model, "LP_solver", "BQPD")

HiGHS

HiGHS can be used by setting the LP_solver attribute:

using JuMP, UnoSolvermodel = Model(() -> UnoSolver.Optimizer(preset="filterslp"))set_attribute(model, "LP_solver", "HiGHS")

BLAS and LAPACK demuxer

Uno_jll.jl is compiled with libblastrampoline (LBT), a library that can switch between BLAS and LAPACK backends at runtime, such as OpenBLAS, Intel MKL, and Apple Accelerate. The default BLAS and LAPACK backend used in the Julia interface UnoSolver.jl is OpenBLAS.

Display backends

You can check which backends are currently loaded with:

import LinearAlgebraLinearAlgebra.BLAS.lbt_get_config()

If no BLAS or LAPACK library compiled with 32-bit integers (LP64) is available, UnoSolver.jl will automatically load a compatible version of OpenBLAS. You can run the command again after using UnoSolver to verify which backend is in use.

Sequential BLAS and LAPACK

If you have the LP64 reference versions of BLAS and LAPACK installed, you can switch to the sequential backends by running:

using ReferenceBLAS32_jll, LAPACK32_jllLinearAlgebra.BLAS.lbt_forward(libblas32)LinearAlgebra.BLAS.lbt_forward(liblapack32)using UnoSolver

MKL

If you have MKL.jl installed, switch to MKL by adding using MKL to your code:

using MKLusing UnoSolver

AppleAccelerate

If you are using macOS v13.4 or later and you have AppleAccelerate.jl installed, add using AppleAccelerate to your code:

using AppleAccelerateusing UnoSolver