Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions docs/src/apimanual.md
Original file line number Diff line number Diff line change
Expand Up @@ -1110,10 +1110,7 @@ checks that `optimizer` implements support for

If the wrapper does not support building the model incrementally (i.e. with `add_variable` and `add_constraint`), then `supports_default_copy_to` can be replaced by `supports_allocate_load` if appropriate (see [Implementing copy](@ref)) and the line `const bridged = ...` can be replaced with
```julia
# Include here the functions/sets supported by the solver wrapper (not those that are supported through bridges)
MOIU.@model(ModelData, (), (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan) (MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives), (),
(), (MOI.ScalarAffineFunction,), (MOI.VectorOfVariables,), (MOI.VectorAffineFunction,))
const cache = MOIU.UniversalFallback(ModelData{Float64}())
const cache = MOIU.UniversalFallback(MOIU.Model{Float64}())
const cached = MOIU.CachingOptimizer(cache, optimizer)
const bridged = MOIB.full_bridge_optimizer(cached, Float64)
```
Expand Down
16 changes: 9 additions & 7 deletions docs/src/apireference.md
Original file line number Diff line number Diff line change
Expand Up @@ -406,20 +406,22 @@ DeleteNotAllowed

## Models

MOI is designed to be extensible, so there is no fixed list of possible
functions and sets. This makes it challenging to define efficient storage
representations for MOI models. For cases where the functions and sets of
interest are known in advance (for example, solvers support a fixed list of
functions and sets), we provide the [`Utilities.@model`](@ref) that macro
defines a [`ModelLike`](@ref) given a list of functions and sets to support.
[`Utilities.Model`](@ref) provides an implementation of a [`ModelLike`](@ref)
that efficiently supports all functions and sets defined within MOI. However,
given the extensibility of MOI, this might not over all use cases.

[`Utilities.UniversalFallback`](@ref) is a layer that sits on top of any
`ModelLike` and provides non-specialized (slower) fallbacks for constraints and
attributes that the underlying `ModeLike` does not support.

For advanced use cases that need efficient support for functions and sets
defined outside of MOI (but still known at compile time), we provide the
[`Utilities.@model`](@ref) macro.

```@docs
Utilities.@model
Utilities.Model
Utilities.UniversalFallback
Utilities.@model
```

## Bridges
Expand Down
35 changes: 35 additions & 0 deletions src/Utilities/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,8 @@ _getCV(s::SymbolFun) = :($(s.cname){T, $(_getC(s))}())
_callfield(f, s::SymbolFS) = :($f(model.$(_field(s))))
_broadcastfield(b, s::SymbolFS) = :($b(f, model.$(_field(s))))

# This macro is for expert/internal use only. Prefer the concrete Model type
# instantiated below.
"""
macro model(model_name, scalar_sets, typed_scalar_sets, vector_sets, typed_vector_sets, scalar_functions, typed_scalar_functions, vector_functions, typed_vector_functions)

Expand Down Expand Up @@ -934,3 +936,36 @@ macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft)
end
return code
end

const LessThanIndicatorSetOne{T} = MOI.IndicatorSet{MOI.ACTIVATE_ON_ONE, MOI.LessThan{T}}
const LessThanIndicatorSetZero{T} = MOI.IndicatorSet{MOI.ACTIVATE_ON_ZERO, MOI.LessThan{T}}

@model(Model,
(MOI.ZeroOne, MOI.Integer),
(MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval,
MOI.Semicontinuous, MOI.Semiinteger),
(MOI.Reals, MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives,
MOI.SecondOrderCone, MOI.RotatedSecondOrderCone,
MOI.GeometricMeanCone, MOI.ExponentialCone, MOI.DualExponentialCone,
MOI.PositiveSemidefiniteConeTriangle, MOI.PositiveSemidefiniteConeSquare,
MOI.RootDetConeTriangle, MOI.RootDetConeSquare, MOI.LogDetConeTriangle,
MOI.LogDetConeSquare),
(MOI.PowerCone, MOI.DualPowerCone, MOI.SOS1, MOI.SOS2,
LessThanIndicatorSetOne, LessThanIndicatorSetZero),
(),
(MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction),
(MOI.VectorOfVariables,),
(MOI.VectorAffineFunction, MOI.VectorQuadraticFunction))

@doc raw"""
Copy link
Member

Choose a reason for hiding this comment

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

Nice one, I was wondering how we could document that struct that is creating inside a macro


An implementation of `ModelLike` that supports all functions and sets defined
in MOI. It is parameterized by the coefficient type.

# Examples
```jl
model = Model{Float64}()
x = add_variable(model)
```
"""
Model
2 changes: 2 additions & 0 deletions src/sets.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Sets

# Note: When adding a new set, also add it to Utilities.Model.

"""
AbstractSet

Expand Down
14 changes: 4 additions & 10 deletions test/Benchmarks/Benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,18 @@ using MathOptInterface, Test
const MOI = MathOptInterface
const MOIU = MOI.Utilities

MOIU.@model(
BenchmarkModel,
(), (MOI.LessThan, ), (), (),
(), (MOI.ScalarAffineFunction, ), (), ()
)

const NUM_BENCHMARKS = length(MOI.Benchmarks.BENCHMARKS)

@testset "suite" begin
suite = MOI.Benchmarks.suite() do
MOIU.MockOptimizer(BenchmarkModel{Float64}())
MOIU.MockOptimizer(MOIU.Model{Float64}())
end
@test length(suite.data) == NUM_BENCHMARKS

