Skip to content

AD interface compatibile with both ArrayDiff and ExaModels - #3046

Open
blegat wants to merge 12 commits into
masterfrom
bl/linearity
Open

AD interface compatibile with both ArrayDiff and ExaModels#3046
blegat wants to merge 12 commits into
masterfrom
bl/linearity

Conversation

@blegat

@blegat blegat commented Aug 12, 2026

Copy link
Copy Markdown
Member

In #2989, I tried doing a simple change to the AD interface for ArrayDiff to serve as an AD backend.
The idea was to have model return a custom model type when given the AD backend as argument so that ArrayDiff could deviate from MOI.Nonlinear.Model.
The conclusion at the JuMP-dev call was to improve MOI.Nonlinear.Model so that we don't need to deviate.
The issue with this is that it forces us to commit the changes to MOI so it means we can't do breaking changes which makes it hard to play around and try things. ArrayDiff is then blocked in a state where it cannot be tried by user until we just commit to an interface that just cannot be changed anymore.
Another proof that the AD interface is too rigid is the fact that ExaModels couldn't interface itself as a new AD backend and had to define itself as a meta-solver.

With AI getting more powerful, I think the features of MOI that allows people to extend it independently in different package is quite important. Trying to have a centralized MOI.Nonlinear.Model that would cover all need is probably too strict.
So this PR attempt to create a new interface so that both ArrayDiff and ExaModels can be defined as AD backends.

On major difference between ExaModels and ReverseAD is that ReverseAD is that Ipopt and NLPModelsJuMP don't give the quadratic constraints to ReverseAD while ExaModels takes the quadratic constraints in its AD.
So for the Ipopt wrapper to work for both, it would need to give the quadratic constraints to both and ReverseAD should also handle quadratic constraints.
The way this PR does it is to refactor the handling of quadratic constraints and VectorNonlinearOracle of Ipopt as layers that we can stack on top of an existing AD.
This is continuing the approach started in jump-dev/Ipopt.jl#520
As a side effect, this reduces the large code duplication of the handling of quadratic constraints and nonlinear oracles in Ipopt, NLopt, MadNLP, NLPModelsJuMP, etc... Again, with AI, we might see a lot of new solvers appear, so having all of them copy the Ipopt wrapper is probably not a good idea. Because when we'll modify the Ipopt wrapper, they won't follow and it will create inconsistent behavior across solvers. Even if many vibe-coded solvers won't be any good, natural selection will do its job and natural selection will work better if they are all easily accessible through JuMP.

So Claude Fable 5 create this PR which seems reasonable although I haved looked at all details yet.
We could probably open a PR for 459c20a and merge it independently if we decide we want to go for this.

We needed linearity information for NLPModelsJuMP and Ipopt so I reused the linearity of MOI.Nonlinear.ReverseAD, just added quadratic in the mix. The quadratic detection might have some false negative at the moment but it's find since the quadratic given as quadratic in JuMP are already reported by the WithQuad layer.

Let's try it with the downstream packages to see if it works

blegat added 12 commits August 12, 2026 17:34
From MadNLP's copy (parameter-aware, accumulating into the output)
The applicable() guard in _inner_constraint_linearity did not recurse:
num_constraints on a layer is applicable but throws when the innermost
evaluator (for example, a legacy NLPBlock evaluator) does not implement
the query. Add _try_num_constraints, which returns nothing in that case
at any depth of the stack.
An evaluator is only required to implement jacobian_structure and
hessian_lagrangian_structure when it supports :Jac and :Hess. Solvers
such as Ipopt query the structures eagerly even for models whose
legacy NLPBlock evaluator supports neither (for example, an
objective-only evaluator with feature :Grad), so the layers must not
call into the inner evaluator in that case.
exploits_structure(backend) returns true when the model returned by
model(backend) natively accepts ScalarAffine/ScalarQuadratic functions
(no ModelWithQuad layer), so consumers such as NLPModelsJuMP know to
pass all functions unparsed. Defined in MOI.Nonlinear because a trait
spanning two package extensions (an AD backend and a consumer) has no
reliable home in either: extension load order is unspecified.

_has_objective falls back to true for unknown evaluators, which is
conservative: the solver then calls eval_objective, and evaluators
without an objective return zero.
Solvers such as MadNLP call the Jacobian-transpose product for dual
computations even when :JacVec is not advertised, so erroring in the
presence of oracle constraints is not an option. The oracle layer now
materializes each oracle's Jacobian (or Hessian) to answer the product
callbacks, which can be slow on large oracles; the :JacVec/:HessVec
features remain removed from features_available so that solvers do not
rely on them for performance.

Also forward MOI.is_valid for constraint indices and
MOI.ListOfSupportedNonlinearOperators through the model layers (needed
by NLopt), and add the Nonlinear.exploits_structure trait.
@odow

odow commented Aug 12, 2026

Copy link
Copy Markdown
Member

Without looking at the details, it's worth investigating, but I'm pretty strongly against this.

My experience with madsuite-org/ExaModels.jl#290 would suggest that writing a new ExaModels.Optimizer works fine. And even if you wanted an AD-backend, lowering from the current MOI.Nonlinear.Model would be okay.

We should have a very, very high bar for making the nonlinear interface in MOI any more complicated.

@amontoison

amontoison commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

I like the Nonlinear.QPBlockData. It will simplify a lot the extensions for MOI in Ipopt.jl, UnoSolver.jl, and MadNLP.jl.

For the other components, I don't know enough MOI to provide feedbacks. Oscar is the expert 🙂

@odow

odow commented Aug 13, 2026

Copy link
Copy Markdown
Member

It was always my intention to move something like https://github.com/jump-dev/Ipopt.jl/blob/master/ext/IpoptMathOptInterfaceExt/utils.jl into MOI.

I'd accept that as a separate PR.

@blegat

blegat commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

I'd accept that as a separate PR.

That's a good first step

We should have a very, very high bar for making the nonlinear interface in MOI any more complicated.

I agree we shouldn't complicate it too much but I feel that at the moment, MOI.Nonlinear.Model is just too rigid for people to experiment with new AD backends. NLP solvers don't really need the nonlinear model to be MOI.Nonlinear.Model, they just use the MOI.Nonlinear callback interface so forcing the model type is adding a lot of friction for no benefit I feel.

And even if you wanted an AD-backend, lowering from the current MOI.Nonlinear.Model would be okay.

Actually it won't. How would you make madsuite-org/ExaModels.jl#237 work ? GenOpt generator functions can be directly given to ExaModels without needing to be expanded. If they have to go through MOI.Nonlinear.Model, then they will need to be expanded. We just completely loose the extensibility of MOI and the ability to try new things on separate package that haven't reached version v1 yet.

My experience with madsuite-org/ExaModels.jl#290 would suggest that writing a new ExaModels.Optimizer works fine.

It's fine as a one time thing but then once you add something new like VectorNonlinearOracle, all the MOI wrappers need to be updated. We loose a decoupling. It's not the end of the world but my feeling is that a slight modification of the interface would make the MOI.Nonlinear.AbstractAutomaticDifferentiation much more useful. Now we'll have to see if a slight modification is enough so I'll see where this PR goes.

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.

3 participants