Skip to content

Commit 8dc133b

Browse files
Merge pull request #36 from opencobra/develop
Regular merge of develop
2 parents a8b4037 + dd4c7c8 commit 8dc133b

File tree

9 files changed

+306
-157
lines changed

9 files changed

+306
-157
lines changed

src/PALM.jl

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#-------------------------------------------------------------------------------------------
99
"""
10-
shareLoad(nModels, nMatlab, verbose)
10+
shareLoad(nModels, nMatlab, printLevel)
1111
1212
Function shares the number of `nModels` across `nMatlab` sessions (Euclidian division)
1313
@@ -17,8 +17,9 @@ Function shares the number of `nModels` across `nMatlab` sessions (Euclidian div
1717
1818
# OPTIONAL INPUTS
1919
20-
- `nMatlab`: Number of desired MATLAB sessions (default: 2)
21-
- `verbose`: Verbose mode, set `false` for quiet load sharing (default: true)
20+
- `nMatlab`: Number of desired MATLAB sessions (default: 2)
21+
- `printLevel`: Verbose level (default: 1). Mute all output with `printLevel = 0`.
22+
- `dryRun`: Test load sharing without changing the parpool (default: false)
2223
2324
# OUTPUTS
2425
@@ -35,71 +36,79 @@ julia> shareLoad(nModels)
3536
3637
- Determination of the load of 4 models in 2 MATLAB sessions
3738
```julia
38-
julia> shareLoad(4, 2, false)
39+
julia> shareLoad(4, 2, 1)
3940
```
4041
4142
See also: `createPool()` and `PALM`
4243
4344
"""
4445

45-
function shareLoad(nModels::Int, nMatlab::Int = 2, verbose::Bool = true)
46+
function shareLoad(nModels::Int, nMatlab::Int = 2, printLevel::Int=1, dryRun::Bool=false)
47+
48+
if printLevel > 0 && dryRun
49+
info("Load sharing is determined without actively changing the number of connected workers (dryRun = true).")
50+
end
4651

4752
# Make sure that not more processes are launched than there are models (load ratio >= 1)
4853
if nMatlab > nModels
49-
if verbose
54+
if printLevel > 0
5055
warn("Number of workers ($nMatlab) exceeds the number of models ($nModels).")
5156
end
5257

5358
nMatlab = nModels
5459

5560
# remove the last workers in the pool
56-
for k = length(workers()):-1:nModels
57-
rmprocs(k)
61+
if !dryRun
62+
for k = length(workers()):-1:nModels
63+
rmprocs(k)
64+
end
5865
end
5966

60-
if verbose
67+
if printLevel > 0
6168
warn("Number of workers reduced to number of models for ideal load distribution.\n")
6269
end
6370
end
6471

6572
# Definition of workers and load distribution
66-
wrks = workers()
73+
if dryRun
74+
wrks = [1:nMatlab;]
75+
else
76+
wrks = workers()
77+
end
6778
nWorkers = length(wrks)
6879
quotientModels = Int(ceil(nModels / nWorkers))
6980

7081
remainderModels = 0
7182

7283
if nModels%nWorkers > 0
73-
if verbose
74-
println(" >> Every worker (#", wrks[1], " - #", wrks[end - 1], ") will solve ", quotientModels, " model(s).")
84+
if printLevel > 0
85+
println(" >> Every worker (#", wrks[1], " - #", wrks[end - 1], ") will run (at least) ", quotientModels, " model(s).")
7586
end
7687

77-
#remainderModels = Int(nModels - (nWorkers) * quotientModels)
7888
remainderModels = Int(nModels - (nWorkers - 1) * quotientModels)
7989
if remainderModels > 0
80-
if verbose
81-
#println(" >> Worker #", wrks[end-1], " will solve ", quotientModels + remainderModels, " model(s).")
90+
if printLevel > 0
8291
println(" >> Worker #", wrks[end-1], " will solve ", quotientModels + remainderModels, " model(s).")
8392
end
8493
end
8594

