Skip to content

Commit f4e3d59

Browse files
committed
Update
1 parent 21c282e commit f4e3d59

File tree

4 files changed

+185
-77
lines changed

4 files changed

+185
-77
lines changed

src/Utilities/cachingoptimizer.jl

Lines changed: 35 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,8 @@ function MOI.add_variable(m::CachingOptimizer)
341341
vindex_optimizer =
342342
MOI.add_variable(m.optimizer)::MOI.VariableIndex
343343
catch err
344-
if err isa MOI.NotAllowedError
345-
reset_optimizer(m)
346-
else
347-
rethrow(err)
348-
end
344+
_rethrow_if_not_NotAllowedError(err)
345+
reset_optimizer(m)
349346
end
350347
else
351348
vindex_optimizer = MOI.add_variable(m.optimizer)::MOI.VariableIndex
@@ -366,11 +363,8 @@ function MOI.add_variables(m::CachingOptimizer, n)
366363
vindices_optimizer =
367364
MOI.add_variables(m.optimizer, n)::Vector{MOI.VariableIndex}
368365
catch err
369-
if err isa MOI.NotAllowedError
370-
reset_optimizer(m)
371-
else
372-
rethrow(err)
373-
end
366+
_rethrow_if_not_NotAllowedError(err)
367+
reset_optimizer(m)
374368
end
375369
else
376370
vindices_optimizer =
@@ -413,11 +407,8 @@ function MOI.add_constrained_variable(
413407
MOI.ConstraintIndex{MOI.VariableIndex,S},
414408
}
415409
catch err
416-
if err isa MOI.NotAllowedError
417-
reset_optimizer(m)
418-
else
419-
rethrow(err)
420-
end
410+
_rethrow_if_not_NotAllowedError(err)
411+
reset_optimizer(m)
421412
end
422413
else
423414
vindex_optimizer, cindex_optimizer = MOI.add_constrained_variable(
@@ -480,11 +471,8 @@ function MOI.add_constrained_variables(
480471
MOI.ConstraintIndex{MOI.VectorOfVariables,S},
481472
}
482473
catch err
483-
if err isa MOI.NotAllowedError
484-
reset_optimizer(m)
485-
else
486-
rethrow(err)
487-
end
474+
_rethrow_if_not_NotAllowedError(err)
475+
reset_optimizer(m)
488476
end
489477
else
490478
vindices_optimizer, cindex_optimizer =
@@ -534,14 +522,11 @@ function MOI.add_constraint(
534522
set,
535523
)::MOI.ConstraintIndex{F,S}
536524
catch err
537-
if err isa MOI.NotAllowedError
538-
# It could be MOI.AddConstraintNotAllowed{F', S'} with F' != F
539-
# or S' != S if, for example, the `F`-in-`S` constraint is bridged
540-
# to other constraints in `m.optimizer`
541-
reset_optimizer(m)
542-
else
543-
rethrow(err)
544-
end
525+
_rethrow_if_not_NotAllowedError(err)
526+
# It could be MOI.AddConstraintNotAllowed{F', S'} with F' != F
527+
# or S' != S if, for example, the `F`-in-`S` constraint is bridged
528+
# to other constraints in `m.optimizer`
529+
reset_optimizer(m)
545530
end
546531
else
547532
cindex_optimizer = MOI.add_constraint(
@@ -571,11 +556,8 @@ function MOI.modify(
571556
try
572557
MOI.modify(m.optimizer, cindex_optimizer, change_optimizer)
573558
catch err
574-
if err isa MOI.NotAllowedError
575-
reset_optimizer(m)
576-
else
577-
rethrow(err)
578-
end
559+
_rethrow_if_not_NotAllowedError(err)
560+
reset_optimizer(m)
579561
end
580562
else
581563
MOI.modify(m.optimizer, cindex_optimizer, change_optimizer)
@@ -607,11 +589,8 @@ function _replace_constraint_function_or_set(
607589
replacement_optimizer,
608590
)
609591
catch err
610-
if err isa MOI.NotAllowedError
611-
reset_optimizer(m)
612-
else
613-
rethrow(err)
614-
end
592+
_rethrow_if_not_NotAllowedError(err)
593+
reset_optimizer(m)
615594
end
616595
else
617596
MOI.set(
@@ -671,11 +650,8 @@ function MOI.modify(
671650
try
672651
MOI.modify(m.optimizer, obj, change_optimizer)
673652
catch err
674-
if err isa MOI.NotAllowedError
675-
reset_optimizer(m)
676-
else
677-
rethrow(err)
678-
end
653+
_rethrow_if_not_NotAllowedError(err)
654+
reset_optimizer(m)
679655
end
680656
else
681657
MOI.modify(m.optimizer, obj, change_optimizer)
@@ -700,11 +676,8 @@ function MOI.delete(m::CachingOptimizer, index::MOI.Index)
700676
try
701677
MOI.delete(m.optimizer, index_optimizer)
702678
catch err
703-
if err isa MOI.NotAllowedError
704-
reset_optimizer(m)
705-
else
706-
rethrow(err)
707-
end
679+
_rethrow_if_not_NotAllowedError(err)
680+
reset_optimizer(m)
708681
end
709682
else
710683
MOI.delete(m.optimizer, index_optimizer)
@@ -734,11 +707,8 @@ function MOI.delete(m::CachingOptimizer, indices::Vector{<:MOI.Index})
734707
try
735708
MOI.delete(m.optimizer, indices_optimizer)
736709
catch err
737-
if err isa MOI.NotAllowedError
738-
reset_optimizer(m)
739-
else
740-
rethrow(err)
741-
end
710+
_rethrow_if_not_NotAllowedError(err)
711+
reset_optimizer(m)
742712
end
743713
else
744714
MOI.delete(m.optimizer, indices_optimizer)
@@ -771,11 +741,8 @@ function MOI.set(m::CachingOptimizer, attr::MOI.AbstractModelAttribute, value)
771741
try
772742
MOI.set(m.optimizer, attr, optimizer_value)
773743
catch err
774-
if err isa MOI.NotAllowedError
775-
reset_optimizer(m)
776-
else
777-
rethrow(err)
778-
end
744+
_rethrow_if_not_NotAllowedError(err)
745+
reset_optimizer(m)
779746
end
780747
else
781748
MOI.set(m.optimizer, attr, optimizer_value)
@@ -798,11 +765,8 @@ function MOI.set(
798765
try
799766
MOI.set(m.optimizer, attr, optimizer_index, optimizer_value)
800767
catch err
801-
if err isa MOI.NotAllowedError
802-
reset_optimizer(m)
803-
else
804-
rethrow(err)
805-
end
768+
_rethrow_if_not_NotAllowedError(err)
769+
reset_optimizer(m)
806770
end
807771
else
808772
MOI.set(m.optimizer, attr, optimizer_index, optimizer_value)
@@ -831,13 +795,15 @@ function MOI.supports(
831795
(m.state == NO_OPTIMIZER || MOI.supports(m.optimizer, attr)::Bool)
832796
end
833797

798+
_rethrow_if_not_NotAllowedError(err) = rethrow(err)
799+
800+
_rethrow_if_not_NotAllowedError(::MOI.NotAllowedError) = nothing
801+
834802
function _get_model_attribute(model::CachingOptimizer, attr::MOI.ObjectiveValue)
835803
try
836804
return MOI.get(model.optimizer, attr)
837805
catch err
838-
if !(err isa MOI.GetAttributeNotAllowed)
839-
rethrow(err)
840-
end
806+
_rethrow_if_not_NotAllowedError(err)
841807
return get_fallback(model, attr)
842808
end
843809
end
@@ -849,9 +815,7 @@ function _get_model_attribute(
849815
try
850816
return MOI.get(model.optimizer, attr)
851817
catch err
852-
if !(err isa MOI.GetAttributeNotAllowed)
853-
rethrow(err)
854-
end
818+
_rethrow_if_not_NotAllowedError(err)
855819
MOI.check_result_index_bounds(model, attr)
856820
# We don't know what coefficient type to use, so just use whatever the
857821
# objective value type is. This is slightly inefficient, but it
@@ -996,10 +960,7 @@ function _get_fallback(
996960
model.model_to_optimizer_map[index],
997961
)
998962
catch err
999-
# Thrown if .optimizer doesn't support attr
1000-
if !(err isa MOI.GetAttributeNotAllowed)
1001-
rethrow(err)
1002-
end
963+
_rethrow_if_not_NotAllowedError(err)
1003964
return get_fallback(model, attr, index)
1004965
end
1005966
end
@@ -1016,10 +977,7 @@ function _get_fallback(
1016977
[model.model_to_optimizer_map[i] for i in indices],
1017978
)
1018979
catch err
1019-
# Thrown if .optimizer doesn't support attr
1020-
if !(err isa MOI.GetAttributeNotAllowed)
1021-
rethrow(err)
1022-
end
980+
_rethrow_if_not_NotAllowedError(err)
1023981
return [get_fallback(model, attr, i) for i in indices]
1024982
end
1025983
end

test/Utilities/cachingoptimizer.jl

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,95 @@ function test_get_AttributeFromModelCache()
13011301
return
13021302
end
13031303

1304+
function test_copy_to_attached()
1305+
cache = MOI.Utilities.Model{Float64}()
1306+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1307+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1308+
x = MOI.add_variable(model)
1309+
MOI.Utilities.attach_optimizer(model)
1310+
src = MOI.Utilities.Model{Float64}()
1311+
x = MOI.add_variable(src)
1312+
index_map = MOI.copy_to(model, src)
1313+
@test model.state == MOI.Utilities.EMPTY_OPTIMIZER
1314+
@test MOI.get(model.model_cache, MOI.NumberOfVariables()) == 1
1315+
return
1316+
end
1317+
1318+
function test_add_variable_not_allowed()
1319+
cache = MOI.Utilities.Model{Float64}()
1320+
optimizer = MOI.Utilities.MockOptimizer(
1321+
MOI.Utilities.Model{Float64}();
1322+
add_var_allowed = false,
1323+
)
1324+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1325+
MOI.Utilities.attach_optimizer(model)
1326+
@test model.state == MOI.Utilities.ATTACHED_OPTIMIZER
1327+
x = MOI.add_variable(model)
1328+
@test model.state == MOI.Utilities.EMPTY_OPTIMIZER
1329+
@test MOI.get(model.model_cache, MOI.NumberOfVariables()) == 1
1330+
return
1331+
end
1332+
1333+
function test_add_variables_not_allowed()
1334+
cache = MOI.Utilities.Model{Float64}()
1335+
optimizer = MOI.Utilities.MockOptimizer(
1336+
MOI.Utilities.Model{Float64}();
1337+
add_var_allowed = false,
1338+
)
1339+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1340+
MOI.Utilities.attach_optimizer(model)
1341+
@test model.state == MOI.Utilities.ATTACHED_OPTIMIZER
1342+
x = MOI.add_variables(model, 2)
1343+
@test model.state == MOI.Utilities.EMPTY_OPTIMIZER
1344+
@test MOI.get(model.model_cache, MOI.NumberOfVariables()) == 2
1345+
return
1346+
end
1347+
1348+
function test_add_constrained_variable_not_allowed()
1349+
cache = MOI.Utilities.Model{Float64}()
1350+
optimizer = MOI.Utilities.MockOptimizer(
1351+
MOI.Utilities.Model{Float64}();
1352+
add_var_allowed = false,
1353+
)
1354+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1355+
MOI.Utilities.attach_optimizer(model)
1356+
@test model.state == MOI.Utilities.ATTACHED_OPTIMIZER
1357+
x, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
1358+
@test model.state == MOI.Utilities.EMPTY_OPTIMIZER
1359+
@test MOI.get(model.model_cache, MOI.NumberOfVariables()) == 1
1360+
return
1361+
end
1362+
1363+
function test_add_constrained_variables_not_allowed()
1364+
cache = MOI.Utilities.Model{Float64}()
1365+
optimizer = MOI.Utilities.MockOptimizer(
1366+
MOI.Utilities.Model{Float64}();
1367+
add_var_allowed = false,
1368+
)
1369+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1370+
MOI.Utilities.attach_optimizer(model)
1371+
@test model.state == MOI.Utilities.ATTACHED_OPTIMIZER
1372+
x, _ = MOI.add_constrained_variables(model, MOI.Zeros(2))
1373+
@test model.state == MOI.Utilities.EMPTY_OPTIMIZER
1374+
@test MOI.get(model.model_cache, MOI.NumberOfVariables()) == 2
1375+
return
1376+
end
1377+
1378+
function test_delete_not_allowed()
1379+
cache = MOI.Utilities.Model{Float64}()
1380+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1381+
optimizer.delete_allowed = false
1382+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1383+
MOI.Utilities.attach_optimizer(model)
1384+
@test model.state == MOI.Utilities.ATTACHED_OPTIMIZER
1385+
x, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
1386+
@test model.state == MOI.Utilities.ATTACHED_OPTIMIZER
1387+
MOI.delete(model, [x])
1388+
@test model.state == MOI.Utilities.EMPTY_OPTIMIZER
1389+
@test MOI.get(model.model_cache, MOI.NumberOfVariables()) == 0
1390+
return
1391+
end
1392+
13041393
end # module
13051394

13061395
TestCachingOptimizer.runtests()

test/Utilities/functions.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,6 +2238,15 @@ function test_filter_variables_variable_index()
22382238
return
22392239
end
22402240

2241+
function test_filter_variables_vector_of_variables()
2242+
f = MOI.VectorOfVariables(MOI.VariableIndex.(1:2))
2243+
s = MOI.Zeros(2)
2244+
g, new_s = MOI.Utilities.filter_variables(x -> x.value != 1, f, s)
2245+
@test g == MOI.VectorOfVariables([MOI.VariableIndex(2)])
2246+
@test new_s == MOI.Zeros(1)
2247+
return
2248+
end
2249+
22412250
function test_mult_bool()
22422251
f = 1.0 * MOI.VariableIndex(1) + 2.0
22432252
@test *(f, false) zero(MOI.ScalarAffineFunction{Float64})

0 commit comments

Comments
 (0)