Skip to content

Conversation

blegat
Copy link
Member

@blegat blegat commented Aug 12, 2025

I always thought it a bit silly to only define the setter for ConstraintDualStart and not with ConstraintDual. I sometimes want to test things mixing a MockOptimizer and a bridge and I can't because bridges don't define the setters for ConstraintDual.

I suggest the following non-breaking change: We should now encourage bridges to supports ConstraintDual. When they do, a new test will be enabled that will do an important consistency check. So the new test will not be run for existing bridge which is nice since it could be breaking but after the transition, it will be run for all bridges that don't disable it by doing dual = nothing.

This would have caught the bug in #2809 as the CI should show

@odow
Copy link
Member

odow commented Aug 19, 2025

I'm still against this. Bridges could/should write better tests regardless. Testing the dual is tricky. And even our Start is a bad test because it checks only get/set doesn't error. It doesn't really have a way to test that the logic is correct.

@blegat
Copy link
Member Author

blegat commented Aug 22, 2025

Yes, we just check that get and set are inverse of each other and that's precisely what this PR is fixing. Now it also checks that it is the adjoint of the bridge transformation so it's starting to get difficult to get the test passing with an incorrect dual

@odow odow force-pushed the bl/bridge_dual_test branch from cded928 to 2553c6c Compare August 25, 2025 03:40
ci::MOI.ConstraintIndex{
<:MOI.AbstractScalarFunction,
<:Union{MOI.ZeroOne,MOI.Interval},
},
Copy link
Member

Choose a reason for hiding this comment

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

This needs to be a separate PR. What is ZeroOne doing in a PR about testing constraint duals?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is an issue detected by running the dual tests through all bridges. This is therefore tested in this PR as well

Copy link
Member

Choose a reason for hiding this comment

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

Which bridge? Why is ZeroOne involved? How can there be a dual if the ZeroOne set is involved?

Copy link
Member Author

Choose a reason for hiding this comment

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

The AbstractFunctionConversionBridge already supports setting ConstraintDual, they treat it the same as ConstraintDualStart so it got hit by the new tests.

How can there be a dual if the ZeroOne set is involved?

From the perspective of _dual_objective_value, since ZeroOne is equivalent to Interval + Integer, and Integer is ignored by _dual_objective_value then it's ok to treat ZeroOne as an Interval. If the solver doesn't have any dual, we will fail when we query the dual from the solver anyway with the expected error. Here, at the level of bridges or _dual_objective_value, we are just taking the transpose of linear maps so we shouldn't worry about whether some variables are integer or not.

Copy link
Member

Choose a reason for hiding this comment

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

Can this be a separate PR? (With an explicit test)

Copy link
Member Author

Choose a reason for hiding this comment

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

We can disable the tests for the failing ones yes

@odow
Copy link
Member

odow commented Aug 27, 2025

Let me take over from here and split it up.

@odow
Copy link
Member

odow commented Aug 27, 2025

So you added ZeroOne to the fallback for dual objective value because some tests tried to call constant(::ZeroOne)? Why is IndicatorSOS1Bridge even attempting to test the duals?

This design feels wrong. Could dual tests be opt-in?

Is a separate bug that we don't have a generic fallback for constant? The test error violates the MethodError principle.

@odow
Copy link
Member

odow commented Aug 28, 2025

#2826 removes the use of constant.

@odow odow force-pushed the bl/bridge_dual_test branch from bdcbbd2 to cfcbc5d Compare August 28, 2025 04:00
@odow odow changed the base branch from master to od/dual-objective-simplification August 28, 2025 04:01
# If the bridges does not support `ConstraintDualStart`, it probably won't
# support `ConstraintDual` so we skip these tests
list_of_constraints = MOI.get(model, MOI.ListOfConstraintTypesPresent())
attr = MOI.ConstraintDual()
Copy link
Member

Choose a reason for hiding this comment

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

Did you mean

Suggested change
attr = MOI.ConstraintDual()
attr = MOI.ConstraintDualStart()

Copy link
Member Author

Choose a reason for hiding this comment

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

No, if the bridge don't support ConstraintDual, we skip the test. Because get_fallback don't work with ConstraintDualStart, we need to use ConstraintDual

Base automatically changed from od/dual-objective-simplification to master August 28, 2025 06:42
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