diff --git a/docs/src/reference/models.md b/docs/src/reference/models.md index 7ce0ea36a8..d75f1325f5 100644 --- a/docs/src/reference/models.md +++ b/docs/src/reference/models.md @@ -60,6 +60,7 @@ AbstractOptimizer OptimizerWithAttributes optimize! instantiate +default_cache ``` ## Optimizer attributes diff --git a/src/Utilities/cachingoptimizer.jl b/src/Utilities/cachingoptimizer.jl index f05bba295f..e95528990e 100644 --- a/src/Utilities/cachingoptimizer.jl +++ b/src/Utilities/cachingoptimizer.jl @@ -203,6 +203,7 @@ errors can be thrown. """ function attach_optimizer(model::CachingOptimizer) @assert model.state == EMPTY_OPTIMIZER + final_touch(model, nothing) indexmap = MOI.copy_to(model.optimizer, model.model_cache)::IndexMap model.state = ATTACHED_OPTIMIZER model.model_to_optimizer_map = indexmap diff --git a/src/instantiate.jl b/src/instantiate.jl index 144ade0e30..7f72f0fb2c 100644 --- a/src/instantiate.jl +++ b/src/instantiate.jl @@ -121,9 +121,22 @@ function instantiate( return optimizer end if !supports_incremental_interface(optimizer) - universal_fallback = - Utilities.UniversalFallback(Utilities.Model{with_bridge_type}()) - optimizer = Utilities.CachingOptimizer(universal_fallback, optimizer) + cache = default_cache(optimizer, with_bridge_type) + optimizer = Utilities.CachingOptimizer(cache, optimizer) end return Bridges.full_bridge_optimizer(optimizer, with_bridge_type) end + +""" + default_cache(optimizer::ModelLike, ::Type{T}) where {T} + +Return a new instance of the default model type to be used as cache for +`optimizer` in a [`Utilities.CachingOptimizer`](@ref) for holding constraints +of coefficient type `T`. By default, this returns +`Utilities.UniversalFallback(Utilities.Model{T}())`. If copying from a instance +of a given model type is faster for `optimizer` then a new method returning +an instance of this model type should be defined. +""" +function default_cache(::ModelLike, ::Type{T}) where {T} + return Utilities.UniversalFallback(Utilities.Model{T}()) +end diff --git a/test/instantiate.jl b/test/instantiate.jl index a6258f92a5..0bf9c81b9b 100644 --- a/test/instantiate.jl +++ b/test/instantiate.jl @@ -6,6 +6,9 @@ const MOI = MathOptInterface struct DummyOptimizer <: MOI.AbstractOptimizer end MOI.is_empty(::DummyOptimizer) = true +function MOI.default_cache(::DummyOptimizer, ::Type{T}) where {T} + return MOI.Utilities.Model{T}() +end function _test_instantiate(T) function f() @@ -37,12 +40,8 @@ function _test_instantiate(T) @test optimizer isa DummyOptimizer optimizer = MOI.instantiate(optimizer_constructor, with_bridge_type = T) @test optimizer isa MOI.Bridges.LazyBridgeOptimizer{ - MOI.Utilities.CachingOptimizer{ - DummyOptimizer, - MOI.Utilities.UniversalFallback{MOI.Utilities.Model{T}}, - }, + MOI.Utilities.CachingOptimizer{DummyOptimizer,MOI.Utilities.Model{T}}, } - err = ErrorException( "The provided `optimizer_constructor` returned a non-empty optimizer.", )