I’m trying to create a number of JuMP models in parallel using pmap, and while the basic functionality of this is working fine, my implementation stores some variables and expressions in the ext field of the JuMP.Model. This works fine if building the models sequentially (single-threaded) using map(), or a for loop, but I’ve run into a problem when I use pmap().
Here’s a very simple example that demonstrates the issue:
using Distributed
if length(workers())==1
addprocs(1)
end
@everywhere using JuMP
@everywhere function model_builder(rhs)
m = JuMP.Model()
@variable(m,x>=0)
@objective(m,Min,x)
@constraint(m,x>=rhs)
m.ext[:variable]=x
m.ext[:expr]=2*x
m
end
# Single-threaded models
models=map(model_builder,1:10)
models[1][:x] in keys(models[1].ext[:expr].terms)
collect(keys(models[1].ext[:expr].terms))[1]==models[1][:x]
models[1].ext[:expr]+models[1].ext[:variable]
# Multi-threaded models
models=pmap(model_builder,1:10)
models[1][:x] in keys(models[1].ext[:expr].terms)
collect(keys(models[1].ext[:expr].terms))[1]==models[1][:x]
models[1].ext[:expr]+models[1].ext[:variable]
I’ve also attached an image showing the output from each line. As you can see everything is normal when using map. However, for pmap Julia thinks that the x in the expression and the x variable are different (sort of). When I add the expression 2x to the variable x, instead of getting 3x, I get 2x+x.
I’ve found a workaround to fix the expression, after pmap returns the models, but this only works single-threaded.
temp=model[1].ext[:expr]
temp_terms=collect(keys(temp.terms))
temp_values=collect(values(temp.terms))
model[1].ext[:expr]=AffExpr(temp.constant)
for i in 1:length(temp_terms)
model[1].ext[:expr]+=temp_values[i]*temp_terms[i]
end
The fact that this fix works confuses me, since it is just taking the variables and coefficients from an AffExpr in order to create a new (identical?) AffExpr. Perhaps, there’s something about how the memory is being managed between the threads that I don’t understand, but I thought that pmap would handle all of that.