8695
if quotientModels < remainderModels - 1 || remainderModels < 1
87-
if verbose
96+
if printLevel > 0
8897
print_with_color(:red, "\n >> Load sharing is not fair. Consider adjusting the maximum poolsize.\n")
8998
end
9099
else
91-
if verbose
100+
if printLevel > 0
92101
print_with_color(:yellow, "\n >> Load sharing is almost ideal.\n")
93102
end
94103
end
95104
else
96-
if verbose
105+
if printLevel > 0
97106
println(" >> Every worker will run ", quotientModels, " model(s).")
98107
print_with_color(:green, " >> Load sharing is ideal.\n")
99108
end
100109
end
101110

102-
if verbose
111+
if printLevel > 0
103112
println("\n -- Load distribution --\n")
104113
println(" - Number of models: $nModels")
105114
println(" - Number of workers: $nWorkers")
@@ -113,7 +122,7 @@ end
113122

114123
#-------------------------------------------------------------------------------------------
115124
"""
116-
loopModels(dir, p, scriptName, dirContent, startIndex, endIndex, varsCharact)
125+
loopModels(dir, p, scriptName, dirContent, startIndex, endIndex, varsCharact, printLevel)
117126
118127
Function `loopModels` is generally called in a loop from `PALM()` on worker `p`.
119128
Runs `scriptName` for all models with an index in `dirContent` between `startIndex` and `endIndex`.
@@ -130,6 +139,10 @@ is computed as `nModels = endIndex - startIndex + 1`.
130139
- `endIndex`: Index of the last model in `dirContent` to be used on worker `p`
131140
- `varsCharact`: Array with the names of variables to be retrieved from the MATLAB session on worker `p`
132141
142+
# OPTIONAL INPUTS
143+
144+
- `printLevel`: Verbose level (default: 1). Mute all output with `printLevel = 0`.
145+
133146
# OUTPUTS
134147
135148
- `data`: Mixed array of variables retrieved from worker p (rows: models, columns: variables).
@@ -146,37 +159,39 @@ See also: `PALM()`
146159
147160
"""
148161

149-
function loopModels(dir, p, scriptName, dirContent, startIndex, endIndex, varsCharact, localnModels)
162+
function loopModels(dir, p, scriptName, dirContent, startIndex, endIndex, varsCharact, localnModels, printLevel::Int=1)
150163

151164
# determine the lengt of the number of variables
152165
nCharacteristics = length(varsCharact)
153166

154167
#local nModels
155168
if endIndex >= startIndex
156-
#nModels = endIndex - startIndex + 1
157-
158169
# declaration of local data array
159170
data = Array{Union{Int,Float64,AbstractString}}(localnModels, nCharacteristics + 1)
160171

161172
for k = 1:localnModels
162173
PALM_iModel = k #+ (p - 1) * nModels
163174
PALM_modelFile = dirContent[startIndex+k-1]
164175
PALM_dir = dir
176+
PALM_printLevel = printLevel
165177

166178
# save the modelName
167179
data[k, 1] = PALM_modelFile
168180

169181
MATLAB.@mput PALM_iModel
170182
MATLAB.@mput PALM_modelFile
171183
MATLAB.@mput PALM_dir
184+
MATLAB.@mput PALM_printLevel
172185
eval(parse("MATLAB.mat\"run('$scriptName')\""))
173186

174187
for i = 1:nCharacteristics
175188
data[k, i + 1] = MATLAB.get_variable(Symbol(varsCharact[i]))
176189
end
177190
end
178191

179-
@show data
192+
if printLevel > 0
193+
@show data
194+
end
180195

181196
return data
182197
else
@@ -186,7 +201,7 @@ end
186201

