Skip to content
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

Add support for starting values #111

Merged
merged 2 commits into from
Sep 30, 2018
Merged

Add support for starting values #111

merged 2 commits into from
Sep 30, 2018

Conversation

blegat
Copy link
Member

@blegat blegat commented Sep 27, 2018

@ccoffrin Can you test it and report whether it works as expected for your use case ?

Closes #109

@ccoffrin
Copy link

Using JuMP master, MOI v0.6.1 and this branch I am getting,

ERROR: MethodError: no method matching allocate(::SCS.Optimizer, ::MathOptInterface.ObjectiveFunction{MathOptInterface.ScalarQuadraticFunction{Float64}}, ::MathOptInterface.ScalarQuadraticFunction{Float64})
Closest candidates are:
  allocate(::MathOptInterface.Utilities.AbstractModel, ::Any...) at /home/.julia/v0.6/MathOptInterface/src/Utilities/model.jl:339
  allocate(::MathOptInterface.Utilities.MockOptimizer, ::MathOptInterface.ObjectiveFunction, ::Any) at /home/.julia/v0.6/MathOptInterface/src/Utilities/mockoptimizer.jl:285
  allocate(::MathOptInterface.Utilities.MockOptimizer, ::Union{MathOptInterface.AbstractConstraintAttribute, MathOptInterface.AbstractModelAttribute, MathOptInterface.AbstractOptimizerAttribute, MathOptInterface.AbstractVariableAttribute}, ::Any) at /home/.julia/v0.6/MathOptInterface/src/Utilities/mockoptimizer.jl:284
  ...
