# Help understanding MOI bridges, Even Proof-of-concept doesn't work

**URL:** <https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152>\
**Category:** Optimization (Mathematical)\
**Created:** [July 16, 2020, 12:41am UTC](https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152 "2020-07-16T00:41:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![votroto](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/votroto/32/224436_2.png) [@votroto](https://discourse.julialang.org/u/votroto)\
**Post date:** [July 16, 2020, 12:41am UTC](https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152/1 "2020-07-16T00:41:38Z")

</div>

Hi, I’ve been playing around with MOI bridges, but I can’t get even the simplest thing to work.  
Let’s imagine I want to create a bridge that simply ignores any PSD constraints:

```julia
module MWE
using MathOptInterface
const MOI = MathOptInterface

struct RemovePSDBridge <: MOI.Bridges.Constraint.AbstractBridge end

function MOI.supports_constraint(::Type{<:RemovePSDBridge},
	::Type{<:MOI.AbstractVectorFunction},
	::Type{<:MOI.PositiveSemidefiniteConeTriangle})
	return true
end

function MOI.Bridges.added_constrained_variable_types(::Type{<:RemovePSDBridge}) 
	Tuple{DataType}[]
end
function MOI.Bridges.added_constraint_types(::Type{<:RemovePSDBridge})
	[]
end

function bridge_constraint(::Type{RemovePSDBridge}, model::MOI.ModelLike, f::MOI.AbstractVectorFunction, s::MathOptInterface.PositiveSemidefiniteConeTriangle)
end
end

```

Then the obvious proof of concept is whether an LP solver accepts it:

```julia

using JuMP
using Clp
using MWE

m = Model(Clp.Optimizer)
MOI.Bridges.add_bridge(m.moi_backend.optimizer, MWE.RemovePSDBridge)

@variable m x[1:3]
@objective m Min x[1]
@constraint(m,[x[1] x[2];x[2] x[3]] in JuMP.PSDCone())

optimize!(m)

```

But it does not work. What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 16, 2020, 1:31am UTC](https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152/2 "2020-07-16T01:31:40Z")

</div>

You’re close, but you need something like

```nohighlight
struct RemovePSDBridge{T} <: MOI.Bridges.Constraint.AbstractBridge 
end

function MOI.Bridges.Constraint.concrete_bridge_type(
    ::Type{<:RemovePSDBridge}, 
    F::Type{<:MOI.AbstractVectorFunction},
    S::Type{<:MOI.PositiveSemidefiniteConeTriangle},
)
    return RemovePSDBridge{Float64}
end

function MOI.supports_constraint(
    ::Type{<:RemovePSDBridge},
	::Type{<:MOI.AbstractVectorFunction},
	::Type{<:MOI.PositiveSemidefiniteConeTriangle},
)
	return true
end

function MOI.Bridges.added_constrained_variable_types(::Type{<:RemovePSDBridge}) 
	return Tuple{DataType}[]
end

function MOI.Bridges.added_constraint_types(::Type{<:RemovePSDBridge})
	return []
end

function MOI.Bridges.Constraint.bridge_constraint(
    ::Type{<:RemovePSDBridge}, 
    ::MOI.ModelLike, 
    f::MOI.AbstractVectorFunction, 
    s::MOI.PositiveSemidefiniteConeTriangle,
)
    return RemovePSDBridge{Float64}()
end

# Wrap the optimizer in a single bridge optimizer
opt = () -> MOI.Bridges.Constraint.SingleBridgeOptimizer{RemovePSDBridge{Float64}}(
    # Clp doesn't support incremental modification, so we need to wrap it in a cache
    MOI.Utilities.CachingOptimizer(
        MOI.Utilities.Model{Float64}(),
        Clp.Optimizer()
    )
)
m = Model(opt)
@variable m x[1:3]
@objective m Min x[1]
@constraint(m,[x[1] x[2];x[2] x[3]] in JuMP.PSDCone())
optimize!(m)

```

If you’re interested in understanding the bridging system, I suggest you read: [MathOptInterface: a data structure for mathematical optimization problems – Optimization Online](http://www.optimization-online.org/DB_HTML/2020/02/7609.html)

Implementing this is definitely nontrivial and not well documented, short of following examples.

@rtwalker did a great job implementing a bridge recently: [https://github.com/jump-dev/MathOptInterface.jl/pull/1099](https://github.com/jump-dev/MathOptInterface.jl/pull/1099). Reading through the comments is probably a good way to learn the thought process.

---

<div class="post-metadata">

**Author:** ![votroto](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/votroto/32/224436_2.png) [@votroto](https://discourse.julialang.org/u/votroto)\
**Post date:** [July 16, 2020, 11:30am UTC](https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152/3 "2020-07-16T11:30:27Z")

</div>

Thanks.  
Additional question: instead of creating the model/bridge/cache/model/solver hierarchy, would this do the same?

```julia
	m = SOSModel(Clp.Optimizer)
	JuMP.add_bridge(m, RemovePSDBridge)

```

BTW: Is it possible / worthwhile adding such external resources to the MOI wiki? With the wiki as is, MOI is fairly impenetrable.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 16, 2020, 1:52pm UTC](https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152/4 "2020-07-16T13:52:26Z")

</div>

Woah! I forgot we had `add_bridge`! Yes, you can go

```Julia
m = Model(Clp.Optimizer)
add_bridge(m, RemovePSDBridge)
@variable m x[1:3]
@objective m Min x[1]
@constraint(m,[x[1] x[2];x[2] x[3]] in JuMP.PSDCone())
optimize!(m)

```

Much simpler.

> creating the model/bridge/cache/model/solver hierarchy

You seem well on your way to understanding what is happening. It is pretty complicated…

> the wiki as is, MOI is fairly impenetrable.

Pull requests to improve the documentation (e.g., adding a link to the paper) would be great! We’ve focused on building functionality, and documentation has fallen behind, unfortunately.
