Skip to content

Commit 774da6a

Browse files
committed
[DEV] Implement parallelization of SDDP in a function
1 parent 8076bb5 commit 774da6a

File tree

1 file changed

+53
-37
lines changed

1 file changed

+53
-37
lines changed

examples/parallel_sddp.jl

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,57 @@
11

22
import StochDynamicProgramming
33

4-
require("damsvalley.jl")
5-
6-
# Perform n parallel passes:
7-
N_PARALLEL_COMPUTATIONS = 3
8-
# Synchronize cuts every n iterations:
9-
SYNCHRONIZE = 5
10-
11-
# Import model and params in main worker
12-
# /!\ This line must be before redefinition of seed!
13-
model, params = init_problem()
14-
15-
# Redefine seeds in every processes to maximize randomness:
16-
@everywhere srand()
17-
18-
params.maxItNumber = SYNCHRONIZE
19-
# First pass of algorithm to define value functions in memory:
20-
V = StochDynamicProgramming.solve_SDDP(model, params)[1]
21-
22-
# Count number of available CPU:
23-
ncpu = nprocs() - 1
24-
println("\nLaunch simulation on ", ncpu, " processes")
25-
workers = procs()[2:end]
26-
27-
# As we distribute computation in n process, we perform forward pass in parallel:
28-
params.forwardPassNumber = max(1, round(Int, params.forwardPassNumber/ncpu))
29-
30-
# Start parallel computation:
31-
for i in 1:N_PARALLEL_COMPUTATIONS
32-
# Distribute computation of SDDP in each process:
33-
refs = [@spawnat w StochDynamicProgramming.solve_SDDP(model, params, V, 1)[1] for w in workers]
34-
# Catch the result in the main process:
35-
V = StochDynamicProgramming.catcutsarray([fetch(r) for r in refs]...)
36-
# We clean the resultant cuts:
37-
StochDynamicProgramming.remove_redundant_cuts!(V)
38-
StochDynamicProgramming.prune_cuts!(model, params, V)
39-
println("Lower bound at pass ", i, ": ", StochDynamicProgramming.get_lower_bound(model, params, V))
40-
end
414

5+
"""
6+
Solve SDDP in parallel.
7+
8+
# Arguments
9+
* `model::SPmodel`:
10+
the stochastic problem we want to optimize
11+
* `param::SDDPparameters`:
12+
the parameters of the SDDP algorithm
13+
* `V::Array{PolyhedralFunction}`:
14+
the current estimation of Bellman's functions
15+
* `n_parallel_pass::Int`: default is 4
16+
Number of parallel pass to compute
17+
* `synchronize::Int`: default is 5
18+
Set when to synchronize the cuts between the different processes.
19+
* `display::Int`: default is 0
20+
Says whether to display results or not
21+
22+
# Return
23+
* `V::Array{PolyhedralFunction}`:
24+
the collection of approximation of the bellman functions
25+
"""
26+
function psolve_sddp(model, params, V; n_parallel_pass=4,
27+
synchronize=5, display=0)
28+
# Redefine seeds in every processes to maximize randomness:
29+
@everywhere srand()
30+
31+
mitn = params.maxItNumber
32+
params.maxItNumber = synchronize
33+
34+
# Count number of available CPU:
35+
ncpu = nprocs() - 1
36+
(display > 0) && println("\nLaunch simulation on ", ncpu, " processes")
37+
workers = procs()[2:end]
38+
39+
fpn = params.forwardPassNumber
40+
# As we distribute computation in n process, we perform forward pass in parallel:
41+
params.forwardPassNumber = max(1, round(Int, params.forwardPassNumber/ncpu))
42+
43+
# Start parallel computation:
44+
for i in 1:n_parallel_pass
45+
# Distribute computation of SDDP in each process:
46+
refs = [@spawnat w StochDynamicProgramming.solve_SDDP(model, params, V, display)[1] for w in workers]
47+
# Catch the result in the main process:
48+
V = StochDynamicProgramming.catcutsarray([fetch(r) for r in refs]...)
49+
# We clean the resultant cuts:
50+
StochDynamicProgramming.remove_redundant_cuts!(V)
51+
(display > 0) && println("Lower bound at pass ", i, ": ", StochDynamicProgramming.get_lower_bound(model, params, V))
52+
end
53+
54+
params.forwardPassNumber = fpn
55+
params.maxItNumber = mitn
56+
return V
57+
end

0 commit comments

Comments
 (0)