Stacktrace:
 [1] _pass_attributes(::SCS.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}, ::Bool, ::MathOptInterface.Utilities.IndexMap, ::Array{MathOptInterface.AbstractModelAttribute,1}, ::Tuple{}, ::Tuple{}, ::Tuple{}, ::MathOptInterface.Utilities.#allocate) at /home/.julia/v0.6/MathOptInterface/src/Utilities/copy.jl:59
 [2] allocate_load(::SCS.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}, ::Bool) at /home/.julia/v0.6/MathOptInterface/src/Utilities/copy.jl:248
 [3] (::MathOptInterface.#kw##copy_to)(::Array{Any,1}, ::MathOptInterface.#copy_to, ::SCS.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}) at ./<missing>:0
 [4] attachoptimizer!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}}) at /home/.julia/v0.6/MathOptInterface/src/Utilities/cachingoptimizer.jl:125
 [5] optimize!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}}) at /home/.julia/v0.6/MathOptInterface/src/Utilities/cachingoptimizer.jl:158
 [6] optimize!(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}},MathOptInterface.Bridges.AllBridgedConstraints{Float64}}) at /home/.julia/v0.6/MathOptInterface/src/Bridges/bridgeoptimizer.jl:73
 [7] #optimize!#92(::Bool, ::Function, ::JuMP.Model, ::Void) at /home/.julia/v0.6/JuMP/src/optimizer_interface.jl:65
 [8] macro expansion at ./util.jl:378 [inlined]
 [9] optimize!(::PowerModels.GenericPowerModel{PowerModels.SDPWRMForm}) at /home/.julia/v0.6/PowerModels/src/core/base.jl:126
 [10] #solve_generic_model#83(::Function, ::Function, ::PowerModels.GenericPowerModel{PowerModels.SDPWRMForm}, ::SCS.Optimizer) at /home/.julia/v0.6/PowerModels/src/core/base.jl:201
 [11] (::PowerModels.#kw##solve_generic_model)(::Array{Any,1}, ::PowerModels.#solve_generic_model, ::PowerModels.GenericPowerModel{PowerModels.SDPWRMForm}, ::SCS.Optimizer) at ./<missing>:0
 [12] #run_generic_model#80(::Function, ::Array{Any,1}, ::Function, ::Dict{String,Any}, ::Type{T} where T, ::SCS.Optimizer, ::Function) at /home/.julia/v0.6/PowerModels/src/core/base.jl:171
 [13] run_generic_model(::Dict{String,Any}, ::Type{T} where T, ::SCS.Optimizer, ::Function) at /home/.julia/v0.6/PowerModels/src/core/base.jl:169
 [14] #run_generic_model#79(::Array{Any,1}, ::Function, ::String, ::Type{T} where T, ::SCS.Optimizer, ::Function) at /home/.julia/v0.6/PowerModels/src/core/base.jl:164
 [15] #run_opf#325 at /home/.julia/v0.6/PowerModels/src/prob/opf.jl:15 [inlined]
 [16] run_opf(::String, ::Type{T} where T, ::SCS.Optimizer) at /home/.julia/v0.6/PowerModels/src/prob/opf.jl:15

@blegat
Copy link
Member Author

blegat commented Sep 27, 2018

SCS does not support quadratic objective function. We might create a bridge that transforms into SOC constraint in MOI but this is not done yet. No change should be done in SCS for that, this is a missing feature in MOI.

@blegat
Copy link
Member Author

blegat commented Sep 27, 2018

Once we have a bridge to move the objective to a constraint as described in jump-dev/MathOptInterface.jl#529, it remains to transform to quadratic constraint to a SOC constraint but there is an open PR for that:
jump-dev/MathOptInterface.jl#483

@mlubin
Copy link
Member

mlubin commented Sep 27, 2018

The MethodError is still a bug via http://www.juliaopt.org/JuMP.jl/latest/style.html#User-facing-MethodError-1 though. (Not related to this PR though.)

@@ -259,13 +260,46 @@ function MOIU.load_variables(optimizer::Optimizer, nvars::Integer)
b = zeros(m)
c = zeros(nvars)
optimizer.data = ModelData(m, nvars, I, J, V, b, 0., c)
if length(optimizer.sol.primal) != nvars
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What could the length be if not nvars? Would isempty also work as a test? Same below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sol contains the solution of the previous optimization. If the user has added new variables, then it is not nvars

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this interface allow adding variables and/or constraints?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can copy a model with a different number of variables/constraints. Normally, they will arrive in the same order.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this if be replaced with resize! then?

@ccoffrin
Copy link

I think there may be a deeper issue here. As far as I can tell PowerModels is posting a linear objective in the JuMP model. See this code, https://github.com/lanl-ansi/PowerModels.jl/blob/moi/src/core/objective.jl#L104

Is it possible that JuMP is interpreting the objective as quadratic when it is linear?

@mlubin
Copy link
Member

mlubin commented Sep 28, 2018

Do we have a test for this functionality anywhere?

@ccoffrin
Copy link

Do you have a test were the model has conic constraints and a linear objective?

@ccoffrin
Copy link

In any case, this PR seems to have resolved #109, should we move this later point to a separate thread?

@blegat
Copy link
Member Author

blegat commented Sep 28, 2018

Yes we can open an issue on JuMP, if you could produce a MWE producing a quadratic objective when it should be linear, it would help. It is probably because of a promotion that shouldn't happen.
For instance if you do

@objective(model, [1, 2]' * [x, y])

if the product is handled by a function that start by promoting the two vectors to the same type, it will promote them to affine expressions and hence the result would be quadratic.
I would guess that you have somthing similar.

@@ -259,13 +260,46 @@ function MOIU.load_variables(optimizer::Optimizer, nvars::Integer)
b = zeros(m)
c = zeros(nvars)
optimizer.data = ModelData(m, nvars, I, J, V, b, 0., c)
if length(optimizer.sol.primal) != nvars
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this interface allow adding variables and/or constraints?

@blegat
Copy link
Member Author

blegat commented Sep 28, 2018

@ccoffrin Can you retest now that a7591c6 has been added.
I forgot to set warm_start to SCS_solve so it was using zero as warm start instead of using the provided value.
Now you should get a better result

@ccoffrin
Copy link

@blegat, I confirmed on the latest commit on this branch I still have the issue with the objective function being quadratic. Probably the starting value is improved; but I don't know yet.

On a side note, I never used to provide starting values to SCS in PowerModels. Now I am because of the all or nothing start value semantics.

@ccoffrin
Copy link

@blegat good news, I found a bug in my code, which was the cause of the quadratic objective function. That is fixed now.

Now I am getting this error,

ERROR: MethodError: no method matching _allocate_constraint(::SCS.ConeData, ::MathOptInterface.VectorAffineFunction{Float64}, ::MathOptInterface.PositiveSemidefiniteConeSquare)
Closest candidates are:
  _allocate_constraint(::SCS.ConeData, ::Any, ::Union{MathOptInterface.EqualTo, MathOptInterface.Zeros}) at home/.julia/v0.6/SCS/src/MOIWrapper.jl:100
  _allocate_constraint(::SCS.ConeData, ::Any, ::Union{MathOptInterface.GreaterThan, MathOptInterface.LessThan, MathOptInterface.Nonnegatives, MathOptInterface.Nonpositives}) at home/.julia/v0.6/SCS/src/MOIWrapper.jl:106
  _allocate_constraint(::SCS.ConeData, ::Any, ::MathOptInterface.SecondOrderCone) at home/.julia/v0.6/SCS/src/MOIWrapper.jl:112
  ...
Stacktrace:
 [1] allocate_constraint at home/.julia/v0.6/SCS/src/MOIWrapper.jl:132 [inlined]
 [2] allocate_constraints(::SCS.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}, ::Bool, ::MathOptInterface.Utilities.IndexMap, ::Type{MathOptInterface.VectorAffineFunction{Float64}}, ::Type{MathOptInterface.PositiveSemidefiniteConeSquare}) at home/.julia/v0.6/MathOptInterface/src/Utilities/copy.jl:205
 [3] allocate_load(::SCS.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{JuMP.JuMPMOIModel{Float64}}, ::Bool) at home/.julia/v0.6/MathOptInterface/src/Utilities/copy.jl:253

Recommendations?

@blegat
Copy link
Member Author

blegat commented Sep 29, 2018

This cone is not supported by SCS and should be bridged. It should be bridged automatically if you use JuMP master with MOI v0.6.1.
You should also normally receive the error message of jump-dev/JuMP.jl#1476 instead of this cryptic method error.

@ccoffrin
Copy link

ccoffrin commented Sep 29, 2018 via email

@blegat
Copy link
Member Author

blegat commented Sep 29, 2018

What would be the translation of this into JuMP v0.19 / MOI?

Same thing.

I just realized that you might get the error you give in #111 (comment) if you do not provide the solver in the Model constructor but rather in the optimize! call. Is that the case ?

@ccoffrin
Copy link

To finish up this discussion. You are correct, specifying the optimizer in the JuMP model constructor resolved the most recent issue. The only remaining issue I have at the moment is with setting the solver parameters (i.e. #113). In any case, this starting point fix is working great for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants