Skip to content

Don't copy ScalarNonlinearFunction in VectorOfConstraints - #2803

Merged
blegat merged 2 commits into
masterfrom
bl/copy_nl
Nov 6, 2026
Merged

blegat merged 2 commits into
masterfrom
bl/copy_nl

Conversation

@blegat

@blegat blegat commented Aug 6, 2025 •

Copy link
Copy Markdown
Member

Extracted from #2788

I'm not too convinced by the current approach.

For the copy in ConstraintFunction, I think we add it mostly to be extra-sure the user does not alter the function but we don't really need it in the context of MOI.copy_to since add_constraint specifies that the model should have its own copy. Maybe we should also have UnsafeConstraintFunction that is used inside MOI.copy_to, it should also safe wasteful copies for ScalarAffineFunction and ScalarQuadraticFunction. So if we have tests that checks that solvers have their own copies in add_constraint then it should be safe.

@odow

odow commented Aug 7, 2025

Copy link
Copy Markdown
Member

I think the first step before we go making any changes to this is to come up with a large suite of benchmarks and tests. There are a number of subtle behaviors here.

@odow odow left a comment

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.

This needs a test.

@blegat
blegat force-pushed the bl/copy_nl branch 2 times, most recently from 3a0669a to 2a1d4a2 Compare November 3, 2026 10:05
@blegat
blegat marked this pull request as ready for review November 3, 2026 10:05
@blegat

blegat commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

Reusing MA.mutability here was a bit weird because we do implement MA.operate! for SNF so I defined a new function with a well-defined behavior

@blegat

blegat commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

After this, there are two places left when aliases can be destroyed, if is_canonical is false or if there are variable bridges, in the substitution

Functions such as `ScalarNonlinearFunction` cannot be modified in-place
through the MOI API, so models do not need to copy them. Copying them
turns shared subexpressions into distinct objects, which prevents
`Nonlinear.ReverseAD` from detecting them as common subexpressions.

* Add `Utilities.copy_if_modifiable`, which defaults to `copy` and
  returns the function itself for `VariableIndex`, `VectorOfVariables`,
  `ScalarNonlinearFunction` and `VectorNonlinearFunction`.
* Use it in `VectorOfConstraints`, `ObjectiveContainer`,
  `UniversalFallback`, `SplitIntervalBridge` and `Utilities.canonical`.
* Document it in `AbstractFunction`, `ScalarNonlinearFunction`,
  `VectorNonlinearFunction` and the implementing tutorial.
@blegat
blegat merged commit 214415c into master Nov 6, 2026
31 checks passed
@blegat
blegat deleted the bl/copy_nl branch November 6, 2026 10:03
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