|
45 | 45 | MOIT.failcopytestia(model) |
46 | 46 | MOIT.failcopytestva(model) |
47 | 47 | MOIT.failcopytestca(model) |
48 | | - MOIT.copytest(model, MOIU.Model{Float64}()) |
| 48 | + MOIT.copytest(model, MOIU.Model{Float64}(), copy_names = false) |
| 49 | + MOIT.copytest(model, MOIU.Model{Float64}(), copy_names = true) |
49 | 50 | end |
50 | 51 | @testset "Allocate-Load" begin |
51 | 52 | @test !MOIU.supports_allocate_load(DummyModel(), false) |
|
55 | 56 | MOIT.failcopytestia(mock) |
56 | 57 | MOIT.failcopytestva(mock) |
57 | 58 | MOIT.failcopytestca(mock) |
58 | | - MOIT.copytest(mock, MOIU.Model{Float64}()) |
| 59 | + MOIT.copytest(mock, MOIU.Model{Float64}(), copy_names = false) |
| 60 | + MOIT.copytest(mock, MOIU.Model{Float64}(), copy_names = true) |
59 | 61 | end |
60 | 62 |
|
61 | 63 | struct DummyEvaluator <: MOI.AbstractNLPEvaluator end |
|
620 | 622 | MOI.NumberOfConstraints{MOI.SingleVariable,MOI.Integer}(), |
621 | 623 | ) == 0 |
622 | 624 | end |
| 625 | + |
| 626 | +# We create a `OnlyCopyConstraints` that don't implement `add_constraint` but |
| 627 | +# implements `pass_nonvariable_constraints` to check that this is passed accross |
| 628 | +# all layers without falling back to `pass_nonvariable_constraints_fallback` |
| 629 | +# which calls `add_constraint`. |
| 630 | + |
| 631 | +struct OnlyCopyConstraints{F,S} <: MOI.ModelLike |
| 632 | + constraints::MOIU.VectorOfConstraints{F,S} |
| 633 | + function OnlyCopyConstraints{F,S}() where {F,S} |
| 634 | + return new{F,S}(MOIU.VectorOfConstraints{F,S}()) |
| 635 | + end |
| 636 | +end |
| 637 | +MOI.empty!(model::OnlyCopyConstraints) = MOI.empty!(model.constraints) |
| 638 | +function MOI.supports_constraint( |
| 639 | + model::OnlyCopyConstraints, |
| 640 | + F::Type{<:MOI.AbstractFunction}, |
| 641 | + S::Type{<:MOI.AbstractSet}, |
| 642 | +) |
| 643 | + return MOI.supports_constraint(model.constraints, F, S) |
| 644 | +end |
| 645 | +function MOIU.pass_nonvariable_constraints( |
| 646 | + dest::OnlyCopyConstraints, |
| 647 | + src::MOI.ModelLike, |
| 648 | + idxmap::MOIU.IndexMap, |
| 649 | + constraint_types, |
| 650 | + pass_cons; |
| 651 | + filter_constraints::Union{Nothing,Function} = nothing, |
| 652 | +) |
| 653 | + return MOIU.pass_nonvariable_constraints( |
| 654 | + dest.constraints, |
| 655 | + src, |
| 656 | + idxmap, |
| 657 | + constraint_types, |
| 658 | + pass_cons; |
| 659 | + filter_constraints = filter_constraints, |
| 660 | + ) |
| 661 | +end |
| 662 | + |
| 663 | +function test_pass_copy(::Type{T}) where {T} |
| 664 | + F = MOI.ScalarAffineFunction{T} |
| 665 | + S = MOI.EqualTo{T} |
| 666 | + S2 = MOI.GreaterThan{T} |
| 667 | + src = MOIU.Model{T}() |
| 668 | + x = MOI.add_variable(src) |
| 669 | + fx = MOI.SingleVariable(x) |
| 670 | + MOI.add_constraint(src, T(1) * fx, MOI.EqualTo(T(1))) |
| 671 | + MOI.add_constraint(src, T(2) * fx, MOI.EqualTo(T(2))) |
| 672 | + MOI.add_constraint(src, T(3) * fx, MOI.GreaterThan(T(3))) |
| 673 | + MOI.add_constraint(src, T(4) * fx, MOI.GreaterThan(T(4))) |
| 674 | + dest = MOIU.CachingOptimizer( |
| 675 | + MOI.Bridges.full_bridge_optimizer( |
| 676 | + MOIU.UniversalFallback( |
| 677 | + MOIU.GenericOptimizer{T,OnlyCopyConstraints{F,S}}(), |
| 678 | + ), |
| 679 | + T, |
| 680 | + ), |
| 681 | + MOIU.AUTOMATIC, |
| 682 | + ) |
| 683 | + MOI.copy_to(dest, src) |
| 684 | + voc = dest.model_cache.model.model.constraints.constraints |
| 685 | + @test MOI.get(voc, MOI.NumberOfConstraints{F,S}()) == 2 |
| 686 | + @test !haskey(dest.model_cache.model.constraints, (F, S)) |
| 687 | + @test MOI.get(dest, MOI.NumberOfConstraints{F,S2}()) == 2 |
| 688 | + @test haskey(dest.model_cache.model.constraints, (F, S2)) |
| 689 | +end |
| 690 | + |
| 691 | +@testset "copy of constraints passed as copy accross layers" begin |
| 692 | + test_pass_copy(Int) |
| 693 | + test_pass_copy(Float64) |
| 694 | +end |
0 commit comments