OSQP.jl icon indicating copy to clipboard operation
OSQP.jl copied to clipboard

Throw error if model tries to copy unsupported MOI-Attributes

Open migarstka opened this issue 5 years ago • 0 comments

At the moment the OSQP-MOI-Wrapper only processes some MOI - Attributes, e.g. ObjectiveSense, VariablePrimalStart, ConstraintDualStart, and every attribute, unknown to OSQP, is ignored.

For example the following example wouldn't produce an error:

using OSQP
using OSQP.MathOptInterfaceOSQP
using LinearAlgebra
using Random
using SparseArrays
using Test

using MathOptInterface
const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities
const Affine = MOI.ScalarAffineFunction{Float64}

model = MOIU.UniversalFallback(MOIU.UniversalFallback(OSQPModel{Float64}()));
optimizer = OSQP.Optimizer()
# define any example problem
x = MOI.add_variable(model)
y = MOI.add_variable(model)
cf = MOI.ScalarAffineFunction{Float64}(MOI.ScalarAffineTerm{Float64}.([1., 1.], [x, y]), 0.)
c = MOI.add_constraint(model, cf, MOI.LessThan(0.))
# define an unknown model attribute 
struct UnsupportedModelAttribute  <: MOI.AbstractModelAttribute end
MOI.set(model, UnsupportedModelAttribute(), 0.)
# the attribute gets ignored during copy_to
@test_throws MOI.UnsupportedAttribute{UnsupportedModelAttribute} MOI.copy_to(optimizer, model);

This can lead to problems if the user falsely believes that a provided attribute got copied.

In this example the user uses the wrong macro @NLobjective instead of @objective to define the objective function (notice that I swapped COSMO with OSQP):


using LinearAlgebra, OSQP, JuMP

X=[1 1; 1 2; 2 2 ];
y=[+1 -1 -1 ];
n=length(y);
p=size(X,2);
G=X*X';

model = Model(with_optimizer(OSQP.Optimizer))    
@variables model begin
  alpha[i=1:length(y)] 
end  
@NLobjective(model, Min, sum(0.5*alpha[k]*G[k,i]*y[k]*y[i]*alpha[i] -alpha[k] for i=1:n for k=1:n))
@constraint(model, sum( y[i] * alpha[i] for i=1:n ) == 0)
@constraint(model, [i=1:n], -alpha[i]<=0)
optimize!(model);   

The @NLobjective leads to an attribute NLPblock in the underlying MOI model, which is ignored during copy_to. Instead of throwing an error, OSQP solves the problem as a feasibility problem with P=0 q=0. For the user it is not obvious why the solver doesn't return the expected result.

I would suggest to loop over all the model-, variable- and constraint-attributes in the model and throw an error or warning if one of them is not supported.

It could be done in a similar way to how I fixed the same behaviour in COSMO: https://github.com/oxfordcontrol/COSMO.jl/commit/39d7bc1c7a54214ce7c741a6d04d2b58fe8d91ca

migarstka avatar Nov 18 '19 15:11 migarstka