-
Notifications
You must be signed in to change notification settings - Fork 1
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
Comparison with SparseAxisArray #16
Comments
Ah. One reason for the fast slice is that slicing returns a julia> flow[5, :, 7, 5]
6-element Vector{VariableRef}:
flow[5, 32, 7, 5]
flow[5, 71, 7, 5]
flow[5, 8, 7, 5]
flow[5, 93, 7, 5]
flow[5, 56, 7, 5]
flow[5, 41, 7, 5]
julia> flow[5, :, :, 5]
12-element Vector{VariableRef}:
flow[5, 37, 16, 5]
flow[5, 32, 7, 5]
flow[5, 71, 7, 5]
flow[5, 31, 16, 5]
flow[5, 29, 16, 5]
flow[5, 8, 7, 5]
flow[5, 82, 16, 5]
flow[5, 93, 7, 5]
flow[5, 56, 7, 5]
flow[5, 40, 16, 5]
flow[5, 93, 16, 5]
flow[5, 41, 7, 5] |
Thanks for looking into the details. We have also been looking a bit into SparseAxisArray as an alternative. The speed-up we get over SparseAxisArray is in my view due to two main factors:
You can see the effect of caching by comparing the timing of these two tests that are doing the same without and with caching.
If we are to consider JuMP in some of our industrial settings with large LP problems and hard time requirements, the setup time of the model is an important issue (e.g. problems with a few millions variables, constraints and non-zeros that are required to be run every five minutes). In these settings, model creation can typically take up to 50 % of the time even on finely tuned models in FICO Xpress Mosel. |
Hmm. Yeah the caching is an interesting optimization. I don't know if it's something we'd want to add by default in JuMP because it could lead to weird memory issues on unsuspecting users. And for the hard time requirements: couldn't you build once in Xpress and then modify subsequent problems? I assume a lot of the structure stays the same, and it's just RHSs changing? |
I think most commercial systems use some form of caching to speed up constraint generation. If you have a look at the docs of e.g. the Python API of Gurobi, you will find they have specialized tupledict/tuplelist with some internal data structures to be used for efficient select procedures: To some extent we can modify problems, but at some stage it is more work to keep track of modifications than to just build the model from scratch. In these dynamic supply chain problems you get new and modified orders that will affect a lot of the structure also in the constraint matrix. |
Thanks for following up on this @odow ! I can add to @trulsf 's first point that I had a look into sparse variable construction a while ago, and it is possible to do more efficiently, but very inconvenient (https://github.com/hellemo/SparseHelper.jl). Incremental variable construction like with I've considered looking into wrapping the result of a slicing operation in a new type (SubSparseVar?) which could be used for further indexing, or perhaps for specialized sum or other methods. |
A quick performance update: We have updated the benchmarks from the talk with a new type We also included the newly added support for slicing of https://github.com/hellemo/SparseVariables.jl/blob/main/benchmark/res.svg |
I was interested in how we compare with the default SparseAxisArray in JuMP.
A naive implementation, using
flow = m[:flow]
is terrible, becauseflow
can't be typed correctly. If we use a function barrier, it's still a problem, because the in-liner removes the function barrier for some reason. But if you use@noinline
, then things are nicer. (It's also the reason for the 8 sec in "Test dictionary".)The filter introduces some function call overhead, and the alternative is slightly cheating, because it reduces to a single iteration through the keys of
flow
.So the most interesting target is the sparse slice.
The text was updated successfully, but these errors were encountered: