Hello, I am trying to squeeze performance of the following code as much as possible. When I benchmark it, I get a very large number for the garbage collection statistic (see below). Does anyone have any recommendation for addressing this issue?
using JuMP, Ipopt, LinearAlgebra, Random, Distributions, BenchmarkTools, MosekTools, NLopt, Plots, FLoops
Threads.nthreads()
const N = 100
const Ι = 250
const J = 50
const σ = 5
const α = 0.15
const S= 100
Random.seed!(2109)
zbar = rand(Ι)
variance = 2.5
Random.seed!(12345)
z= exp.(rand(Normal(-variance/2,sqrt(variance)),Ι,S)) .+ zbar
Random.seed!(123)
β = ones(J)
function distmat(J,Ι)
Distances = zeros(J,Ι)
Random.seed!(7777)
coordinates_market = hcat([x for x = 1:J],fill(0.0,J))
coordinates_plant = hcat([x for x = 1:Ι].*J/Ι,fill(0.0,Ι))
for j = 1:J, l=1:Ι
Distances[j,l] = sqrt((coordinates_market[j,1]-coordinates_plant[l,1])^2+(coordinates_market[j,2]-coordinates_plant[l,2])^2)
end
return 1 .+ Distances
end
const τ = distmat(J,Ι)
function f2(Cap,β,τ,z)
(J,Ι) = size(τ)
opt = JuMP.Model(optimizer_with_attributes(Mosek.Optimizer, "QUIET" => false, "INTPNT_CO_TOL_DFEAS" => 1e-7))
set_silent(opt)
mktsize = ((σ-1)/σ)^(σ-1)/(σ).*β.^(σ)
@variable(opt, ν[1:Ι] >= 0)
@variable(opt, μ[1:J]>= 0)
@variable(opt, t[1:J]>= 0)
@objective(opt, Min, ν'*Cap .+ mktsize'*t)
@inbounds for i=1:Ι, j=1:J
@constraint(opt, τ[j,i]/z[i] + τ[j,i]*ν[i] - μ[j] >= 0)
end
@inbounds for j = 1 : J
@constraint(opt, [t[j],μ[j],1] in MOI.PowerCone(1/σ))
end
JuMP.optimize!(opt)
#return objective_value(opt), value.(μ), value.(ν)
return objective_value(opt), value.(ν)[1:Ι], value.(μ)[1:J]
end
@views function f1(Cap,β,τ,z)
(J,Ι) = size(τ)
Simul = size(z)[2]
@inbounds @floop for s = 1 : Simul
temp = f2(Cap,β,τ,z[:,s])./Simul
@reduce( Eπ = zero(eltype(temp[1])) + temp[1] )
@reduce( Eν = zeros(Ι) + temp[2] )
end
func = Eπ .- α*sum(Cap)
foc = Eν .- α
return func, foc
end
function myfunc_floops(x::Vector, grad::Vector)
temp = f1(x,β,τ,z)
if length(grad) > 0
grad[:]=-temp[2]
end
return -temp[1]
end
function fopt(guess)
opt = Opt(:LD_MMA, Ι)
opt.lower_bounds = zeros(Ι)
opt.xtol_rel = 1e-3
opt.ftol_rel = 1e-8
opt.min_objective = myfunc_floops
(minf,minx,ret) = NLopt.optimize(opt, guess)
numevals = opt.numevals # the number of function evaluations
println("got $minf at $minx after $numevals iterations in (returned $ret)")
return minx
end
sol = @benchmark fopt(ones(Ι))
sol
with the following benchmark results
Single result which took 147.664 s (18.66% GC) to evaluate,
with a memory estimate of 172.62 GiB, over 2295693135 allocations.