# Creating efficient MOI wrapper for different cones and ordering them by types

**URL:** https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [June 19, 2025, 3:41pm UTC](https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031 "2025-06-19T15:41:05Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![yuwenchen95](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuwenchen95/32/38718_2.png) [@yuwenchen95](https://discourse.julialang.org/u/yuwenchen95)
#### Post date: [June 19, 2025, 3:41pm UTC](https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031/1 "2025-06-19T15:41:05Z")

</div>

I’m considering to create a MOI wrapper for [CuClarabel](https://github.com/cvxgrp/CuClarabel/tree/main), where users can input different types of cones in arbitrary order while the MOI wrapper is able to order them in a predefined order and then pass it to CuClarabel. The current implementation is quite inefficient as I have to loop over different types, [see here](https://github.com/cvxgrp/CuClarabel/blob/be4f23c5867b29b36ba3c5686f1249de61351c29/src/MOI_wrapper/MOI_wrapper.jl#L424-L508). Is there any efficient way to do it?

---

<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: [June 20, 2025, 8:10am UTC](https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031/2 "2025-06-20T08:10:08Z")

</div>

Yes, this is one common problem with the design of MOI.

The quick answer is that there is no efficient type stable way.

A better answer is that you can use a function barrier, so that iterating over the constraint types is unstable, but iterating over the list of constraints within a particular constraint type _is_ stable.

See, e.g.,

> <https://github.com/jump-dev/HiGHS.jl/blob/dbc50d7e377b039c4d258da4eaf4e83753ae7801/src/MOI_wrapper.jl#L3045-L3053>

---

<div class="post-metadata">

### Author: ![yuwenchen95](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuwenchen95/32/38718_2.png) [@yuwenchen95](https://discourse.julialang.org/u/yuwenchen95)
#### Post date: [June 30, 2025, 9:25am UTC](https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031/3 "2025-06-30T09:25:50Z")

</div>

Thanks! I tried to modified it accoring to it but found another issue for the current MOI wrapper of Clarabel. Even for the following simple example,

```julia
using JuMP
using Clarabel  

model = Model(Clarabel.Optimizer)
@variable(model, x[1:3])

@constraint(model, x[1:2] >= 0)
@constraint(model, sum(x) == 3.0)

@objective(model, Min, x[1])

optimize!(model)

```

After creating an `CachingOptimizer` object and calling `optimize!(model)`, I found [this function](https://github.com/jump-dev/MathOptInterface.jl/blob/f68a7a0bf38ce08628b8022db05097c94d2a5414/src/MathOptInterface.jl#L119-L124) is executed twice, where it went into the default `copy_to!()` at [here](https://github.com/jump-dev/MathOptInterface.jl/blob/f68a7a0bf38ce08628b8022db05097c94d2a5414/src/Bridges/bridge_optimizer.jl#L443) and then executed `copy_to!()` [defined in Clarabel](https://github.com/oxfordcontrol/Clarabel.jl/blob/73592f41310487f764a673e0c42097b29b6186e8/src/MOI_wrapper/MOI_wrapper.jl#L362).

The issue may come from the initialization for the `CachingOptimizer.optimizer` for Clarabel is of the type `MOIB.LazyBridgeOptimizer{MOIU.CachingOptimizer{Clarabel.MOIwrapper.Optimizer{Float64}, MOIU.UniversalFallback{MOIU.Model{Float64}}}}` while other solvers like `HiGHS` creating `MOIB.LazyBridgeOptimizer{HiGHS.Optimizer}`. It seems that there is one redudant layer `MOIU.CachingOptimizer` making an additional calling. Why don’t `Clarabel` creates an object like `MOIB.LazyBridgeOptimizer{Clarabel.MOIwrapper.Optimizer}`?

---

<div class="post-metadata">

### Author: ![pgoulart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pgoulart/32/17514_2.png) [@pgoulart](https://discourse.julialang.org/u/pgoulart)
#### Post date: [July 4, 2025, 10:54am UTC](https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031/4 "2025-07-04T10:54:41Z")

</div>

Something similar (I think) already happens elsewhere in the solver, specifically [here](https://github.com/oxfordcontrol/Clarabel.jl/blob/main/src/cones/cone_dispatch.jl).

The idea is to write a macro that gets all concrete subtypes of some abstract type, then unroll a big if/else switchyard calling appropriate functions on those types. That turned out to be quite a bit faster than relying on dynamic dispatch.

---

<div class="post-metadata">

### Author: ![yuwenchen95](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuwenchen95/32/38718_2.png) [@yuwenchen95](https://discourse.julialang.org/u/yuwenchen95)
#### Post date: [January 5, 2026, 4:19pm UTC](https://discourse.julialang.org/t/creating-efficient-moi-wrapper-for-different-cones-and-ordering-them-by-types/130031/5 "2026-01-05T16:19:12Z")

</div>

Following [Zaphod.jl](https://github.com/blegat/Zaphod.jl/blob/main/src/MOI_wrapper.jl) and [SCS.jl](https://github.com/jump-dev/SCS.jl/blob/master/src/MOI_wrapper/MOI_wrapper.jl), I update the MOI wrapper for [CuClarabel](https://github.com/oxfordcontrol/Clarabel.jl/tree/CuClarabel) by the use of `VectorAffineFunction`, which is more suitable for the large-scale optimization problems. See [here](https://github.com/oxfordcontrol/Clarabel.jl/commit/7da8611d404469e46c522c5e611c35d2f04340c5).
