Hi
I’ve built a code which basically calculates the value of a complex non-linear function with a set of parameters for which I need to find a fixed point. Because of it is computationally heavy, I use distributed computing. Below is my attempt at simplifying the code I built.
model_wrapper!(pa::Param,pr::Prices,q_ret::AbstractArray{<:Real},q_act::AbstractArray{<:Real})
while abs(diff_AE) > tol_out || abs(diff_h) > tol_out
println("Starting inner loop")
# initiate mtg price convergence variables
diff_act_mtg = 1.0; diff_ret_mtg = 1.0
# Inner loop: mortgage pricing function
#--------------------------------------
while diff_act_mtg > tol_in || diff_ret_mtg > tol_in
# compute model
out = model_compute(pa_new,pr_new,q_ret,q_act)
# compute the norm between the mortgage pricing function
diff_act_mtg,act_coor = findmax(broadcast(abs,out.q_act_new-q_act))
diff_ret_mtg,ret_coor = findmax(broadcast(abs,out.q_ret_new-q_ret))
# current distances
println("")
println("Convergence criteria")
println("diff (housing) = $diff_h")
println("diff (mtg act) = $diff_act_mtg")
println("diff (mtg ret) = $diff_ret_mtg")
# update guesses of the mortgage pricing function
if diff_act_mtg > tol_in || diff_ret_mtg > tol_in # update only if it has not converged
q_ret = (1.0-hom_q)*out.q_ret_new + hom_q*q_ret
q_act = (1.0-hom_q)*out.q_act_new + hom_q*q_act
end
end
println("")
println("---- Inner loop converged ----")
abs(diff_h) > tol_out # only update if loop did not converge
pr_new.p_h = hom_p_h*pr_new.p_h + (1.0-hom_p_h)*((mm.HD-mm.HS)/pa_new.Lbar)^(pa_new.φ/(1.0-pa_new.φ))*(1.0/(1.0-pa_new.φ))
pr_new.p_h = max(pr_new.p_h,0.01)
pr_new.p_hp = copy(pr_new.p_h)
end
end
println("p_h = ",pr_new.p_h)
println("AE = ",pa_new.AE)
end
# compute the model one last time to obtain the statistics consistent with the updates
out = model_compute(pa_new,pr_new,q_ret,q_act)
println("")
println("---- Outer loop converged ----")
return (q_ret=out.q_ret,q_act=out.q_act,pa_new=out.pa_new,pr_new=out.pr_new)
end
What the function model_wrapper does is to take guesses for p_h, q_ret, q_act, and compute a fixed point using a homotopy algorithm. model_compute is the non-linear function for which I’m calculating the fixed point. Essentially, it takes parameters and guesses for the variables and computes values for the variables which are compared with the guesses. model_wrapper repeats this process until convergence.
Model compute can be summarized as follows:
model_compute(pa::Param,pr::Prices,q_ret::AbstractArray{<:Real},q_act::AbstractArray{<:Real})
pa_new = deep_copy(pa)
pr_new = deep_copy(pr)
vn_act = SharedArray{Float64}(nb,nϵ,na) # value function
cnf_act = SharedArray{Float64}(nb,nϵ,na) # consumption function
bnf_act = SharedArray{Float64}(nb,nϵ,na) # asset function
htnf_act = SharedArray{Float64}(nb,nϵ,na) # rent decision
hnf_act = SharedArray{Float64}(nb,nϵ,na) # house decision
mnf_act = SharedArray{Float64}(nb,nϵ,na) # mortgage decision
go_act = SharedArray{Int}(nb,nϵ,na) # decision to own
@sync @distributed for i in CartesianIndices(view(vn_act,1,:,:,1))
iϵ = i[1]; ia = i[2]; iy = (ia-1)*nϵ + iϵ
for ib in eachindex(b_grid)
bn,vn,cn,htn,hn,mn,gn = solve_problems(pa_new,pr_new,ib,iϵ,ia,q_ret,q_act)
vn_act[ib,iϵ,ia] = vn # value function
cnf_act[ib,iϵ,ia] = cn # consumption function
bnf_act[ib,iϵ,ia] = bn # bond function
htnf_act[ib,iϵ,ia] = htn # decision to rent
hnf_act[ib,iϵ,ia] = hn # own house
mnf_act[ib,iϵ,ia] = mn # mortage decision
go_act[ib,iϵ,ia] = gn # decision to own
end
end
out = calculate_statistics(pa_new,pr_new,vn_act,cnf_act,bnf_act,htnf_act,mnf_act,go_act)
return (pa_new = out.pa_new, pr_new = out.pr_new, q_ret_new = out.q_ret_new, q_act_new=out.q_act_new)
end
The problem which I did not foresee and cannot understand is the following: When I run the function model_wrapper many times, in order to see what happens when I change parameters, the RAM of my computer keeps allocating more and more memory (I have 256 G of RAM, and 64 processors) up to a point where I cannot run the function anymore. Could this be the result of creating new shared arrays each time I run the function? Why are they not eliminated from the memory of the cores once the model compute is finished? Thanks for any assistance