From 2c894068e3c53daa8be78c9791b5d9f0226ee075 Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 30 Apr 2021 15:56:32 +1200 Subject: [PATCH 1/5] [breaking] Rename MOIU.supports_default_copy_to to MOI.supports_incremental_interface --- docs/src/manual/implementing.md | 26 ++++---- docs/src/submodules/Test/overview.md | 8 +-- docs/src/submodules/Utilities/reference.md | 2 +- src/Bridges/bridge_optimizer.jl | 4 +- src/MathOptInterface.jl | 30 +++++++++ src/Test/contconic.jl | 76 +++++++++++----------- src/Test/contlinear.jl | 36 +++++----- src/Test/contquadratic.jl | 20 +++--- src/Test/intconic.jl | 2 +- src/Test/intlinear.jl | 12 ++-- src/Test/modellike.jl | 12 ++-- src/Utilities/cachingoptimizer.jl | 8 +-- src/Utilities/copy.jl | 48 ++------------ src/Utilities/mockoptimizer.jl | 4 +- src/Utilities/model.jl | 2 +- src/Utilities/universalfallback.jl | 4 +- src/instantiate.jl | 30 ++++----- test/Utilities/cachingoptimizer.jl | 2 +- test/Utilities/copy.jl | 10 +-- 19 files changed, 162 insertions(+), 174 deletions(-) diff --git a/docs/src/manual/implementing.md b/docs/src/manual/implementing.md index f582d044d3..dc8e7870b8 100644 --- a/docs/src/manual/implementing.md +++ b/docs/src/manual/implementing.md @@ -453,25 +453,23 @@ MOI.supports_add_constrained_variables(::Optimizer, ::Type{Reals}) = false ### Incremental and `copy_to` If you implement the incremental interface, you have the option of also -implementing [`copy_to`](@ref). If you don't want to implement -[`copy_to`](@ref), e.g., because the solver has no API for building the problem -in a single function call, define the following fallback: +implementing [`copy_to`](@ref). + +If you don't want to implement [`copy_to`](@ref), e.g., because the solver has +no API for building the problem in a single function call, define the following +fallback: ```julia +# If you support VariableName and ConstraintName... +MOI.supports_incremental_interface(::Optimizer, copy_names::Bool) = true +# Otherwise... +MOI.supports_incremental_interface(::Optimizer, copy_names::Bool) = !copy_names + function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike; kwargs...) return MOI.Utilities.automatic_copy_to(dest, src; kwargs...) end - -function MOI.Utilities.supports_default_copy_to( - model::Optimizer, - copy_names::Bool, -) - # If you support names... - return true - # Otherwise... - return !copy_names -end ``` -See [`Utilities.supports_default_copy_to`](@ref) for more details. +See [`MOI.supports_incremental_interface`](@ref) for more details on whether to +implement the `true` or `!copy_names` version. ## [Names](@id implement_names) diff --git a/docs/src/submodules/Test/overview.md b/docs/src/submodules/Test/overview.md index f6a48fdd5a..81406431d4 100644 --- a/docs/src/submodules/Test/overview.md +++ b/docs/src/submodules/Test/overview.md @@ -22,7 +22,7 @@ so that all solvers can benefit. The skeleton below can be used for the wrapper test file of a solver named `FooBar`. Remove unnecessary tests as appropriate, for example tests for features that the solver does not support (tests are not skipped depending -on the value of `supports`). +on the value of `supports`). ```julia # ============================ /test/MOI_wrapper.jl ============================ @@ -61,10 +61,10 @@ function test_SolverName() @test MOI.get(OPTIMIZER, MOI.SolverName()) == "FooBar" end -function test_supports_default_copy_to() - @test MOI.Utilities.supports_default_copy_to(OPTIMIZER, false) +function test_supports_incremental_interface() + @test MOI.Utilities.supports_incremental_interface(OPTIMIZER, false) # Use `@test !...` if names are not supported - @test MOI.Utilities.supports_default_copy_to(OPTIMIZER, true) + @test MOI.Utilities.supports_incremental_interface(OPTIMIZER, true) end function test_unittest() diff --git a/docs/src/submodules/Utilities/reference.md b/docs/src/submodules/Utilities/reference.md index 638125e293..f51ae504fc 100644 --- a/docs/src/submodules/Utilities/reference.md +++ b/docs/src/submodules/Utilities/reference.md @@ -52,7 +52,7 @@ Utilities.mode ```@docs Utilities.automatic_copy_to Utilities.default_copy_to -Utilities.supports_default_copy_to +Utilities.supports_incremental_interface ``` ### [Allocate-Load API](@id allocate_load_api_ref) diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index 3949f148e4..7c9a8fa0d2 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -358,11 +358,11 @@ end function MOI.copy_to(mock::AbstractBridgeOptimizer, src::MOI.ModelLike; kws...) return MOIU.automatic_copy_to(mock, src; kws...) end -function MOIU.supports_default_copy_to( +function MOI.supports_incremental_interface( b::AbstractBridgeOptimizer, copy_names::Bool, ) - return MOIU.supports_default_copy_to(b.model, copy_names) + return MOI.supports_incremental_interface(b.model, copy_names) end # References diff --git a/src/MathOptInterface.jl b/src/MathOptInterface.jl index 03015f7558..137ecbabd5 100644 --- a/src/MathOptInterface.jl +++ b/src/MathOptInterface.jl @@ -94,6 +94,36 @@ Empty the model, that is, remove all variables, constraints and model attributes """ function empty! end +""" + supports_incremental_interface(model::ModelLike, copy_names::Bool) + +Return a `Bool` indicating whether `model` supports building incrementally via +[`add_variable`](@ref) and [`add_constraint`](@ref). + +`copy_names` is a `Bool` indicating whether the user wishes to set +[`VariableName`](@ref) and [`ConstraintName`](@ref) attributes. +If `model` supports the incremental interface but does not support name +attributes, define +```julia +supports_incremental_interface(::MyNewModel, copy_names::Bool) = !copy_names +``` + +The main purpose of this function is to determine whether a model can be loaded +into `model` incrementally or whether it should be cached and copied at once +instead. + +This is used by [`instantiate`](@ref) to determine whether to add a cache in two +situations: +1. A first cache can be used to store the model as entered by the user as well + as the names of variables and constraints. This cache is created if this + function returns `false` when `copy_names` is `true`. +2. If bridges are used, then a second cache can be used to store the bridged + model with unnamed variables and constraints. This cache is created if this + function returns `false` when `copy_names` is `false`. +``` +""" +supports_incremental_interface(::ModelLike, ::Bool) = false + """ copy_to(dest::ModelLike, src::ModelLike; copy_names=true, warn_attributes=true) diff --git a/src/Test/contconic.jl b/src/Test/contconic.jl index dbf0a1a919..0a57abd50d 100644 --- a/src/Test/contconic.jl +++ b/src/Test/contconic.jl @@ -11,7 +11,7 @@ function _lin1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool) # x>=0 y>=0 z>=0 # Opt obj = -11, soln x = 1, y = 0, z = 2 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -157,7 +157,7 @@ function _lin2test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool) # Opt solution = -82 # x = -4, y = -3, z = 16, s == 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -346,7 +346,7 @@ function lin3test(model::MOI.ModelLike, config::TestConfig) # s.t. -1 + x ∈ R₊ # 1 + x ∈ R₋ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -436,7 +436,7 @@ function lin4test(model::MOI.ModelLike, config::TestConfig) # s.t. -1 + x ∈ R₊ # x ∈ R₋ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -524,7 +524,7 @@ function _norminf1test( # y == 1/2 # x >= ||(y,z)||_∞ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -671,7 +671,7 @@ function norminf2test(model::MOI.ModelLike, config::TestConfig) # -1 + x ∈ R₋ # (x,y) ∈ NormInf₂ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -772,7 +772,7 @@ function norminf3test(model::MOI.ModelLike, config::TestConfig) # (1 .+ y) in Nonnegatives(n) # let n = 3. optimal solution: y .= -1, x = 2 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -884,7 +884,7 @@ function _normone1test( # y == 1/2 # x >= ||(y,z)||_1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1027,7 +1027,7 @@ function normone2test(model::MOI.ModelLike, config::TestConfig) # -1 + x ∈ R₋ # (x,y) ∈ NormOne₂ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1128,7 +1128,7 @@ function normone3test(model::MOI.ModelLike, config::TestConfig) # (1 .+ y) in Nonnegatives(n) # let n = 3. optimal solution: y .= -1, x = 4 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -1234,7 +1234,7 @@ function _soc1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool) # st x == 1 # x >= ||(y,z)|| - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1365,7 +1365,7 @@ function _soc2test(model::MOI.ModelLike, config::TestConfig, nonneg::Bool) # 1 - t ∈ {0} # (t,x,y) ∈ SOC₃ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1530,7 +1530,7 @@ function soc3test(model::MOI.ModelLike, config::TestConfig) # -1 + x ∈ R₋ # (x,y) ∈ SOC₂ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1638,7 +1638,7 @@ function soc4test(model::MOI.ModelLike, config::TestConfig) # Like SOCINT1 but with copies of variables and integrality relaxed # Tests out-of-order indices in cones - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1760,7 +1760,7 @@ function _rotatedsoc1test( # [0.0] - [-y ] SOCRotated # [0.0] - [ -z] SOCRotated - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1913,7 +1913,7 @@ function rotatedsoc2test(model::MOI.ModelLike, config::TestConfig) b = [-2, -1, 1 / 2] c = [0.0, 0.0, 0.0] - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2036,7 +2036,7 @@ function rotatedsoc3test( # [t1/√2, t2/√2, x] in SOC4 # [x1/√2, u/√2, v] in SOC3 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2232,7 +2232,7 @@ function rotatedsoc4test( # We conclude that the optimal solution is x = y = t = u = 1 # with objective value 2. - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2335,7 +2335,7 @@ function _geomean1test( # Therefore xyz ≤ 1 # This can be attained using x = y = z = 1 so it is optimal. - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2451,7 +2451,7 @@ function _geomean2test(model::MOI.ModelLike, config::TestConfig, vecofvars) # x_1 == x_2, ..., x_9 == 1 # the optimal solution is 1 with optimal value 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2575,7 +2575,7 @@ function _geomean3test(model::MOI.ModelLike, config::TestConfig, vecofvars) # x <= 2 # the optimal solution is (t, x) = (2, 2) with objective value 4 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2696,7 +2696,7 @@ function _exp1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool) # x == 1 # y == 2 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2813,7 +2813,7 @@ function exp2test(model::MOI.ModelLike, config::TestConfig) atol = config.atol rtol = config.rtol - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -2991,7 +2991,7 @@ function exp3test(model::MOI.ModelLike, config::TestConfig) atol = config.atol rtol = config.rtol - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -3109,7 +3109,7 @@ function _dualexp1test( # w == 1 # (u, v, w) ∈ DualExponentialCone - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -3257,7 +3257,7 @@ function _pow1test(model::MOI.ModelLike, config::TestConfig, vecofvars::Bool) # v + β = 0 # w = -1 a = 0.9 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -3397,7 +3397,7 @@ function _dualpow1test( # hence you get v = 0.1 and u = 0.9. # The same works for other values of exponent as key word argument - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -3538,7 +3538,7 @@ function relentr1test(model::MOI.ModelLike, config::TestConfig) # Optimal solution is: # u = 2*log(2/1) + 3*log(3/5) ≈ -0.1461825 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -3615,7 +3615,7 @@ function normspec1test(model::MOI.ModelLike, config::TestConfig) # Singular values are [sqrt(3), sqrt(2)], so optimal solution is: # t = sqrt(3) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -3689,7 +3689,7 @@ function normspec2test(model::MOI.ModelLike, config::TestConfig) # Singular values are [sqrt(3), sqrt(2)], so optimal solution is: # t = sqrt(3) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -3767,7 +3767,7 @@ function normnuc1test(model::MOI.ModelLike, config::TestConfig) # Singular values are [sqrt(3), sqrt(2)], so optimal solution is: # t = sqrt(3) + sqrt(2) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -3844,7 +3844,7 @@ function normnuc2test(model::MOI.ModelLike, config::TestConfig) # Singular values are [sqrt(3), sqrt(2)], so optimal solution is: # t = sqrt(3) + sqrt(2) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( @@ -3934,7 +3934,7 @@ function _psd0test( # X = ⎜ ⎟ y = 2 # ⎝ 1 1 ⎠ - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -4130,7 +4130,7 @@ function _psd1test( α = √(3 - 2obj - 4x2) / 2 β = k * α - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -4308,7 +4308,7 @@ function psdt2test(model::MOI.ModelLike, config::TestConfig) rtol = config.rtol # Caused getdual to fail on SCS and Mosek - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -4494,7 +4494,7 @@ function _psd3test( atol = config.atol rtol = config.rtol - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint(model, MOI.VectorAffineFunction{T}, psdcone) @@ -4631,7 +4631,7 @@ function _det1test( # |_________| # -Q22 ≥ -1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -4808,7 +4808,7 @@ function _det2test(model::MOI.ModelLike, config::TestConfig, detcone) mat = Float64[3 2 1; 2 2 1; 1 1 3] matL = Float64[3, 2, 2, 1, 1, 3] - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports(model, MOI.ObjectiveFunction{MOI.SingleVariable}()) @test MOI.supports(model, MOI.ObjectiveSense()) @test MOI.supports_constraint( diff --git a/src/Test/contlinear.jl b/src/Test/contlinear.jl index dfc5fa7bc2..3cb20ed28e 100644 --- a/src/Test/contlinear.jl +++ b/src/Test/contlinear.jl @@ -9,7 +9,7 @@ function linear1test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # st x + y <= 1 (x + y - 1 ∈ Nonpositives) # x, y >= 0 (x, y ∈ Nonnegatives) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -571,7 +571,7 @@ function linear2test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. x + y <= 1 # x, y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -681,7 +681,7 @@ function linear3test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. x >= 0 # x >= 3 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -820,7 +820,7 @@ function linear4test(model::MOI.ModelLike, config::TestConfig{T}) where {T} atol = config.atol rtol = config.rtol - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -930,7 +930,7 @@ function linear5test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # # solution: x = 1.3333333, y = 1.3333333, objv = 2.66666666 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1099,7 +1099,7 @@ function linear6test(model::MOI.ModelLike, config::TestConfig{T}) where {T} atol = config.atol rtol = config.rtol - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1238,7 +1238,7 @@ function linear7test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # w == 1 (c2) # i.e. z == w == 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1389,7 +1389,7 @@ function linear8atest(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. 2x+y <= -1 # x,y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1476,7 +1476,7 @@ function linear8btest(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. -x+2y <= 0 # x,y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1553,7 +1553,7 @@ function linear8ctest(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. x-y == 0 # x,y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1639,7 +1639,7 @@ function linear9test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # solution: (59.0909, 36.3636) # objv: 71818.1818 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1746,7 +1746,7 @@ function linear10test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. 5 <= x + y <= 10 # x, y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -1952,7 +1952,7 @@ function linear10btest(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. -1 <= x + y <= 10 # x, y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -2071,7 +2071,7 @@ function linear11test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # w >= 0, z <= 0 # sol: w = 1, z = 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -2159,7 +2159,7 @@ function linear12test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # y <= 2 # x,y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -2250,7 +2250,7 @@ function linear13test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # s.t. 2x + 3y >= 1 # x - y == 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports_constraint( model, MOI.ScalarAffineFunction{T}, @@ -2329,7 +2329,7 @@ function linear14test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # x, y, z >= 0 # z <= 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), @@ -2492,7 +2492,7 @@ function linear15test(model::MOI.ModelLike, config::TestConfig{T}) where {T} # minimize 0 # s.t. 0 == 0 # x == 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), diff --git a/src/Test/contquadratic.jl b/src/Test/contquadratic.jl index 3c44de18fa..55ee0e7f1e 100644 --- a/src/Test/contquadratic.jl +++ b/src/Test/contquadratic.jl @@ -9,7 +9,7 @@ function qp1test(model::MOI.ModelLike, config::TestConfig) # x + y >= 1 (c2) # x, y, z \in R - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}}(), @@ -120,7 +120,7 @@ function qp2test(model::MOI.ModelLike, config::TestConfig) # x + y >= 1 (c2) # x, y, z \in R - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}}(), @@ -274,7 +274,7 @@ function qp3test(model::MOI.ModelLike, config::TestConfig) # s.t. x, y >= 0 # x + y = 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}}(), @@ -414,7 +414,7 @@ function qcp1test(model::MOI.ModelLike, config::TestConfig) # Optimal solution # x = 1/2, y = 7/4 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -540,7 +540,7 @@ function qcp2test(model::MOI.ModelLike, config::TestConfig) # Max x # s.t. x^2 <= 2 (c) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -618,7 +618,7 @@ function qcp3test(model::MOI.ModelLike, config::TestConfig) # Min -x # s.t. x^2 <= 2 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -701,7 +701,7 @@ function _qcp4test(model::MOI.ModelLike, config::TestConfig, less_than::Bool) # s.t. x^2 + x * y + y^2 <= 3 (c) # y == 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -818,7 +818,7 @@ function ncqcp1test(model::MOI.ModelLike, config::TestConfig) # s.t. x * y <= 4 (c) # x, y >= 1 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -903,7 +903,7 @@ function ncqcp2test(model::MOI.ModelLike, config::TestConfig) # x * x == 4 (c2) # x, y >= 0 - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports_constraint( model, MOI.ScalarQuadraticFunction{Float64}, @@ -990,7 +990,7 @@ function socp1test(model::MOI.ModelLike, config::TestConfig) # x^2 + y^2 <= t^2 (c2) # t >= 0 (bound) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), diff --git a/src/Test/intconic.jl b/src/Test/intconic.jl index e36bc2fc6c..89fe6a5d2e 100644 --- a/src/Test/intconic.jl +++ b/src/Test/intconic.jl @@ -10,7 +10,7 @@ function intsoc1test(model::MOI.ModelLike, config::TestConfig) # x >= ||(y,z)|| # (y,z) binary - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), diff --git a/src/Test/intlinear.jl b/src/Test/intlinear.jl index fdad93f07d..e05e5ac2a6 100644 --- a/src/Test/intlinear.jl +++ b/src/Test/intlinear.jl @@ -13,7 +13,7 @@ function int1test(model::MOI.ModelLike, config::TestConfig) # y is integer: 0 <= y <= 10 # z is binary - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -147,7 +147,7 @@ function int2test(model::MOI.ModelLike, config::TestConfig) atol = config.atol rtol = config.rtol @testset "SOSI" begin - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -266,7 +266,7 @@ function int2test(model::MOI.ModelLike, config::TestConfig) end end @testset "SOSII" begin - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -426,7 +426,7 @@ function int3test(model::MOI.ModelLike, config::TestConfig) MOI.empty!(model) @test MOI.is_empty(model) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -519,7 +519,7 @@ function knapsacktest(model::MOI.ModelLike, config::TestConfig) MOI.empty!(model) @test MOI.is_empty(model) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -1032,7 +1032,7 @@ function _semitest( atol = config.atol rtol = config.rtol - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# @test MOI.supports( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), diff --git a/src/Test/modellike.jl b/src/Test/modellike.jl index 9d51eda101..4aae63fdd3 100644 --- a/src/Test/modellike.jl +++ b/src/Test/modellike.jl @@ -79,7 +79,7 @@ function nametest(model::MOI.ModelLike) @testset "Name test with $(typeof(model))" begin MOI.empty!(model) - @test MOIU.supports_default_copy_to(model, true) #=copy_names=# + @test MOI.supports_incremental_interface(model, true) #=copy_names=# @test MOI.supports(model, MOI.Name()) @test !(MOI.Name() in MOI.get(model, MOI.ListOfModelAttributesSet())) @test MOI.get(model, MOI.Name()) == "" @@ -352,7 +352,7 @@ end # Taken from https://github.com/jump-dev/MathOptInterfaceUtilities.jl/issues/41 function validtest(model::MOI.ModelLike) MOI.empty!(model) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# v = MOI.add_variables(model, 2) @test MOI.is_valid(model, v[1]) @test MOI.is_valid(model, v[2]) @@ -404,7 +404,7 @@ end function emptytest(model::MOI.ModelLike) MOI.empty!(model) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# # Taken from LIN1 v = MOI.add_variables(model, 3) @test MOI.supports_constraint( @@ -700,7 +700,7 @@ end function start_values_test(dest::MOI.ModelLike, src::MOI.ModelLike) MOI.empty!(dest) - @test MOIU.supports_default_copy_to(src, false) #=copy_names=# + @test MOI.supports_incremental_interface(src, false) #=copy_names=# x, y, z = MOI.add_variables(src, 3) fz = MOI.SingleVariable(z) a = MOI.add_constraint(src, x, MOI.EqualTo(1.0)) @@ -784,7 +784,7 @@ function start_values_test(dest::MOI.ModelLike, src::MOI.ModelLike) end function copytest(dest::MOI.ModelLike, src::MOI.ModelLike; copy_names = false) - @test MOIU.supports_default_copy_to(src, true) #=copy_names=# + @test MOI.supports_incremental_interface(src, true) #=copy_names=# MOI.empty!(src) MOI.empty!(dest) MOI.set(src, MOI.Name(), "ModelName") @@ -1000,7 +1000,7 @@ Test whether the model returns ListOfVariableIndices and ListOfConstraintIndices sorted by creation time. """ function orderedindicestest(model::MOI.ModelLike) - @test MOIU.supports_default_copy_to(model, false) #=copy_names=# + @test MOI.supports_incremental_interface(model, false) #=copy_names=# MOI.empty!(model) v1 = MOI.add_variable(model) @test MOI.get(model, MOI.ListOfVariableIndices()) == [v1] diff --git a/src/Utilities/cachingoptimizer.jl b/src/Utilities/cachingoptimizer.jl index 8cc42c29a8..4eed7e34cf 100644 --- a/src/Utilities/cachingoptimizer.jl +++ b/src/Utilities/cachingoptimizer.jl @@ -127,9 +127,9 @@ function reset_optimizer(m::CachingOptimizer, optimizer::MOI.AbstractOptimizer) for attr in MOI.get(m.model_cache, MOI.ListOfOptimizerAttributesSet()) # Skip attributes which don't apply to the new optimizer. if attr isa MOI.RawParameter - # Even if the optimizer claims to `supports` `attr`, the value + # Even if the optimizer claims to `supports` `attr`, the value # might have a different meaning (e.g., two solvers with `logLevel` - # as a RawParameter). To be on the safe side, just skip all raw + # as a RawParameter). To be on the safe side, just skip all raw # parameters. continue elseif !MOI.is_copyable(attr) || !MOI.supports(m.optimizer, attr) @@ -224,8 +224,8 @@ function MOI.copy_to(m::CachingOptimizer, src::MOI.ModelLike; kws...) m.state == ATTACHED_OPTIMIZER && reset_optimizer(m) return MOI.copy_to(m.model_cache, src; kws...) end -function supports_default_copy_to(model::CachingOptimizer, copy_names::Bool) - return supports_default_copy_to(model.model_cache, copy_names) +function MOI.supports_incremental_interface(model::CachingOptimizer, copy_names::Bool) + return MOI.supports_incremental_interface(model.model_cache, copy_names) end function MOI.empty!(m::CachingOptimizer) diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 74995ac7af..5c047249e8 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -5,7 +5,7 @@ copy_names::Bool=true, filter_constraints::Union{Nothing, Function}=nothing) -Use [`Utilities.supports_default_copy_to`](@ref) and +Use [`Utilities.supports_incremental_interface`](@ref) and [`Utilities.supports_allocate_load`](@ref) to automatically choose between [`Utilities.default_copy_to`](@ref) or [`Utilities.allocate_load`](@ref) to apply the copy operation. @@ -20,7 +20,7 @@ function automatic_copy_to( copy_names::Bool = true, filter_constraints::Union{Nothing,Function} = nothing, ) - if supports_default_copy_to(dest, copy_names) + if MOI.supports_incremental_interface(dest, copy_names) default_copy_to(dest, src, copy_names, filter_constraints) elseif supports_allocate_load(dest, copy_names) allocate_load(dest, src, copy_names, filter_constraints) @@ -33,47 +33,7 @@ function automatic_copy_to( end end -""" - supports_default_copy_to(model::ModelLike, copy_names::Bool) - -Return a `Bool` indicating whether the model `model` supports -[`default_copy_to(model, src, copy_names=copy_names)`](@ref) if all the -attributes set to `src` and constraints added to `src` are supported by `model`. - -This function can be used to determine whether a model can be loaded into -`model` incrementally or whether it should be cached and copied at once instead. -This is used by JuMP to determine whether to add a cache or not in two -situations: -1. A first cache can be used to store the model as entered by the user as well - as the names of variables and constraints. This cache is created if this - function returns `false` when `copy_names` is `true`. -2. If bridges are used, then a second cache can be used to store the bridged - model with unnamed variables and constraints. This cache is created if this - function returns `false` when `copy_names` is `false`. - -## Examples - -If [`MathOptInterface.set`](@ref), [`MathOptInterface.add_variable`](@ref) and -[`MathOptInterface.add_constraint`](@ref) are implemented for a model of type -`MyModel` and names are supported, then [`MathOptInterface.copy_to`](@ref) can -be implemented as -```julia -MOI.Utilities.supports_default_copy_to(model::MyModel, copy_names::Bool) = true -function MOI.copy_to(dest::MyModel, src::MOI.ModelLike; kws...) - return MOI.Utilities.automatic_copy_to(dest, src; kws...) -end -``` -The [`Utilities.automatic_copy_to`](@ref) function automatically redirects to -[`Utilities.default_copy_to`](@ref). - -If names are not supported, simply change the first line by -```julia -MOI.supports_default_copy_to(model::MyModel, copy_names::Bool) = !copy_names -``` -The [`Utilities.default_copy_to`](@ref) function automatically throws an helpful -error in case `copy_to` is called with `copy_names` equal to `true`. -""" -supports_default_copy_to(model::MOI.ModelLike, copy_names::Bool) = false +@deprecate supports_default_copy_to MOI.supports_incremental_interface """ _index_to_variable(i::Int) @@ -653,7 +613,7 @@ end Implements `MOI.copy_to(dest, src)` by adding the variables and then the constraints and attributes incrementally. The function -[`supports_default_copy_to`](@ref) can be used to check whether `dest` supports +[`supports_incremental_interface`](@ref) can be used to check whether `dest` supports the copying a model incrementally. If the `filter_constraints` arguments is given, only the constraints for which diff --git a/src/Utilities/mockoptimizer.jl b/src/Utilities/mockoptimizer.jl index 4596f21847..753e7b6d23 100644 --- a/src/Utilities/mockoptimizer.jl +++ b/src/Utilities/mockoptimizer.jl @@ -754,9 +754,9 @@ end function MOI.copy_to(mock::MockOptimizer, src::MOI.ModelLike; kws...) return automatic_copy_to(mock, src; kws...) end -function supports_default_copy_to(mock::MockOptimizer, copy_names::Bool) +function MOI.supports_incremental_interface(mock::MockOptimizer, copy_names::Bool) return !mock.needs_allocate_load && - supports_default_copy_to(mock.inner_model, copy_names) + MOI.supports_incremental_interface(mock.inner_model, copy_names) end # Allocate-Load Interface diff --git a/src/Utilities/model.jl b/src/Utilities/model.jl index f9c7aaa0dc..4168b1a04b 100644 --- a/src/Utilities/model.jl +++ b/src/Utilities/model.jl @@ -773,7 +773,7 @@ end function MOI.copy_to(dest::AbstractModel, src::MOI.ModelLike; kws...) return automatic_copy_to(dest, src; kws...) end -supports_default_copy_to(model::AbstractModel, copy_names::Bool) = true +MOI.supports_incremental_interface(::AbstractModel, ::Bool) = true # Allocate-Load Interface # Even if the model does not need it and use default_copy_to, it could be used diff --git a/src/Utilities/universalfallback.jl b/src/Utilities/universalfallback.jl index e23bfcf611..bbf261b26b 100644 --- a/src/Utilities/universalfallback.jl +++ b/src/Utilities/universalfallback.jl @@ -125,8 +125,8 @@ function MOI.copy_to(uf::UniversalFallback, src::MOI.ModelLike; kws...) return MOIU.automatic_copy_to(uf, src; kws...) end -function supports_default_copy_to(uf::UniversalFallback, copy_names::Bool) - return supports_default_copy_to(uf.model, copy_names) +function MOI.supports_incremental_interface(uf::UniversalFallback, copy_names::Bool) + return MOI.supports_incremental_interface(uf.model, copy_names) end # References diff --git a/src/instantiate.jl b/src/instantiate.jl index 11bd9dd2b8..9ec1ce1b9a 100644 --- a/src/instantiate.jl +++ b/src/instantiate.jl @@ -91,26 +91,26 @@ function _instantiate_and_check(optimizer_constructor::OptimizerWithAttributes) end """ - instantiate(optimizer_constructor, - with_bridge_type::Union{Nothing, Type}=nothing, - with_names::Bool=false) + instantiate( + optimizer_constructor, + with_bridge_type::Union{Nothing, Type} = nothing, + with_names::Bool = false, + ) -Creates an instance of optimizer either by calling -`optimizer_constructor.optimizer_constructor()` and setting the parameters in -`optimizer_constructor.params` if `optimizer_constructor` is a -[`OptimizerWithAttributes`](@ref) or by calling `optimizer_constructor()` -if `optimizer_constructor` is callable. +Creates an instance of optimizer by either: + * calling `optimizer_constructor.optimizer_constructor()` and setting the + parameters in `optimizer_constructor.params` if `optimizer_constructor` is a + [`OptimizerWithAttributes`](@ref) +* calling `optimizer_constructor()` if `optimizer_constructor` is callable. If `with_bridge_type` is not `nothing`, it enables all the bridges defined in -the MathOptInterface.Bridges submodule with coefficient type -`with_bridge_type`. +the MathOptInterface.Bridges submodule with coefficient type `with_bridge_type`. If the optimizer created by `optimizer_constructor` does not support loading the -problem incrementally or does not support names and `with_names` is `true` (see -[`Utilities.supports_default_copy_to`](@ref)) then a +problem incrementally (see [`supports_incremental_interface`](@ref)), or does +not support names and `with_names` is `true`, then a [`Utilities.CachingOptimizer`](@ref) is added to store a cache of the bridged -model. -Hence set `with_names` to `true` if names might be set. +model. Hence set `with_names` to `true` if names might be set. """ function instantiate( optimizer_constructor; @@ -121,7 +121,7 @@ function instantiate( if with_bridge_type === nothing return optimizer end - if !Utilities.supports_default_copy_to(optimizer, with_names) + if !supports_incremental_interface(optimizer, with_names) universal_fallback = Utilities.UniversalFallback(Utilities.Model{with_bridge_type}()) optimizer = Utilities.CachingOptimizer(universal_fallback, optimizer) diff --git a/test/Utilities/cachingoptimizer.jl b/test/Utilities/cachingoptimizer.jl index 977486f61e..4d523aa440 100644 --- a/test/Utilities/cachingoptimizer.jl +++ b/test/Utilities/cachingoptimizer.jl @@ -609,7 +609,7 @@ function MOI.add_constrained_variables( return MOI.add_constrained_variables(model.inner, set) end -MOI.Utilities.supports_default_copy_to(::NoFreeVariables, names::Bool) = !names +MOI.Utilities.supports_incremental_interface(::NoFreeVariables, names::Bool) = !names function MOI.copy_to(dest::NoFreeVariables, src::MOI.ModelLike; kwargs...) return MOI.Utilities.automatic_copy_to(dest, src; kwargs...) end diff --git a/test/Utilities/copy.jl b/test/Utilities/copy.jl index 4e45549330..eff39fd86e 100644 --- a/test/Utilities/copy.jl +++ b/test/Utilities/copy.jl @@ -38,8 +38,8 @@ end end end @testset "Default" begin - @test !MOIU.supports_default_copy_to(DummyModel(), false) - @test !MOIU.supports_default_copy_to(DummyModel(), true) + @test !MOI.supports_incremental_interface(DummyModel(), false) + @test !MOI.supports_incremental_interface(DummyModel(), true) model = MOIU.Model{Float64}() MOIT.failcopytestc(model) MOIT.failcopytestia(model) @@ -96,7 +96,7 @@ function MOI.empty!(model::ConstrainedVariablesModel) return empty!(model.added_constrained) end -function MOIU.supports_default_copy_to(model::ConstrainedVariablesModel, ::Bool) +function MOI.supports_incremental_interface(model::ConstrainedVariablesModel, ::Bool) return !model.allocate_load end function MOIU.supports_allocate_load(model::ConstrainedVariablesModel, ::Bool) @@ -226,7 +226,7 @@ function MOI.copy_to( return MOIU.automatic_copy_to(dest, src; kws...) end -function MOIU.supports_default_copy_to( +function MOI.supports_incremental_interface( model::AbstractConstrainedVariablesModel, ::Bool, ) @@ -581,7 +581,7 @@ function MOI.supports_constraint( return true end -MOIU.supports_default_copy_to(::BoundModel, ::Bool) = true +MOI.supports_incremental_interface(::BoundModel, ::Bool) = true function MOI.copy_to(dest::BoundModel, src::MOI.ModelLike; kws...) return MOIU.automatic_copy_to(dest, src; kws...) end From 8822f13be1f8823feaad509bc338237af683cbbf Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 30 Apr 2021 15:59:20 +1200 Subject: [PATCH 2/5] Straggling changes --- docs/src/reference/models.md | 1 + docs/src/submodules/Test/overview.md | 4 ++-- docs/src/submodules/Utilities/reference.md | 1 - src/Utilities/copy.jl | 2 +- test/Utilities/cachingoptimizer.jl | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/reference/models.md b/docs/src/reference/models.md index a8009726c2..4f1971b26f 100644 --- a/docs/src/reference/models.md +++ b/docs/src/reference/models.md @@ -28,6 +28,7 @@ is_empty empty! write_to_file read_from_file +supports_incremental_interface copy_to ``` diff --git a/docs/src/submodules/Test/overview.md b/docs/src/submodules/Test/overview.md index 81406431d4..545abb1f0b 100644 --- a/docs/src/submodules/Test/overview.md +++ b/docs/src/submodules/Test/overview.md @@ -62,9 +62,9 @@ function test_SolverName() end function test_supports_incremental_interface() - @test MOI.Utilities.supports_incremental_interface(OPTIMIZER, false) + @test MOI.supports_incremental_interface(OPTIMIZER, false) # Use `@test !...` if names are not supported - @test MOI.Utilities.supports_incremental_interface(OPTIMIZER, true) + @test MOI.supports_incremental_interface(OPTIMIZER, true) end function test_unittest() diff --git a/docs/src/submodules/Utilities/reference.md b/docs/src/submodules/Utilities/reference.md index f51ae504fc..4585ed1e62 100644 --- a/docs/src/submodules/Utilities/reference.md +++ b/docs/src/submodules/Utilities/reference.md @@ -52,7 +52,6 @@ Utilities.mode ```@docs Utilities.automatic_copy_to Utilities.default_copy_to -Utilities.supports_incremental_interface ``` ### [Allocate-Load API](@id allocate_load_api_ref) diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 5c047249e8..211a1bfa71 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -5,7 +5,7 @@ copy_names::Bool=true, filter_constraints::Union{Nothing, Function}=nothing) -Use [`Utilities.supports_incremental_interface`](@ref) and +Use [`MOI.supports_incremental_interface`](@ref) and [`Utilities.supports_allocate_load`](@ref) to automatically choose between [`Utilities.default_copy_to`](@ref) or [`Utilities.allocate_load`](@ref) to apply the copy operation. diff --git a/test/Utilities/cachingoptimizer.jl b/test/Utilities/cachingoptimizer.jl index 4d523aa440..3090ab0241 100644 --- a/test/Utilities/cachingoptimizer.jl +++ b/test/Utilities/cachingoptimizer.jl @@ -609,7 +609,7 @@ function MOI.add_constrained_variables( return MOI.add_constrained_variables(model.inner, set) end -MOI.Utilities.supports_incremental_interface(::NoFreeVariables, names::Bool) = !names +MOI.supports_incremental_interface(::NoFreeVariables, names::Bool) = !names function MOI.copy_to(dest::NoFreeVariables, src::MOI.ModelLike; kwargs...) return MOI.Utilities.automatic_copy_to(dest, src; kwargs...) end From 775dd2556ca38e854587a83aac641f234bc7e302 Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 30 Apr 2021 16:17:14 +1200 Subject: [PATCH 3/5] Fix formatting --- docs/src/manual/implementing.md | 2 +- src/Utilities/cachingoptimizer.jl | 5 ++++- src/Utilities/mockoptimizer.jl | 5 ++++- src/Utilities/universalfallback.jl | 5 ++++- test/Utilities/copy.jl | 5 ++++- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/src/manual/implementing.md b/docs/src/manual/implementing.md index dc8e7870b8..2cc5e00efc 100644 --- a/docs/src/manual/implementing.md +++ b/docs/src/manual/implementing.md @@ -468,7 +468,7 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike; kwargs...) return MOI.Utilities.automatic_copy_to(dest, src; kwargs...) end ``` -See [`MOI.supports_incremental_interface`](@ref) for more details on whether to +See [`supports_incremental_interface`](@ref) for more details on whether to implement the `true` or `!copy_names` version. ## [Names](@id implement_names) diff --git a/src/Utilities/cachingoptimizer.jl b/src/Utilities/cachingoptimizer.jl index 4eed7e34cf..24bdf77d61 100644 --- a/src/Utilities/cachingoptimizer.jl +++ b/src/Utilities/cachingoptimizer.jl @@ -224,7 +224,10 @@ function MOI.copy_to(m::CachingOptimizer, src::MOI.ModelLike; kws...) m.state == ATTACHED_OPTIMIZER && reset_optimizer(m) return MOI.copy_to(m.model_cache, src; kws...) end -function MOI.supports_incremental_interface(model::CachingOptimizer, copy_names::Bool) +function MOI.supports_incremental_interface( + model::CachingOptimizer, + copy_names::Bool, +) return MOI.supports_incremental_interface(model.model_cache, copy_names) end diff --git a/src/Utilities/mockoptimizer.jl b/src/Utilities/mockoptimizer.jl index 753e7b6d23..8f8c74a135 100644 --- a/src/Utilities/mockoptimizer.jl +++ b/src/Utilities/mockoptimizer.jl @@ -754,7 +754,10 @@ end function MOI.copy_to(mock::MockOptimizer, src::MOI.ModelLike; kws...) return automatic_copy_to(mock, src; kws...) end -function MOI.supports_incremental_interface(mock::MockOptimizer, copy_names::Bool) +function MOI.supports_incremental_interface( + mock::MockOptimizer, + copy_names::Bool, +) return !mock.needs_allocate_load && MOI.supports_incremental_interface(mock.inner_model, copy_names) end diff --git a/src/Utilities/universalfallback.jl b/src/Utilities/universalfallback.jl index bbf261b26b..28516ad28d 100644 --- a/src/Utilities/universalfallback.jl +++ b/src/Utilities/universalfallback.jl @@ -125,7 +125,10 @@ function MOI.copy_to(uf::UniversalFallback, src::MOI.ModelLike; kws...) return MOIU.automatic_copy_to(uf, src; kws...) end -function MOI.supports_incremental_interface(uf::UniversalFallback, copy_names::Bool) +function MOI.supports_incremental_interface( + uf::UniversalFallback, + copy_names::Bool, +) return MOI.supports_incremental_interface(uf.model, copy_names) end diff --git a/test/Utilities/copy.jl b/test/Utilities/copy.jl index eff39fd86e..3014a6868b 100644 --- a/test/Utilities/copy.jl +++ b/test/Utilities/copy.jl @@ -96,7 +96,10 @@ function MOI.empty!(model::ConstrainedVariablesModel) return empty!(model.added_constrained) end -function MOI.supports_incremental_interface(model::ConstrainedVariablesModel, ::Bool) +function MOI.supports_incremental_interface( + model::ConstrainedVariablesModel, + ::Bool, +) return !model.allocate_load end function MOIU.supports_allocate_load(model::ConstrainedVariablesModel, ::Bool) From 5b568aae379933e20e100de9ff7942feb60a6c7d Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 30 Apr 2021 17:26:05 +1200 Subject: [PATCH 4/5] Fix docs --- src/Utilities/copy.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 211a1bfa71..01b0b76562 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -5,7 +5,7 @@ copy_names::Bool=true, filter_constraints::Union{Nothing, Function}=nothing) -Use [`MOI.supports_incremental_interface`](@ref) and +Use [`MathOptInterface.supports_incremental_interface`](@ref) and [`Utilities.supports_allocate_load`](@ref) to automatically choose between [`Utilities.default_copy_to`](@ref) or [`Utilities.allocate_load`](@ref) to apply the copy operation. @@ -613,8 +613,8 @@ end Implements `MOI.copy_to(dest, src)` by adding the variables and then the constraints and attributes incrementally. The function -[`supports_incremental_interface`](@ref) can be used to check whether `dest` supports -the copying a model incrementally. +[`MathOptInterface.supports_incremental_interface`](@ref) can be used to check +whether `dest` supports the copying a model incrementally. If the `filter_constraints` arguments is given, only the constraints for which this function returns `true` will be copied. This function is given a From 0e5a1ed27af19239731d5f45a91442dd234b220a Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Wed, 5 May 2021 07:31:38 +1200 Subject: [PATCH 5/5] Update MathOptInterface.jl --- src/MathOptInterface.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/MathOptInterface.jl b/src/MathOptInterface.jl index 137ecbabd5..60d10ec281 100644 --- a/src/MathOptInterface.jl +++ b/src/MathOptInterface.jl @@ -112,8 +112,7 @@ The main purpose of this function is to determine whether a model can be loaded into `model` incrementally or whether it should be cached and copied at once instead. -This is used by [`instantiate`](@ref) to determine whether to add a cache in two -situations: +This is used in two places to determine whether to add a cache: 1. A first cache can be used to store the model as entered by the user as well as the names of variables and constraints. This cache is created if this function returns `false` when `copy_names` is `true`.