-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Comprehensive testing of basic constraint functionality #354
Conversation
Codecov Report
@@ Coverage Diff @@
## master #354 +/- ##
==========================================
- Coverage 96.27% 96.25% -0.03%
==========================================
Files 36 37 +1
Lines 4723 4801 +78
==========================================
+ Hits 4547 4621 +74
- Misses 176 180 +4
Continue to review full report at Codecov.
|
(MOI.VectorOfVariables, MOI.LogDetConeTriangle) => ( dummy_vectorofvariables, 6, MOI.LogDetConeTriangle(3) ), | ||
(MOI.VectorOfVariables, MOI.LogDetConeSquare) => ( dummy_vectorofvariables, 9, MOI.LogDetConeSquare(3) ), | ||
(MOI.VectorOfVariables, MOI.RootDetConeTriangle) => ( dummy_vectorofvariables, 6, MOI.RootDetConeTriangle(3) ), | ||
(MOI.VectorOfVariables, MOI.RootDetConeSquare) => ( dummy_vectorofvariables, 9, MOI.RootDetConeSquare(3) ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blegat are these right? I'm not sure if I understood the docs correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost, you should do +1 (6->7 and 9->10) for the Det-cones to account for the t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could check that with the dimension
function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be clarified in the docs? It currently says:
"The argument dimension
is the side dimension of the matrix X
, i.e., its number of rows or columns."
I took that to mean excluding the t
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the dimension
field excludes the t
but the dimension
function returns the size that a vector set should have to belong to that set so it includes t
and all element of the matrices hence it is 1 + d^2
for LogDetSquare where d
is the field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right. I got confused. The docs are clear now that I read them properly.
This is now RFC. It doesn't attempt to test each method thoroughly. It just tries to check that solvers have implemented the full API for all the This helps avoid situations where you think you've implemented There are a few unchecked items that can probably be addressed in a new PR. |
if length(include) > 0 && length(exclude) > 0 | ||
error("Don't use `include` and `exclude` together.") | ||
end | ||
test_keys = length(include) > 0 ? include : Iterators.filter(x->!(x in exclude), keys(BasicConstraintTests)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you do test_keys = keys(BasicConstraintTests)
in the case where include
and exclude
are both empty. Since you do if MOI.supportsconstraint
later, this would test all supported constraints and remove the need for a ListOfSupportedConstraintTypes
discussed in #357 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does test keys(BasicConstraintTests)
if include
and exclude
are both empty.
If we had ListOfSupportedConstraintTypes
, we could throw a warning that we didn't test SingleVariable
-in-LessThan{Int}
for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does test keys(BasicConstraintTests) if include and exclude are both empty.
Indeed ^^
If we had ListOfSupportedConstraintTypes, we could throw a warning that we didn't test SingleVariable-in-LessThan{Int} for example.
The warning would be called when include
is non-empty and it does not contain all supported sets ? This can already be done now by iterating through the keys of BasicConstraintTests
@test length(c_indices) == 3 # check that we've added a constraint | ||
@test MOI.candelete(model, c_indices[1]) | ||
|
||
@test length(c_indices) == 3 # check that we've added a constraint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is already done three lines before
|
||
@testset "isvalid" begin | ||
c_indices = MOI.get(model, MOI.ListOfConstraintIndices{F,S}()) | ||
@test length(c_indices) == 3 # check that we've added a constraint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the comment
# x₁, x₂ | ||
const dummy_vectorofvariables = (x::Vector{MOI.VariableIndex}) -> MOI.VectorOfVariables(x) | ||
# 1.0 * x | ||
const dummy_scalar_affine = (x::Vector{MOI.VariableIndex}) -> MOI.ScalarAffineFunction(x, [1.0], 0.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[1.0] should be replaced by ones(Float64, length(x))
The naming of |
Merged this as is. We can address the modification tests after #360 is addressed. |
Background
At the moment it is pretty hard from the solver's point-of-view to check that they are implementing the full MOI API correctly (e.g., LQOI). This PR attempts to test this.
For every constraint type supported by the solver, it tests the basic usage of the MOI API. It does not test corner cases. That can come later. In most cases, checking that the solver implemented something correctly will involve forming the problem, modifying, solving, and then checking the solution. This PR just tries to ensure that the methods are implemented.
It has exposed a number of bugs an un-implemented stuff in LQOI (ref JuliaOpt/LinQuadOptInterface.jl#10).
See the tests in Gurobi.jl for an example of how it can be called.
What this does
N.B. some unchecked things still todo.
In particular, it adds tests for basic usage of:
NumberOfConstraints{F,S}()
ListOfConstraintIndices{F,S}()
ConstraintFunction
ConstraintSet
ConstraintName
ConstraintPrimalStart
ConstraintDualStart
ConstraintBasisStatus
ConstraintDual
ConstraintPrimal
for the function-set combinations
ScalarAffineFunction{Float64}
-in-{LessThan, GreaterThan, EqualTo, Interval
}ScalarQuadraticFunction{Float64}
-in-{LessThan, GreaterThan, EqualTo, Interval
}VectorAffineFunction{Float64}
-in-{Zeros,Nonnegatives,Nonpositives,Reals
}VectorQuadraticFunction{Float64}
-in-{Zeros,Nonnegatives,Nonpositives,Reals
}SingleVariable
-in-{LessThan, GreaterThan, EqualTo, Interval
}SingleVariable
-in-{ZeroOne, Integer, Semicontinuous, Semiinteger
}VectorOfVariables
-in-{SOS1, SOS2, Zeros,Nonnegatives,Nonpositives,Reals
}VectorOfVariables
-in-SecondOrderCone
VectorOfVariables
-in-RotatedSecondOrderCone
VectorOfVariables
-in-GeometricMeanCone
VectorOfVariables
-in-ExponentialCone
VectorOfVariables
-in-DualExponentialCone
Considering doing something likeBut, we probably need a way for solvers to specify if they don't support deleting or querying a subset of constraint types.I did something like this.