187202
#-------------------------------------------------------------------------------------------
188203
"""
189-
PALM(dir, scriptName, nMatlab, outputFile, cobraToolboxDir)
204+
PALM(dir, scriptName, nMatlab, outputFile, cobraToolboxDir, printLevel)
190205
191206
Function reads the directory `dir`, and launches `nMatlab` sessions to run `scriptName`.
192207
Results are saved in the `outputFile`.
@@ -201,6 +216,7 @@ Results are saved in the `outputFile`.
201216
- `nMatlab`: Number of desired MATLAB sessions (default: 2)
202217
- `outputFile`: Name of `.mat` file to save the result table named "summaryData" (default name: "PALM_data.mat")
203218
- `cobraToolboxDir`: Directory of the COBRA Toolbox (default: "~/cobratoolbox")
219+
- `printLevel`: Verbose level (default: 1). Mute all output with `printLevel = 0`.
204220
205221
# OUTPUTS
206222
@@ -222,12 +238,14 @@ See also: `loopModels()` and `shareLoad()`
222238
223239
"""
224240

225-
function PALM(dir, scriptName, nMatlab::Int=2, outputFile::AbstractString="PALM_data.mat", varsCharact=[], cobraToolboxDir=ENV["HOME"]*Base.Filesystem.path_separator*"cobratoolbox")
241+
function PALM(dir, scriptName, nMatlab::Int=2, outputFile::AbstractString="PALM_data.mat", varsCharact=[], cobraToolboxDir=ENV["HOME"]*Base.Filesystem.path_separator*"cobratoolbox", printLevel::Int=1)
226242

227243
# read the content of the directory
228244
dirContent = readdir(dir)
229245

230-
info("Directory with $(length(dirContent)) models read successfully.")
246+
if printLevel > 0
247+
info("Directory with $(length(dirContent)) models read successfully.")
248+
end
231249

232250
nWorkers, quotientModels, remainderModels = shareLoad(length(dirContent), nMatlab)
233251

