# LazyBridgeOptimizer not working with copy\_to

**URL:** <https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [December 2, 2024, 5:22pm UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366 "2024-12-02T17:22:47Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![thibault-vignon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thibault-vignon/32/213894_2.png) [@thibault-vignon](https://discourse.julialang.org/u/thibault-vignon)\
**Post date:** [December 2, 2024, 5:22pm UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/1 "2024-12-02T17:22:48Z")

</div>

Hi, I’m writing a script in order to convert files from CBF to NL format. See example below:

```
src = MOI.FileFormats.Model(format = MOI.FileFormats.FORMAT_CBF);
MOI.read_from_file(src, "path_to_file");
dest = MOI.FileFormats.Model(format = MOI.FileFormats.FORMAT_NL);
bridged = MOI.Bridges.full_bridge_optimizer(dest, Float64);
MOI.copy_to(bridged, src);
MOI.write_to_file(dest, replace("path_to_file", ".cbf.gz" => ".nl"))

```

I had to add the bridge due to there being constraints in the CBF files which were not accepted in NL format.  
However, I now get the error: “LoadError: Model MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.FileFormats.NL.Model} does not support copy\_to.”

Does anyone have an idea of a workaround ?

Huge thanks in advance !

---

<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:** [December 2, 2024, 8:18pm UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/2 "2024-12-02T20:18:33Z")

</div>

Hi @thibault-vignon, welcome to the forum 😄

The easiest approach is to use JuMP’s `read_from_file` and `write_to_file`. It will automate the bridging for you.

```julia
using JuMP
model = Model()
@variable(model, x >= 0)
write_to_file(model, "out.cbf")

function transform_file_format_jump(filename; from, to)
    model = read_from_file(filename)
    output_filename = replace(filename, from => to)
    write_to_file(model, output_filename)
    return output_filename
end
transform_file_format_jump("out.cbf"; from = ".cbf", to = ".nl")

```

But if you really want to use MOI, you need:

```julia
function transform_file_format_moi(filename; from, to)
    src = MOI.FileFormats.Model(; filename)
    MOI.read_from_file(src, filename)
    output_filename = replace(filename, from => to)
    inner = MOI.FileFormats.Model(; filename = output_filename)
    dest = MOI.instantiate(() -> inner; with_bridge_type = Float64)
    MOI.copy_to(dest, src)
    MOI.write_to_file(inner, output_filename)
    return output_filename
end
transform_file_format_moi("out.cbf"; from = ".cbf", to = ".nl")

```

Note that there’s little point in rewriting CBF to NL, because JuMP does not reformulate conic constraints into their scalar nonlinear equivalents. You’ll get an error like:

```Julia
julia> using JuMP

julia> begin
           model = Model()
           @variable(model, x[1:3])
           @constraint(model, x in MOI.ExponentialCone())
           write_to_file(model, "out.cbf")
           transform_file_format_jump("out.cbf"; from = ".cbf", to = ".nl")
       end
ERROR: Unable to write problem to file because the chosen file format doesn't support constraints of the type MathOptInterface.VectorOfVariables-in-MathOptInterface.ExponentialCone.

```

---

<div class="post-metadata">

