Multithreading unstable with JuMP

I have tested your suggestion of making the variable assignment inside the loop local. On another model with actual data this gives incorrect results. If a race condition arises then use of local may be not be a good idea. It may have worked for your specific case, but in the MWE above it is mixing up something.

Locks can be used in a race condition, but this tend to slowdown the program. If possible, I would prefer to code it in a way that race condition is avoided. I also got into problem with my workaround code above when I tried to use it on another problem.

This is my code for the MWE that works well and avoids race condition. I believe this is exactly what @odow suggested using.

using JuMP
using Clp
function generate_data()
    # Generate random data
    InitialValue= float(rand(80:140,1,5))
    FutureValue = float(rand(40:150,100,5))
    Demand = float(rand(40:50,100))
    nscen = size(FutureValue,1)
    nproducts = size(FutureValue,2)
    prob = 1/nscen*ones(nscen)
    Loss = zeros(Float64,nscen,nproducts)
    Loss = -FutureValue.+InitialValue
    return FutureValue, Loss, Demand,nproducts, prob, nscen
end

function build_model(FutureValue,Loss,Demand,nproducts,prob,nscen,α)
    model = Model(Clp.Optimizer)
    set_optimizer_attribute(model, MOI.Silent(), true)
    @variable(model,x[b=1:nproducts]>=0)
    @variable(model,y[b=1:nscen]>=0)
    @variable(model,γ>=0)
    @constraint(model,budget,sum(x[i] for i =1:nproducts) == 1)
    @constraint(model,constraint2[j in 1:nscen], y[j]-sum(Loss[j,i]*x[i] for i in 1:nproducts) + γ >= 0)
    @constraint(model,constraint3[j in 1:nscen], sum(FutureValue[j,i]*x[i] for i in 1:nproducts)-Demand[j] >= 0)
    @objective(model,Min,γ+1/(α)*sum(y[j]*prob[j] for j =1:nscen))
    optimize!(model)
    γ_result = JuMP.value.(γ)
    Objective_result = objective_value(model)
    DecisionVariable_result = JuMP.value.(x)
    return γ_result, Objective_result, DecisionVariable_result
end

function run_modelthreading(;n=10,α=0.05)
    FutureValue, Loss, Demand,nproducts, prob, nscen = generate_data()
    γ_result, Objective_result, DecisionVariable_result = build_model(FutureValue,Loss,Demand,nproducts,prob,nscen,α)
    Limit = Objective_result
    VaR = Vector{Float64}(undef,n)
    CVaR = Vector{Float64}(undef,n)
    Product = Array{Float64,2}(undef, nproducts,n)
    Threads.@threads for i in 1:n
        α = (n-(i-1))/Limit
        γ_result, Objective_result, DecisionVariable_result = 
        build_model(FutureValue,Loss,Demand,nproducts,prob,nscen,α)
        VaR[i] = γ_result
        CVaR[i] = Objective_result
        Product[:,i] = DecisionVariable_result
    end
    return VaR, CVaR, Product
end

run_modelthreading(;n=10,α=0.05)

1 Like