# Resolve models in parallel within a loop

**URL:** https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469
**Category:** Optimization (Mathematical)
**Created:** [July 18, 2018, 4:21pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469 "2018-07-18T16:21:08Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 18, 2018, 4:21pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/1 "2018-07-18T16:21:08Z")

</div>

Hi all, I am trying to implement an algorithm in JuMP. In each iteration, I will need to solve several models in parallel, update some data and then resolve these models in the next iteration with different objectives (constraints and variables are the same). What I am thinking is that I set up models without objectives beforehand, and then in each iteration I use pmap to set new objectives and resolve. I don’t want to rebuild models from scratch in each iteration. I am wondering is this doable and supported in JuMP? Thanks.

---

<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 18, 2018, 9:35pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/2 "2018-07-18T21:35:40Z")

</div>

> I am wondering is this doable and supported in JuMP?

There is nothing “in” JuMP that supports this. However, it does support changing the objective of a model and efficiently resolving the problem.

However, you can use Julia’s parallel features to parallelize the solves. It is worth having a read of some related posts as there are quite a few traps you can run into:  
[https://discourse.julialang.org/search?q=jump%20parallel](https://discourse.julialang.org/search?q=jump%20parallel)

Have a read, try some things out, and then come back if you run into problems.

---

<div class="post-metadata">

### Author: ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)
#### Post date: [July 18, 2018, 10:06pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/3 "2018-07-18T22:06:17Z")

</div>

It sounds pretty similar to what I used in [Juniper.jl](https://github.com/lanl-ansi/Juniper.jl)

[The function itself](https://github.com/lanl-ansi/Juniper.jl/blob/master/src/BnBTree.jl#L524-L629)

So you basically load the basis model to all processors and then use `remotecall_fetch` to call the processors with information like the new objective and get that back. All in a `pmap` function (`@sync, @async` loop 😉 )

Don’t hesitate to comment here if you need some more information.  
[More about the pmap function](https://docs.julialang.org/en/v0.6.0/manual/parallel-computing/#Scheduling-1)

---

<div class="post-metadata">

### Author: ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)
#### Post date: [July 19, 2018, 4:37pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/4 "2018-07-19T16:37:05Z")

</div>

One constraint to be aware of is that JuMP `Model` objects aren’t designed to support serialization. `pmap`ping over a list of models to solve generally won’t work, because that involves sending the model across processes. You should try to build a model locally once per process.

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 19, 2018, 5:46pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/5 "2018-07-19T17:46:07Z")

</div>

Thanks, I am looking into this!

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 19, 2018, 5:46pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/6 "2018-07-19T17:46:38Z")

</div>

Thanks! That’s helpful!

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 19, 2018, 5:48pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/7 "2018-07-19T17:48:37Z")

</div>

Thanks for the reply. Can you please specify how to

> [@miles.lubin](#):
>
> build a model locally once per process.

Say I have 3 models and 3 processes, can I do something like:

```julia
@everywhere using JuMP
@everywhere using Ipopt

function generateModel()
    mList = Array(JuMP.Model,3)
    for i in 1:3
        m = Model(solver = IpoptSolver(print_level = 0))
        @variable(m, x[1:2], lowerbound = -1, upperbound = 1)
        a = rand(2)
        @constraint(m, dot(a, x) == 0)
        mList[i] = m
    end
    return mList
end

@everywhere function solveModel(m::JuMP.Model)
    c = rand(2)
    @objective(m, Min, dot(c,m[:x]))
    s = solve(m)
    return getobjectivevalue(m)
end

mList = generateModel()

addprocs(2)

for i in 1:3
    rr = RemoteChannel(i)
    put!(rr, mList[i])
end

bList = Any[]

@time for k in 1:100
    b = Dict(i=>0.0 for i in 1:3)
    @sync begin
        for i in 1:3
            b[i] = solveModel(mList[i])
           
        end
    end
    push!(bList, b)
end

```

When I tried to put each model into a process, I had

```julia
LoadError: On worker 2:
UndefVarError: JuMP not defined

```

In addition, can this make sure in every iteration(1:100), the model i will be solved in process i? I am also a little confused about when to use @parallel after @sync.

Thank you!

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 19, 2018, 11:52pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/8 "2018-07-19T23:52:39Z")

</div>

Hi. Thank you for the reply. I am trying to workout a simple example:

```julia
addprocs(2)

@everywhere using JuMP
@everywhere using Ipopt

@everywhere function generateModel()
    m = Model(solver = IpoptSolver(print_level = 0))
    @variable(m, x[1:2], lowerbound = -1, upperbound = 1)
    a = rand(2)
    @constraint(m, dot(a,x) == 0)
    return m
end

@everywhere function solveModel(m::JuMP.Model)
    c = rand(2)
    @objective(m, Min, dot(c, m[:x]))
    solve(m)
    return getobjectivevalue(m)
end

mList = Array{JuMP.Model}(3)
@sync for i in 1:3
    mList[i] = remotecall_fetch(generateModel, i)
end

```

I think I am generating models in each process, and my first question is : am I generating models in a parallel way?

In addition, I am a little confused about the following different approaches to solve the model  
(a)

```julia
sol = Array{Float64}(3)
@time @sync for i in 1:3
    sol[i] = remotecall_fetch(solveModel,i,mList[i])
end

```

(b)

```julia
sol = Array{Float64}(3)
@time @sync @parallel for i in 1:3
    sol[i] = remotecall_fetch(solveModel,i,mList[i])
end

```

(c)

```julia
sol = Array{Float64}(3)
@time @sync for i in 1:3
    sol[i] = remote_do(solveModel,i,mList[i])
end

```

(d)

```julia
sol = pmap(solveModel, mList)

```

Anyone can help explain the difference of the four approaches? Thanks!

---

<div class="post-metadata">

### Author: ![Juser](https://avatars.discourse-cdn.com/v4/letter/j/34f0e0/32.png) [@Juser](https://discourse.julialang.org/u/Juser)
#### Post date: [July 20, 2018, 12:14am UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/9 "2018-07-20T00:14:36Z")

</div>

It looks like you’re adding procs after `using JuMP` and declaring functions. The procs you add are not able to use anything declared with @everywhere before the proc is added.

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 20, 2018, 12:16am UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/10 "2018-07-20T00:16:39Z")

