-
Notifications
You must be signed in to change notification settings - Fork 94
MatrixOfConstraints #1287
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
MatrixOfConstraints #1287
Conversation
dd03250
to
6206427
Compare
1a42cb5
to
9b3166b
Compare
What's the status of this? Can we make a new MOI release without it? |
There is still some work needed, we don't need to wait for it for a new MOI release |
235c46a
to
3565b31
Compare
8cf4d33
to
ea094b7
Compare
ea094b7
to
38da881
Compare
As another benchmark: how is the first solve? Compilation times are our big killer for this. |
f3a2afb
to
866bca9
Compare
c875104
to
5edfaaf
Compare
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 is quite hard to review because there is a lot of new types being added
- ProductOfSets
- MixOfScalarSets
- OrderedProductOfSets
- OrderedProductOfScalarSets
- UnevenIterator
- Box
- MatrixOfConstraints
- IdentityMap
- MutableSparseMatrixCSC
Can we break it down into smaller pieces? It's not obvious why we need so many different structures, or how they inter-relate.
single_variable_not_added | ||
end | ||
|
||
function final_touch(::MOI.ModelLike, idxmap) end |
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 needs a docstring.
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.
Let me know what you think for the name. Another option would be end_of_copy
if model.variable_indices !== nothing | ||
push!(model.variable_indices, vi) | ||
end | ||
_add_variable(model.constraints) |
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.
It seems weird to force other types to overload _add_variable
. Why not just overload MOI.add_variable(model.constraints)
?
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.
Then VectorOfConstraints
should return a VariableIndex
but currently it does not keep track of this information.
5edfaaf
to
71d0a8b
Compare
aa37bf9
to
82e94cd
Compare
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 needs documentation added to the Utilities
part of the manual.
I wonder about making a subdirectory in src/Utilities
to contain these. That would isolate the code a little more, and better document what goes with what.
I'm also keen to see what impact this has on our time-to-first-solve issue.
return new{F,S}(MOIU.VectorOfConstraints{F,S}()) | ||
end | ||
end | ||
function MOI.Utilities._add_variable(::OnlyCopyConstraints) end |
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.
If this is a public API that people need to implement, it shouldn't begin with _
.
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 needs to be implemented by the type of the constraints
field but it's currently not public API.
It's best we don't let user create new types at the moment until we converge. This is similar to _delete_variables
, _deleted_constraints
and _throw_if_cannot_delete
.
end | ||
|
||
function final_touch(model::MatrixOfConstraints, index_map) | ||
num_rows = number_of_rows(model.sets) |
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 needs documenting
function final_touch(model::MatrixOfConstraints, index_map) | ||
num_rows = number_of_rows(model.sets) | ||
resize!(model.constants, num_rows) | ||
set_number_of_rows(model.coefficients, num_rows) |
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 needs documenting
Return an integer corresponding to the index of the set type in the list given | ||
by [`set_types`](@ref).. | ||
""" | ||
set_index(sets::ProductOfSets, ::Type{S}) where {S<:MOI.AbstractSet} = nothing |
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 needs to be documented in MatrixOfConstraints
40ced0d
to
e806115
Compare
e806115
to
b629e45
Compare
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 have some reservations about adding yet more complexity to MOI. And it would be better if the documentation clearly identified which functions needed to be implemented for which bits, but it may be easier to merge and keep iterating in new PRs. We still have time to break things, so we should merge and then update solvers in branches to figure out what tweaks need to be made.
type_def = :(struct $esc_name{$T} <: $MOIU.OrderedProductOfScalarSets{$T} | ||
num_rows::Vector{Int} | ||
function $esc_name{$T}() where {$T} | ||
return new(zeros(Int, $(1 + length(set_types)))) |
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.
So all this is a OrderedProductOfSets
but without the dimension
field? Then the only efficiency is that we save a Dict{Int,Int}()
call, and a call on empty!
?
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, that not so much. I used to store the dimension for the scalar sets for OrderedProductOfSets
so OrderedProductOfScalarSets
was a big win but now even OrderedProductOfSets
don't store the dimension of scalar sets so we could indeed get rid of OrderedProductOfScalarSets
(although it's just a few lines of code).
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.
Part of this is that it's just a few lines of code, but much more code to compile.
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, I think we can remove it
|
||
```@docs | ||
Utilities.ProductOfSets | ||
Utilities.set_index |
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.
These functions (set_index
, set_types
, add_set
, indices
) get called by MatrixOfConstraints, so they're part of that API. ProductOfSets is just one implementation of the .sets
field.
Is any solver going to implement a different type for the .sets
field? I wonder if we're making our life harder by making this design too flexible...
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 made this into a well-defined API to make the code more understandable. We will need yet another one for list of sets that are not known at compile time, e.g., DiffOpt but we might have enough with 3, can't say for now.
Yes I agree. It's ready so that people can start play with it and we can iterate a bit before releasing. |
Current benchmark:
With this branch, Cbc#od/moi10 and
M=MOIU.Model{Float64}
, I get:With this branch, Cbc#bl/matrix and
M=Cbc.Model
, I get:What really matters is the sum of the two. The speedup is approximately 10x.
We already have a significant decrease but I think we could have a number of allocation which does not scale linearly withn
andm
so I'm trying to figure it out.The number of allocations is a constant + some logarithmic on
n
andm
which is expected (e.g. because ofpush
incaches
).See #1261
Requires #1267, #1286