**Author:** ![thibault-vignon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thibault-vignon/32/213894_2.png) [@thibault-vignon](https://discourse.julialang.org/u/thibault-vignon)\
**Post date:** [December 3, 2024, 7:55am UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/3 "2024-12-03T07:55:20Z")

</div>

Thanks for the answer @odow !  
I was clearly barking up the wrong tree, as reformulating the conic constraints into their scalar nonlinear equivalents was exactly what I was hoping to use JuMP for.  
Might you perhaps know of an other way (not necessarily in Julia) to do this ?

---

<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:** [December 3, 2024, 8:03am UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/4 "2024-12-03T08:03:00Z")

</div>

What cones do you want? We could add this to JuMP

---

<div class="post-metadata">

**Author:** ![thibault-vignon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thibault-vignon/32/213894_2.png) [@thibault-vignon](https://discourse.julialang.org/u/thibault-vignon)\
**Post date:** [December 4, 2024, 5:52pm UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/5 "2024-12-04T17:52:20Z")

</div>

I’m trying to do this for the entire CBLIB benchmark, which I admit is potentially a lot of different kind of cones. You pointed out that exponential cones aren’t yet handled by JuMP, but when I tried your first suggestion I actually got errors indicating that it wasn’t able to handle constraints involving rotated second-order cones. This suprised me, because looking at the list of bridges in the docs I saw several meant to handle precisely rotated second-order cones ?

---

<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:** [December 4, 2024, 6:35pm UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/6 "2024-12-04T18:35:40Z")

</div>

Some bridges are not added by default. You’d need:

```julia
using JuMP
model = Model()
@variable(model, x[1:3])
@constraint(model, x in RotatedSecondOrderCone())
write_to_file(model, "out.cbf")

function transform_file_format_moi(filename; from, to)
    src = MOI.FileFormats.Model(; filename)
    MOI.read_from_file(src, filename)
    output_filename = replace(filename, from => to)
    inner = MOI.FileFormats.Model(; filename = output_filename)
    dest = MOI.instantiate(() -> inner; with_bridge_type = Float64)
    MOI.Bridges.add_bridge(
        dest,
        MOI.Bridges.Constraint.SOCtoNonConvexQuadBridge{Float64},
    )
    MOI.copy_to(dest, src)
    MOI.write_to_file(inner, output_filename)
    return output_filename
end
transform_file_format_moi("out.cbf"; from = ".cbf", to = ".nl")

```

How do you expect `PSDCone` to be written to `.nl` files?

---

<div class="post-metadata">

**Author:** ![thibault-vignon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thibault-vignon/32/213894_2.png) [@thibault-vignon](https://discourse.julialang.org/u/thibault-vignon)\
**Post date:** [December 6, 2024, 9:17am UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/7 "2024-12-06T09:17:26Z")

</div>

Using the above code snippet results in the .nl file for an empty problem (1 objective but no variables or constraints), whichever cbf file I feed into it.

To answer your question on PSD cones, I’m by no means an expert in conic optimization, but I’d naturally want to rewrite a PSD cone variable as M.transpose multiplied by M, where M is a general square matrix variable.

---

<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:** [December 8, 2024, 10:34pm UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/8 "2024-12-08T22:34:17Z")

</div>

I guess you need:

```julia
julia> function transform_file_format_moi(filename; from, to)
           src = MOI.FileFormats.Model(; filename)
           MOI.read_from_file(src, filename)
           output_filename = replace(filename, from => to)
           inner = MOI.FileFormats.Model(; filename = output_filename)
           dest = MOI.instantiate(() -> inner; with_bridge_type = Float64)
           MOI.Bridges.add_bridge(
               dest,
               MOI.Bridges.Constraint.SOCtoNonConvexQuadBridge{Float64},
           )
           MOI.copy_to(dest, src)
           MOI.Utilities.attach_optimizer(dest.model) # <-- new
           MOI.write_to_file(inner, output_filename)
           return output_filename
       end

```

What’s the motivation to rewrite CBLIB. into nonlinear? Typically, people have taken nonlinear models and reformulated then into CBF. Going the other way naively isn’t obviously better, and we can’t easily recover structure that may have been present in the original model.

For example, if the original model had `log(sum(exp.(x)))`, that’s a neat and tidy NLP expression that we can handle. But the conic reformulation introduces a bunch of extra variables and constraints. Going to that NLP formulation might be worse, but that doesn’t imply much.

---

<div class="post-metadata">

**Author:** ![thibault-vignon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thibault-vignon/32/213894_2.png) [@thibault-vignon](https://discourse.julialang.org/u/thibault-vignon)\
**Post date:** [December 10, 2024, 9:56am UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/9 "2024-12-10T09:56:28Z")

</div>

I’m attempting to benchmark a general non-linear solver which is suited to SOCP problems but not specialized for them, and which doesn’t accept CBF as an input format.  
By adding the ‘attach\_optimizer’ call I was finally able to convert some instances to NL format, thanks for that I wouldn’t have been able to find that trick on my own. It ended up failing on an instance due to a PSD cone constraint, which you had foreseen. I see that you’ve already added a new bridge for exponential cones, are PSD cones on the menu soon ? Thanks for being so reactive !

---

<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:** [December 11, 2024, 7:52am UTC](https://discourse.julialang.org/t/lazybridgeoptimizer-not-working-with-copy-to/123366/10 "2024-12-11T07:52:39Z")

</div>

> are PSD cones on the menu soon

I don’t think so. But we have our monthly developer call on Thursday 2:30pm Eastern that I will discuss this at. (DM me if you want an invite)
