Skip to content

Use MOI.Nonlinear.QPBlockData - #548

Draft
blegat wants to merge 5 commits into
masterfrom
bl/qp_block_data
Draft

Use MOI.Nonlinear.QPBlockData#548
blegat wants to merge 5 commits into
masterfrom
bl/qp_block_data

Conversation

@blegat

@blegat blegat commented Aug 13, 2026

Copy link
Copy Markdown
Member

A net line deletion of 534 lines. Needs

blegat added 2 commits August 13, 2026 12:25
Delete the local QPBlockData (utils.jl) in favor of the copy that
moved to MathOptInterface. Two adaptations:

- MOI's QPBlockData treats a variable as a parameter if and only if its
  index is a key of the parameters dictionary, instead of the
  index-offset convention, so parameters are registered when the
  constrained variable is added (the value is still re-synced in
  copy_parameters before every solve).
- eval_constraint_jacobian and eval_hessian_lagrangian now return the
  number of entries written instead of a one-indexed cursor, so the
  callers drop the offset adjustment.
@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.01493% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.55%. Comparing base (b5b0e62) to head (9519e5f).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
ext/IpoptMathOptInterfaceExt/MOI_wrapper.jl 97.01% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##            master     #548      +/-   ##
===========================================
- Coverage   100.00%   99.55%   -0.45%     
===========================================
  Files            5        4       -1     
  Lines         1192      899     -293     
===========================================
- Hits          1192      895     -297     
- Misses           0        4       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The evaluator methods of MOI.Nonlinear.QPBlockData now return nothing,
following the documented contract of MOI.eval_constraint_jacobian and
MOI.eval_hessian_lagrangian, so the offsets of the oracle and NLP
blocks are computed once in _setup_model instead.
any(isequal(_kFunctionTypeScalarQuadratic), model.qp_data.function_type)
any(
isequal(MOI.Nonlinear._kFunctionTypeScalarQuadratic),
model.qp_data.function_type,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this part of the public API of qp_data?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think QPBlockData should be internal and we should only expose ModelWithQuad, see #548

# is a key of `parameters`, so the parameter must be registered before
# any structure query. The value is re-synced in `copy_parameters` before
# every solve.
model.qp_data.parameters[p.value] = set.value

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we improve this API somehow?

# in the LICENSE.md file or at https://opensource.org/licenses/MIT.

include("utils.jl")
const QPBlockData = MOI.Nonlinear.QPBlockData

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strongly prefer that we use explicit prefixes instead of these extra constants. It's only needed in a few places, and using the explicit prefix makes the code much easier to read.

Comment thread .github/workflows/ci.yml
using Pkg
Pkg.add([
PackageSpec(name="MathOptInterface", rev="bl/qp_block_data"),
])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sources]
MathOptInterface = {url = "https://github.com/jump-dev/MathOptInterface.jl", rev = "bl/qp_block_data"}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't work on Julia v1.10

blegat added 2 commits August 21, 2026 07:17
* Use MOI.Nonlinear.ModelWithQuad instead of QPBlockData

Store the affine and quadratic objective and constraints in a
MOI.Nonlinear.ModelWithQuad whose inner model is the nonlinear model
(nlp_model now aliases quad_data.inner), and evaluate everything through a
MOI.Nonlinear.EvaluatorWithQuad built in _setup_model. The evaluator owns
the QP block entry counts, so the qp_nnzj/qp_nnzh fields are removed. The
inner evaluator is a new _OracleNLPEvaluator that stacks the
VectorNonlinearOracle rows before the NLPBlock rows; it extends the private
MOI.Nonlinear._constraint_bounds so that the constraint bounds of the whole
stack are assembled by the evaluator.

* MOI

* Set the quadratic objective with Nonlinear.set_objective

MOI.Nonlinear.ModelWithQuad no longer implements MOI.set for the objective;
Nonlinear.set_objective is the single way to set it.

* Merge the variables, parameters and nonlinear model into one field

MOI.Nonlinear.ModelWithQuad now owns the variables (with indices guaranteed
to be 1:n) and the parameters of the model, so the variables, parameters,
quad_data and nlp_model fields collapse into a single model field that most
of the MOI API forwards to. The parameter convention is back to the simple
_PARAMETER_OFFSET test, now defined in MOI.Nonlinear, and the parameter
values are stored once, in the inner nonlinear model, aliased by the QP
block: the per-solve parameter sync is gone. A uses_nlp_block flag replaces
the nlp_model !== nothing test to tell the legacy MOI.NLPBlock API apart,
because optimize! overwrites nlp_data; the NLPBlock is rebuilt on every
setup unless that flag is set, so that a stale objective cannot survive an
objective switch.

* Use the _is_parameter of MOI.Nonlinear directly

Defining the term methods on a local alias of the function pirated it; the
term methods are in MOI.Nonlinear now.

* Fix

* Get rid of list_of_variable_indices
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants