Cache subexpressions when building MOI.ScalarNonlinearExpression #4032
+35
−3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Here is a simplified reproducer of the performance issue identified in #4024:
Before this PR, this gives
After this PR, this gives
Note that the
MOI.ScalarNonlinearFunction
we generate now share common sub-expression by pointers! If I'm not mistaken, we don't support modifying these in-place so that shouldn't be an issue.This fixes the slow model-building issue but ReverseAD will still be terribly slow. One thing we could do is to detect, in
MOI.Nonlinear
, theMOI.ScalarNonlinearFunction
that share sub-functions correponding to the same object (with a dictionary). When it detects two functions with the same pointer, it can then create subexpressions and use its existing support for subexpressions.The nice thing about it is that we're not doing any change to the MOI interface. Creating
MOI.ScalarNonlinearFunction
was already possible from the beginning, we just didn't treat it any differently. So this change will just be a performance optimization of the AD but the interface is as simple and non-breaking as it gets.