</div>

Thanks for the reply. Yes you are right. I just realized that. I changed the code in the previous reply.

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 20, 2018, 12:20am UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/11 "2018-07-20T00:20:30Z")

</div>

Hi. Could you please explain what is happening in the while loop marked by the marco @async in the map function? Thanks

---

<div class="post-metadata">

### Author: ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)
#### Post date: [July 20, 2018, 7:44am UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/12 "2018-07-20T07:44:22Z")

</div>

You have basically the `@sync` loop over the processors and the `@async` loop over the tasks. At the beginning you get the new task (for you a new objective from a list) and break if the list is empty. This is all done by the master processor. Then use `remotecall_fetch` function to send the task to the processor. Do you need more information?

---

<div class="post-metadata">

### Author: ![Ksun46](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ksun46/32/9437_2.png) [@Ksun46](https://discourse.julialang.org/u/Ksun46)
#### Post date: [July 20, 2018, 2:38pm UTC](https://discourse.julialang.org/t/resolve-models-in-parallel-within-a-loop/12469/13 "2018-07-20T14:38:36Z")

</div>

I see. So assume I have equal number (n) of models and processes, and I want each process to take care of one model. Can I do something like

```julia
@sync for i in 1:n
    @async result[i] = remotecall_fetch(solveModel, i, modelList[i])
end

```

where `modelList` is an array of `n` JuMP models.

In addition, what I need is that in each iteration of my algorithm, I need to implement the above code (in parallel) to resolve n models. But each process will always handle the same model. Is it necessary to build and store each model in a process (say with the same id), or is it find to create all models in the main process (with id 1)?

Thanks.
