OSQP.jl
OSQP.jl copied to clipboard
Throw error if model tries to copy unsupported MOI-Attributes
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