jump-dev / MathOptInterface.jl

A data structure for mathematical optimization problems
http://jump.dev/MathOptInterface.jl/
Other
393 stars 87 forks source link

Improve performance of adding variables with bounds #2564

Open joaquimg opened 4 hours ago

joaquimg commented 4 hours ago

From this simple example:

using JuMP
using HiGHS

using Profile
using PProf

function add_var()
    model = direct_model(HiGHS.Optimizer())
    @variable(model, 1 <= x[i in 1:10000] <= 2)
    return nothing
end

add_var()

Profile.clear()
@profile add_var()

pprof()

we get:

image

So, almost 2/3 of the time is spent on adding the bounds.

But, similar to many other solvers, HiGHS would be able to do both in a single call: Highs_addCol(model, 0.0, -Inf, Inf, 0, C_NULL, C_NULL)

One idea would be:

Create the function(s): MOI.Utilities.add_variable(s)_and_bounds_constraints The fallback would be add_variable(s) + add_constraint(s) But solvers could choose to implement this function, and JuMP would always use it (which would work, thanks to the fallback).

guilhermebodin commented 4 hours ago

One of the problems related to this is that we should be able to query the bounds separately afterward and possibly we would like to query duals related to one of the bounds.

There is some discussion about this on this issue https://github.com/jump-dev/JuMP.jl/issues/3023

odow commented 2 hours ago

So, almost 2/3 of the time is spent on adding the bounds.

I would expect this, since there are three things we need to do: add a variable, add a lower bound, add an upper bound.

Note that if you use Model(HiGHS.Optimizer), then we will do an efficient copy_to operation.

Do you have a real-world example where this operation is a performance problem?

odow commented 2 hours ago

It seems like we could also make a more efficient method in HiGHS' C API to modify a single bound, instead of the iterator that they currently do. (We shouldn't need malloc and free to modify a bound.)