-
Notifications
You must be signed in to change notification settings - Fork 97
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
odow
left a 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 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
odow
left a 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 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
odow
left a 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.
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 withnandmso I'm trying to figure it out.The number of allocations is a constant + some logarithmic on
nandmwhich is expected (e.g. because ofpushincaches).See #1261
Requires #1267, #1286