Conventions for interfacing between JuMP and MathOptInterface

The purpose of this guide is to document the conventions that we have developed for interfacing between JuMP and MathOptInterface.

Attributes

JuMP provides get_attribute and set_attribute as thin shims for MOI.get and MOI.set. However, there are two common cases where the thin shims are not sufficient:

In these two cases, the convention is to keep get_attribute as a thin shim that does not modify the attribute value, and to develop new functions that modify or reshape the value as appropriate.

As an example, JuMP provides dual_start_value and set_dual_start_value to get and set the MOI.ConstraintDualStart in the original matrix shape, while get_attribute and set_attribute can be used to get and set the value in the vectorized shape:

julia> using JuMP
julia> model = Model();
julia> @variable(model, x[1:2, 1:2], PSD);
julia> c = VariableInSetRef(x);
julia> set_dual_start_value(c, [1 0; 0 1])
julia> dual_start_value(c)2×2 LinearAlgebra.Symmetric{Float64, Matrix{Float64}}: 1.0 0.0 0.0 1.0
julia> get_attribute(c, MOI.ConstraintDualStart())3-element Vector{Float64}: 1.0 0.0 1.0
julia> set_attribute(c, MOI.ConstraintDualStart(), [2.0, -1.0, 1.0])
julia> dual_start_value(c)2×2 LinearAlgebra.Symmetric{Float64, Matrix{Float64}}: 2.0 -1.0 -1.0 1.0

unset_ methods

There are a variety of attributes in JuMP and MOI that can be "set" and "unset." For example, there is MOI.Silent, and the corresponding set_silent and unset_silent.

Note how set_silent and unset_silent take a single argument (the model), where set_silent(model) corresponds to MOI.set(model, MOI.Silent(), true) and unset_silent(model) corresponds to MOI.set(model, MOI.Silent(), false). We could have instead implemented a single method set_silent(model, flag::Bool) that corresponded to MOI.set(model, MOI.Silent(), flag). Another example is unset_time_limit_sec, which is equivalent to set_time_limit_sec(model, nothing).

We have come to regard the unset_ design as a mistake, because it leads to a proliferation of unique function names instead of leveraging Julia's strength for multiple dispatch.

The existing unset_ names are retained for backwards compatibility, but, going forward, provide a single set_ method and document what value type should be provided to restore the model to the default setting. Thus, we have set_string_names_on_creation, but no corresponding unset_string_names_on_creation.