suite = MOI.Benchmarks.suite(
exclude = [r"delete_"]
) do
MOIU.MockOptimizer(BenchmarkModel{Float64}())
MOIU.MockOptimizer(MOIU.Model{Float64}())
end
# Note: update this value whenever more benchmarks are added to
# `src/Benchmarks/Benchmarks.jl`.
Expand All @@ -34,7 +28,7 @@ end
@test !isfile(baseline)
@testset "create_baseline" begin
suite = MOI.Benchmarks.suite() do
MOIU.MockOptimizer(BenchmarkModel{Float64}())
MOIU.MockOptimizer(MOIU.Model{Float64}())
end
MOI.Benchmarks.create_baseline(
suite, "baseline"; directory=@__DIR__, seconds = 2, verbose = true
Expand All @@ -44,7 +38,7 @@ end
@test isfile(baseline)
@testset "compare_against_baseline" begin
suite = MOI.Benchmarks.suite() do
MOIU.MockOptimizer(BenchmarkModel{Float64}())
MOIU.MockOptimizer(MOIU.Model{Float64}())
end
MOI.Benchmarks.compare_against_baseline(
suite, "baseline"; directory=@__DIR__, seconds = 2, verbose = true
Expand Down
4 changes: 1 addition & 3 deletions test/Bridges/Constraint/indicator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ const MOIB = MathOptInterface.Bridges

include("../utilities.jl")

include("../../model.jl")

@testset "Indicator" begin
# linear problem with indicator constraint
# similar to indicator1_test with reversed z1
Expand All @@ -18,7 +16,7 @@ include("../../model.jl")
# z1 == 0 ==> x2 <= 8
# z2 == 1 ==> x2 + x1/5 <= 9
# (1-z1) + z2 >= 1 <=> z2 - z1 >= 0
model = MOIU.MockOptimizer(Model{Float64}());
model = MOIU.MockOptimizer(MOIU.Model{Float64}());
config = MOIT.TestConfig()

x1 = MOI.add_variable(model)
Expand Down
4 changes: 1 addition & 3 deletions test/Test/config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model_for_mock.jl")

function atest(model::MOI.ModelLike, config::MOIT.TestConfig)
@test config.atol == 1e-8
@test config.rtol == 1e-8
Expand All @@ -25,7 +23,7 @@ const customtests = Dict("a" => atest,
MOIT.@moitestset custom

@testset "TestConfig" begin
mock = MOIU.MockOptimizer(ModelForMock{Float64}())
mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()
customtest(mock, config, ["b"])
end
4 changes: 1 addition & 3 deletions test/Test/contconic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model.jl")

mock = MOIU.MockOptimizer(Model{Float64}())
mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()

@testset "Linear" begin
Expand Down
4 changes: 1 addition & 3 deletions test/Test/contlinear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model_for_mock.jl")

mock = MOIU.MockOptimizer(MOIU.UniversalFallback(ModelForMock{Float64}()))
mock = MOIU.MockOptimizer(MOIU.UniversalFallback(MOIU.Model{Float64}()))
config = MOIT.TestConfig(basis = true)
config_no_lhs_modif = MOIT.TestConfig(modify_lhs = false)

Expand Down
4 changes: 1 addition & 3 deletions test/Test/contquadratic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model.jl")

mock = MOIU.MockOptimizer(Model{Float64}())
mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()

@testset "QP" begin
Expand Down
4 changes: 1 addition & 3 deletions test/Test/intconic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model.jl")

mock = MOIU.MockOptimizer(Model{Float64}())
mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()

@testset "SOC" begin
Expand Down
4 changes: 1 addition & 3 deletions test/Test/intlinear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model.jl")

mock = MOIU.MockOptimizer(Model{Float64}())
mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()

MOIU.set_mock_optimize!(mock,
Expand Down
13 changes: 6 additions & 7 deletions test/Test/unit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ const MOI = MathOptInterface
const MOIT = MOI.Test
const MOIU = MOI.Utilities

include("../model.jl")

@testset "Basic Constraint Tests" begin
mock = MOIU.MockOptimizer(Model{Float64}())
mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()
MOIT.basic_constraint_tests(mock, config)
end

@testset "Unit Tests" begin
# `UniversalFallback` needed for `MOI.Silent`
mock = MOIU.MockOptimizer(MOIU.UniversalFallback(Model{Float64}()))
mock = MOIU.MockOptimizer(MOIU.UniversalFallback(MOIU.Model{Float64}()))
MOI.set(mock, MOI.Silent(), true)
config = MOIT.TestConfig()
for model in [mock, MOIU.CachingOptimizer(MOIU.UniversalFallback(Model{Float64}()),
mock)]
for model in [mock,
MOIU.CachingOptimizer(MOIU.UniversalFallback(
MOIU.Model{Float64}()), mock)]
MOIT.unittest(model, config, [
"solve_blank_obj",
"solve_constant_obj",
Expand Down Expand Up @@ -343,7 +342,7 @@ end

@testset "modifications" begin
# `UniversalFallback` needed for `MOI.Silent`
mock = MOIU.MockOptimizer(MOIU.UniversalFallback(Model{Float64}()))
mock = MOIU.MockOptimizer(MOIU.UniversalFallback(MOIU.Model{Float64}()))
config = MOIT.TestConfig()
@testset "solve_set_singlevariable_lessthan" begin
MOIU.set_mock_optimize!(mock,
Expand Down
Loading