@@ -263,22 +281,27 @@ function PALM(dir, scriptName, nMatlab::Int=2, outputFile::AbstractString="PALM_
263281
# launch the function loopModels on every worker
264282
@sync for (p, pid) in enumerate(workers())
265283

266-
info("Launching MATLAB session on worker $(p+1).")
284+
if printLevel > 0
285+
info("Launching MATLAB session on worker $(p+1).")
286+
end
267287

288+
# adding the model directory and eventual subdirectories to the MATLAB path
289+
# Note: the fileseparator `/` also works on Windows systems if git Bash has been installed
268290
@async R[p] = @spawnat (p+1) begin
269-
# adding the model directory and eventual subdirectories to the MATLAB path
270291
eval(parse("mat\"addpath(genpath('/tmp/test-ct-$p'))\""))
271-
eval(parse("mat\"run('/tmp/test-ct-$p/initCobraToolbox.m');\"")) #*Base.Filesystem.path_separator*
272-
# add the path with the models
273-
#eval(parse("mat\"addpath('$dir');\""))
292+
eval(parse("mat\"run('/tmp/test-ct-$p/initCobraToolbox.m');\""))
274293
end
275294

276295
end
277296

278-
info("> MATLAB sessions initializing")
297+
# print an informative message
298+
if printLevel > 0
299+
info("> MATLAB sessions initializing")
300+
end
279301

280302
@sync for (p, pid) in enumerate(workers())
281303

304+
# determine the starting index
282305
startIndex = Int((p - 1) * quotientModels + 1)
283306

284307
# save the startIndex for each worker
@@ -292,8 +315,9 @@ function PALM(dir, scriptName, nMatlab::Int=2, outputFile::AbstractString="PALM_
292315

293316
localnModels = quotientModels
294317

295-
info("(case1): Worker $(p+1) runs $localnModels models: from $startIndex to $endIndex")
296-
318+
if printLevel > 0
319+
info("(case1): Worker $(p+1) runs $localnModels models: from $startIndex to $endIndex")
320+
end
297321
else
298322
endIndex = Int((p+1) * quotientModels + remainderModels)
299323

@@ -306,8 +330,9 @@ function PALM(dir, scriptName, nMatlab::Int=2, outputFile::AbstractString="PALM_
306330

307331
localnModels = endIndex - startIndex + 1
308332

309-
info("(case 2): Worker $(p+1) runs $localnModels models: from $startIndex to $endIndex")
310-
333+
if printLevel > 0
334+
info("(case 2): Worker $(p+1) runs $localnModels models: from $startIndex to $endIndex")
335+
end
311336
end
312337

313338
@async R[p] = @spawnat (p+1) begin

src/checkSetup.jl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ Function checks whether a package is installed properly or not and returns a boo
1717
1818
# OPTIONAL INPUTS
1919
20-
- `verbose`: Verbose mode:
21-
- 0: off (quiet)
22-
- 1: on (default)
20+
- `printLevel`: Verbose level (default: 1). Mute all output with `printLevel = 0`.
2321
2422
# OUTPUTS
2523
@@ -29,13 +27,13 @@ See also: `using`, `isdir()`
2927
3028
"""
3129

32-
function checkPackage(pkgName, verbose = 1)
30+
function checkPackage(pkgName, printLevel::Int=1)
3331

3432
try
3533
eval(Expr(:using, pkgName))
3634
return true
3735
catch
38-
if verbose == 1
36+
if printLevel > 0
3937
print_with_color(:yellow, "Package ",string(pkgName), " is not installed. ",
4038
"In order to use $pkgName, you must first run `Pkg.add(\"$pkgName\")`\n")
4139
end
@@ -46,16 +44,14 @@ end
4644

4745
#-------------------------------------------------------------------------------------------
4846
"""
49-
checkSysConfig()
47+
checkSysConfig(printLevel)
5048
5149
Function evaluates whether the LP solvers of MathProgBase are installed on the system or not and
5250
returns a list of these packages. `MathProgBase.jl` must be installed.
5351
5452
# OPTIONAL INPUTS
5553
56-
- `verbose`: Verbose mode:
57-
- 0: off (quiet)
58-
- 1: on (default)
54+
- `printLevel`: Verbose level (default: 1). Mute all output with `printLevel = 0`.
5955
6056
# OUTPUTS
6157
@@ -65,9 +61,9 @@ See also: `MathProgBase`, `checkPackage()`
6561
6662
"""
6763

68-
function checkSysConfig(verbose = 1)
64+
function checkSysConfig(printLevel::Int=1)
6965

70-
if verbose == 1
66+
if printLevel > 0
7167
print_with_color(:yellow, "\n >> Checking the system's configuration ...\n\n")
7268
end
7369

@@ -77,22 +73,22 @@ function checkSysConfig(verbose = 1)
7773
# initialize a vector with supported LP solvers
7874
LPsolvers = [:Clp, :GLPKMathProgInterface, :Gurobi, :CPLEX, :Mosek]
7975

80-
if checkPackage(:MathProgBase, verbose)
76+
if checkPackage(:MathProgBase, printLevel)
8177

8278
# loop through all implemented interfaces
8379
for s in 1:length(LPsolvers)
8480
pkgName = LPsolvers[s]
8581

86-
if checkPackage(pkgName, verbose)
87-
if verbose == 1
82+
if checkPackage(pkgName, printLevel)
83+
if printLevel > 0
8884
print_with_color(:green, string(pkgName), " is installed.\n")
8985
end
9086
push!(packages, pkgName)
9187
end
9288

9389
# load an additional package for GLPK
9490
if string(pkgName) == "GLPKMathProgInterface"
95-
checkPackage(:GLPK, verbose)
91+
checkPackage(:GLPK, printLevel)
9692
end
9793
end
9894

@@ -104,7 +100,7 @@ function checkSysConfig(verbose = 1)
104100

105101
# print a success message if the solver is installed
106102
catch
107-
if verbose == 1
103+
if printLevel > 0
108104
print_with_color(:green, "\n >> Done. $(length(packages)) solvers are installed and ready to use.\n")
109105
end
110106

0 commit comments

Comments
 (0)