-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
I was interested in how we compare with the default SparseAxisArray in JuMP.
A naive implementation, using flow = m[:flow] is terrible, because flow can't be typed correctly. If we use a function barrier, it's still a problem, because the in-liner removes the function barrier for some reason. But if you use @noinline, then things are nicer. (It's also the reason for the 8 sec in "Test dictionary".)
The filter introduces some function call overhead, and the alternative is slightly cheating, because it reduces to a single iteration through the keys of flow.
julia> test()
-- Test SparseAxisArray --
Variable creation: 0.027661869 [nv=2160]
Constraint creation: 0.519338562 [nc=9093]
-- Test dictionary --
Variable creation: 0.005746578 [nv=2160]
Constraint creation: 7.898748765 [nc=9093]
-- Test dictionary filter--
Variable creation: 0.005215764 [nv=2160]
Constraint creation: 0.705254153 [nc=9093]
-- Test dictionary alternative --
Variable creation: 0.005294635 [nv=2160]
Constraint creation: 0.013705239 [nc=9093]
-- Test sparse array slice--
Variable creation: 0.004835772 [nv=2160]
Constraint creation: 0.059691706 [nc=9093]
-- Test sparse array select --
Variable creation: 0.005393562 [nv=2160]
Constraint creation: 0.593879205 [nc=9093]
-- Test sparse array with cache --
Variable creation: 0.005129799 [nv=2160]
Constraint creation: 0.039051761 [nc=9093]
-- Test sparse array with cache (check empty) --
Variable creation: 0.005233172 [nv=2160]
Constraint creation: 0.037110871 [nc=2563]
-- Test indexed table --
Variable creation: 0.006558805 [nv=2160]
Constraint creation: 0.008344676 [nc=2482]So the most interesting target is the sparse slice.
function create_vars_SparseAxisArray(m, pp)
return @variable(
m,
flow[
f = pp.factories,
c = pp.customers,
p = pp.products,
t = pp.periods;
haskey(pp.demand, (c, p, t)) && canproduce(pp, f, p)
] >= 0,
)
end
function create_constraints_SparseAxisArray(m, pp)
flow = m[:flow]
_create_constraints_SparseAxisArray(m, pp, flow)
end
@noinline function _create_constraints_SparseAxisArray(m, pp, flow)
# Production capacity
for (f, t) in keys(pp.prodcap)
@constraint(
m,
sum(
flow[f, c, p, t] for
(ff, c, p, tt) in eachindex(flow) if ff == f && tt == t
) ≤ pp.prodcap[f, t]
)
end
# Customer demand
for (c, p, t) in keys(pp.demand)
@constraint(
m,
sum(
flow[f, c, p, t] for
(f, cc, pp, tt) in eachindex(flow) if cc == c && pp == p && tt == t
) ≤ pp.demand[c, p, t]
)
end
# Transport capacity
for (f, c) in keys(pp.flowcap), t in pp.periods
@constraint(
m,
sum(
flow[f, c, p, t] for
(ff, cc, p, tt) in eachindex(flow) if ff == f && cc == c && tt == t
) ≤ pp.flowcap[f, c]
)
end
end
function test_SparseAxisArray(pp)
println("-- Test SparseAxisArray --")
m = Model()
t1 = @elapsed create_vars_SparseAxisArray(m, pp)
println("Variable creation: $t1 [nv=$(num_variables(m))]")
t2 = @elapsed create_constraints_SparseAxisArray(m, pp)
println(
"Constraint creation: $t2 [nc=$(num_constraints(m, AffExpr, MOI.LessThan{Float64}))]",
)
return println()
endReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels