All notable changes to the XpressAPI Julia package are documented here. Version numbers track the FICO Xpress version from which the bindings were generated.
- Fixed newly added JuMP / MOI variables silently defaulting to a lower bound of
0.0. MOI variables are free by default (-Inf,+Inf), but Xpress defaults a column's lower bound to0.0, so a variable with no explicit bound was made non-negative -- causing wrong results or spurious infeasibilities for models relying on free variables. New variables are now created with an explicit-Inflower bound. - Added in-place
set(::Optimizer, ::MOI.ConstraintSet, ...)to the JuMP / MOI interface. Variable bounds (GreaterThan,LessThan,EqualTo,Interval) and affine constraint right-hand sides can now be modified without rebuilding the model, routing throughXPRSchgbounds/XPRSchgrhs, so warm-start and re-solve loops pick up the new set on the nextoptimize!. - Added
MOI.DualObjectiveValueto the JuMP / MOI interface. It reports the objective value of the dual solution after an LP solve, derived from the constraint duals so that it follows the MOI sign convention and, at optimality, matchesMOI.ObjectiveValuewithin tolerance. - Fixed the
MOI.ConstraintDualsign conventions in the JuMP / MOI interface. Duals are now reported relative to a minimization problem as MOI requires (negated for maximization models), so aGreaterThanrow/bound has a non-negative dual and aLessThanone a non-positive dual regardless of the objective sense. Duals of variable bounds are now returned as the column reduced cost (viaXPRSgetredcosts) instead ofNaN, and the dual of a parent constraint (such as a splitIntervalbound) is taken from its binding child; the vector getter now returns a flatVectorrather than a malformed nested one. - Shipped
MOI_FEATURES.mdinside the installed package. The README links to it, but it was previously omitted from the install, leaving a dead link. The bridge-usage examples in that document were also corrected to create the model directly withModel(XpressAPI.Optimizer)(JuMP adds the required bridges automatically) rather than wrapping it in aMOI.Bridges.full_bridge_optimizer, and the README wording no longer claims the package provides no modeling API given the JuMP / MOI extension it ships. - Continued the low-level wrapper clean-up following upstream review feedback:
string arguments and results now use the concrete
Stringtype (and name lists are returned asVector{String}) instead ofAbstractString, except for name-array inputs which stay generic so any string vector can be passed; wrapped functions emit an explicitreturn; and the docstring signature line now shows the return type rather than the output parameter names. - Fixed the "argument too short" error raised when a pre-allocated output
array is smaller than required. The generated code concatenated the required
length (an integer) directly onto the message string, which threw an opaque
MethodErrorinstead of the intendedXPRSexception; the length is now converted withstring(...). - Fixed an intermittent heap-corruption crash on Windows (an access violation
during garbage collection) that could occur while a callback was active
during a solve. Each callback invocation previously allocated a fresh
problem wrapper to pass to the user callback; because callbacks run
re-entrantly while the solver holds the call stack, this per-invocation
allocation could trigger garbage collection at an unsafe point. The wrapper
is now created once and reused across all invocations of a given callback,
so callbacks no longer allocate it per call. Note: this reuse is only safe
because MIP branch-and-bound callbacks are serialised on the main thread
(
XPRS_CALLBACKFROMMAINTHREAD). That guarantee does not hold for the SLP / nonlinear / multistart solves, where the optimizer may invoke callbacks from worker threads; callbacks are not currently safe to use during those solves.
- Added
MOI.SolverVersionto the JuMP / MOI interface. It reports the version of the Xpress library actually loaded at runtime (viaXPRSgetversionnumbers), which may differ from the version the bindings were built against, as amajor.minor.buildstring. - Added
MOI.ListOfConstraintTypesPresentto the JuMP / MOI interface. It reports each(F, S)constraint-type tuple currently present in the model exactly once. - Added
MOI.ObjectiveFunctionTypeto the JuMP / MOI interface. It reports the type of the objective function currently set (MOI.VariableIndex,MOI.ScalarAffineFunction,MOI.ScalarQuadraticFunction, orMOI.VectorOfVariables), defaulting toMOI.ScalarAffineFunctionwhen no objective has been set. - Fixed the low-level wrapper for deferred-reference (dref) output-array
functions such as
XPRSgetqrowqmatrixtripletswhen called with pre-allocated arrays (ornothing). The generated code previously skipped the C call on that path, returning the untouched input arrays and a size of 0; it now issues the call and returns the correct data and size. - Hardened the generated bindings against a garbage-collection use-after-free
that could corrupt the heap (observed as intermittent access violations on
Windows). String output buffers are now kept alive with
GC.@preserveacross theunsafe_string(pointer(...))conversion, and callbacks are rooted in the problem's callback list before being registered with the C library. - Reported callback support accurately:
MOI.supportsnow returnstrueonly forMOI.UserCutCallback(the one implemented callback) andfalseforMOI.LazyConstraintCallbackandMOI.HeuristicCallback, instead of a blankettruethat made JuMP offer callbacks that then failed at runtime. The feature docs were corrected to match. - Cleaned up the generated low-level wrapper following upstream review
feedback: module globals are now
constor concretely typed (avoiding the untyped-global performance penalty);Libdl/SparseArraysare brought in withimportand referenced qualified; the broken default argument onBase.showerrorwas removed; and redundantglobal/exportstatements were dropped (allXPRS-prefixed symbols are exported by a single loop). - Fixed the
SparseMatrixCSCoverload ofXPRSaddcols, which passed a malformedmap.nzvalinstead of the matrix's non-zero values.
- Added warm-start support to the JuMP / MOI interface via
set_start_value(MOI.VariablePrimalStart). The starting point is forwarded to the solver according to the problem type: MIP starts throughXPRSaddmipsol, non-linear starts throughXPRSnlpsetinitval(both accept partial solutions), and pure LP starts throughXPRSloadlpsol(which requires a complete vector, so unset variables are filled from their bounds or zero). Basis reuse across solves is left to the user to drive explicitly withXPRSgetbasis/XPRSloadbasis; the interface does not cache and reload a basis implicitly.
- Fixed
compute_conflict!so that an infeasible subproblem is reported asMOI.CONFLICT_FOUNDeven when the IIS search did not finish (for example, when it was stopped by a time limit) or when the returned infeasible set is not guaranteed to be irreducible. Previously such results were silently dropped and reported as no conflict. - Constrained the
juliacompat entry to a bounded range so the package satisfies the Julia General registry AutoMerge requirements.
- Introduced the JuMP / MathOptInterface (MOI) interface, shipped as the
XpressMOIExtpackage extension. This provides anOptimizerusable from JuMP, including linear, quadratic, nonlinear, SOS and indicator constraints, callbacks, and IIS/conflict support. - Added DREF-style array allocation helpers for the low-level wrapper.
- Fixed Windows-specific callback and test issues.
- First public release. Introduced the low-level Julia wrapper for the Xpress Optimizer C API: a Julia function wrapper for every supported C function, with error-code translation, output parameters returned as values, optional array allocation, resource finalizers, and callback support.