Skip to content

Commit dad2b10

Browse files
Merge pull request #2600 from pybamm-team/i2599-bench-idaklu
I2599 bench idaklu
2 parents 5be34ac + 3cbb4ab commit dad2b10

File tree

7 files changed

+164
-136
lines changed

7 files changed

+164
-136
lines changed

.github/workflows/benchmark_on_push.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ jobs:
1111
uses: actions/setup-python@v4
1212
with:
1313
python-version: 3.8
14-
- name: Install asv
15-
run: pip install -U pip virtualenv asv
14+
- name: Install Linux system dependencies
15+
run: |
16+
sudo apt-get update
17+
sudo apt install gfortran gcc libopenblas-dev
18+
- name: Install python dependencies
19+
run: |
20+
python -m pip install --upgrade pip wheel setuptools virtualenv asv wget cmake casadi numpy
21+
- name: Install SuiteSparse and Sundials
22+
run: python scripts/install_KLU_Sundials.py
1623
- name: Fetch base branch
1724
run: |
1825
# This workflow also runs for merge commits
@@ -22,6 +29,7 @@ jobs:
2229
if [ $current_branch != "develop" ]; then
2330
git fetch origin develop:develop
2431
fi
32+
2533
- name: Run benchmarks
2634
run: |
2735
asv machine --machine "GitHubRunner"
@@ -30,7 +38,7 @@ jobs:
3038
HEAD_COMMIT=$(git rev-parse HEAD)
3139
echo $BASE_COMMIT | tee commits_to_compare.txt
3240
echo $HEAD_COMMIT | tee -a commits_to_compare.txt
33-
asv run HASHFILE:commits_to_compare.txt --m "GitHubRunner" --show-stderr
41+
asv run HASHFILE:commits_to_compare.txt --m "GitHubRunner" --show-stderr -v
3442
- name: Compare commits' benchmark results
3543
run: |
3644
BASE_COMMIT=$(head -1 commits_to_compare.txt)

asv.conf.json

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
//
2424
// "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}"],
2525
// "uninstall_command": ["return-code=any python -mpip uninstall -y {project}"],
26-
// "build_command": [
27-
// "python setup.py build",
28-
// "PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}"
29-
// ],
26+
"build_command": [
27+
"/usr/bin/git clone --depth 1 --branch v2.6.2 https://github.com/pybind/pybind11.git",
28+
"python setup.py build",
29+
"PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}"
30+
],
3031

3132
// List of branches to benchmark. If not provided, defaults to "master"
3233
// (for git) or "default" (for mercurial).
@@ -44,7 +45,7 @@
4445
// If missing or the empty string, the tool will be automatically
4546
// determined by looking for tools on the PATH environment
4647
// variable.
47-
"environment_type": "virtualenv"
48+
"environment_type": "virtualenv",
4849

4950
// timeout in seconds for installing any dependencies in environment
5051
// defaults to 10 min
@@ -71,11 +72,17 @@
7172
// pip (with all the conda available packages installed first,
7273
// followed by the pip installed packages).
7374
//
74-
// "matrix": {
75-
// "numpy": ["1.6", "1.7"],
76-
// "six": ["", null], // test with and without six installed
77-
// "pip+emcee": [""], // emcee is only available for install with pip.
78-
// },
75+
"matrix": {
76+
"req": {
77+
"numpy": [],
78+
"casadi": [],
79+
"wget": [],
80+
"cmake": []
81+
},
82+
"env": {
83+
"LD_LIBRARY_PATH": "/home/runner/.local/lib"
84+
}
85+
}
7986

8087
// Combinations of libraries/python versions can be excluded/included
8188
// from the set to test. Each entry is a dictionary containing additional

benchmarks/different_model_options.py

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,19 @@ def build_model(parameter, model_, option, value):
3030

3131

3232
class SolveModel:
33-
solver = pybamm.CasadiSolver()
34-
35-
def solve_setup(self, parameter, model_, option, value):
33+
def solve_setup(self, parameter, model_, option, value, solver_class):
34+
import importlib
35+
36+
idaklu_spec = importlib.util.find_spec("pybamm.solvers.idaklu")
37+
if idaklu_spec is not None:
38+
try:
39+
idaklu = importlib.util.module_from_spec(idaklu_spec)
40+
idaklu_spec.loader.exec_module(idaklu)
41+
except ImportError as e: # pragma: no cover
42+
print("XXXXX cannot find klu", e)
43+
idaklu_spec = None
44+
45+
self.solver = solver_class()
3646
self.model = model_({option: value})
3747
c_rate = 1
3848
tmax = 4000 / c_rate
@@ -62,7 +72,7 @@ def solve_setup(self, parameter, model_, option, value):
6272
disc.process_model(self.model)
6373

6474
def solve_model(self, model, params):
65-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
75+
self.solver.solve(self.model, t_eval=self.t_eval)
6676

6777

6878
class TimeBuildModelLossActiveMaterial:
@@ -78,17 +88,20 @@ def time_setup_model(self, model, params):
7888

7989

8090
class TimeSolveLossActiveMaterial:
81-
param_names = ["model", "model option"]
91+
param_names = ["model", "model option", "solver class"]
8292
params = (
8393
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
8494
["none", "stress-driven", "reaction-driven", "stress and reaction-driven"],
95+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
8596
)
8697

87-
def setup(self, model, params):
88-
SolveModel.solve_setup(self, "Ai2020", model, "loss of active material", params)
98+
def setup(self, model, params, solver_class):
99+
SolveModel.solve_setup(
100+
self, "Ai2020", model, "loss of active material", params, solver_class
101+
)
89102

90-
def time_solve_model(self, model, params):
91-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
103+
def time_solve_model(self, model, params, solver_class):
104+
self.solver.solve(self.model, t_eval=self.t_eval)
92105

93106

94107
class TimeBuildModelLithiumPlating:
@@ -103,17 +116,20 @@ def time_setup_model(self, model, params):
103116

104117

105118
class TimeSolveLithiumPlating:
106-
param_names = ["model", "model option"]
119+
param_names = ["model", "model option", "solver class"]
107120
params = (
108121
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
109122
["none", "irreversible", "reversible", "partially reversible"],
123+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
110124
)
111125

112-
def setup(self, model, params):
113-
SolveModel.solve_setup(self, "OKane2020", model, "lithium plating", params)
126+
def setup(self, model, params, solver_class):
127+
SolveModel.solve_setup(
128+
self, "OKane2020", model, "lithium plating", params, solver_class
129+
)
114130

115-
def time_solve_model(self, model, params):
116-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
131+
def time_solve_model(self, model, params, solver_class):
132+
self.solver.solve(self.model, t_eval=self.t_eval)
117133

118134

119135
class TimeBuildModelSEI:
@@ -138,7 +154,7 @@ def time_setup_model(self, model, params):
138154

139155

140156
class TimeSolveSEI:
141-
param_names = ["model", "model option"]
157+
param_names = ["model", "model option", "solver class"]
142158
params = (
143159
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
144160
[
@@ -152,13 +168,14 @@ class TimeSolveSEI:
152168
"ec reaction limited",
153169
"ec reaction limited (asymmetric)",
154170
],
171+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
155172
)
156173

157-
def setup(self, model, params):
158-
SolveModel.solve_setup(self, "Marquis2019", model, "SEI", params)
174+
def setup(self, model, params, solver_class):
175+
SolveModel.solve_setup(self, "Marquis2019", model, "SEI", params, solver_class)
159176

160-
def time_solve_model(self, model, params):
161-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
177+
def time_solve_model(self, model, params, solver_class):
178+
self.solver.solve(self.model, t_eval=self.t_eval)
162179

163180

164181
class TimeBuildModelParticle:
@@ -178,7 +195,7 @@ def time_setup_model(self, model, params):
178195

179196

180197
class TimeSolveParticle:
181-
param_names = ["model", "model option"]
198+
param_names = ["model", "model option", "solver class"]
182199
params = (
183200
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
184201
[
@@ -187,13 +204,16 @@ class TimeSolveParticle:
187204
"quadratic profile",
188205
"quartic profile",
189206
],
207+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
190208
)
191209

192-
def setup(self, model, params):
193-
SolveModel.solve_setup(self, "Marquis2019", model, "particle", params)
210+
def setup(self, model, params, solver_class):
211+
SolveModel.solve_setup(
212+
self, "Marquis2019", model, "particle", params, solver_class
213+
)
194214

195-
def time_solve_model(self, model, params):
196-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
215+
def time_solve_model(self, model, params, solver_class):
216+
self.solver.solve(self.model, t_eval=self.t_eval)
197217

198218

199219
class TimeBuildModelThermal:
@@ -208,17 +228,20 @@ def time_setup_model(self, model, params):
208228

209229

210230
class TimeSolveThermal:
211-
param_names = ["model", "model option"]
231+
param_names = ["model", "model option", "solver class"]
212232
params = (
213233
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
214234
["isothermal", "lumped", "x-lumped", "x-full"],
235+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
215236
)
216237

217-
def setup(self, model, params):
218-
SolveModel.solve_setup(self, "Marquis2019", model, "thermal", params)
238+
def setup(self, model, params, solver_class):
239+
SolveModel.solve_setup(
240+
self, "Marquis2019", model, "thermal", params, solver_class
241+
)
219242

220-
def time_solve_model(self, model, params):
221-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
243+
def time_solve_model(self, model, params, solver_class):
244+
self.solver.solve(self.model, t_eval=self.t_eval)
222245

223246

224247
class TimeBuildModelSurfaceForm:
@@ -233,14 +256,17 @@ def time_setup_model(self, model, params):
233256

234257

235258
class TimeSolveSurfaceForm:
236-
param_names = ["model", "model option"]
259+
param_names = ["model", "model option", "solver class"]
237260
params = (
238261
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
239262
["false", "differential", "algebraic"],
263+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
240264
)
241265

242-
def setup(self, model, params):
243-
SolveModel.solve_setup(self, "Marquis2019", model, "surface form", params)
266+
def setup(self, model, params, solver_class):
267+
SolveModel.solve_setup(
268+
self, "Marquis2019", model, "surface form", params, solver_class
269+
)
244270

245-
def time_solve_model(self, model, params):
246-
SolveModel.solver.solve(self.model, t_eval=self.t_eval)
271+
def time_solve_model(self, model, params, solver_class):
272+
self.solver.solve(self.model, t_eval=self.t_eval)
Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,43 @@
11
import pybamm
22

3-
parameters = ["Marquis2019", "Chen2020"]
43

5-
6-
class TimeSPMSimulationCCCV:
7-
param_names = ["parameter"]
8-
params = parameters
9-
10-
def time_setup_SPM_simulation(self, parameters):
11-
self.param = pybamm.ParameterValues(parameters)
12-
self.model = pybamm.lithium_ion.SPM()
13-
exp = pybamm.Experiment(
14-
[
15-
"Discharge at C/5 for 10 hours or until 3.3 V",
16-
"Rest for 1 hour",
17-
"Charge at 1 A until 4.1 V",
18-
"Hold at 4.1 V until 10 mA",
19-
"Rest for 1 hour",
20-
]
21-
)
22-
pybamm.Simulation(self.model, parameter_values=self.param, experiment=exp)
23-
24-
25-
class TimeDFNSimulationCCCV:
26-
param_names = ["parameter"]
27-
params = parameters
28-
29-
def time_setup_SPM_simulation(self, parameters):
4+
class TimeSimulation:
5+
param_names = ["experiment", "parameter", "model_class", "solver_class"]
6+
params = [
7+
["CCCV", "GITT"],
8+
["Marquis2019", "Chen2020"],
9+
[pybamm.lithium_ion.SPM, pybamm.lithium_ion.DFN],
10+
[pybamm.CasadiSolver, pybamm.IDAKLUSolver],
11+
]
12+
experiment_descriptions = {
13+
"CCCV": [
14+
"Discharge at C/5 for 10 hours or until 3.3 V",
15+
"Rest for 1 hour",
16+
"Charge at 1 A until 4.1 V",
17+
"Hold at 4.1 V until 10 mA",
18+
"Rest for 1 hour",
19+
],
20+
"GITT": [("Discharge at C/20 for 1 hour", "Rest for 1 hour")] * 20,
21+
}
22+
23+
def setup(self, experiment, parameters, model_class, solver_class):
3024
self.param = pybamm.ParameterValues(parameters)
31-
self.model = pybamm.lithium_ion.DFN()
32-
exp = pybamm.Experiment(
33-
[
34-
"Discharge at C/5 for 10 hours or until 3.3 V",
35-
"Rest for 1 hour",
36-
"Charge at 1 A until 4.1 V",
37-
"Hold at 4.1 V until 10 mA",
38-
"Rest for 1 hour",
39-
]
25+
self.model = model_class()
26+
self.solver = solver_class()
27+
self.exp = pybamm.Experiment(self.experiment_descriptions[experiment])
28+
self.sim = pybamm.Simulation(
29+
self.model,
30+
parameter_values=self.param,
31+
experiment=self.exp,
32+
solver=self.solver,
4033
)
41-
pybamm.Simulation(self.model, parameter_values=self.param, experiment=exp)
42-
4334

44-
class TimeSPMSimulationGITT:
45-
param_names = ["parameter"]
46-
params = parameters
35+
def time_setup(self, experiment, parameters, model_class, solver_class):
36+
param = pybamm.ParameterValues(parameters)
37+
model = model_class()
38+
solver = solver_class()
39+
exp = pybamm.Experiment(self.experiment_descriptions[experiment])
40+
pybamm.Simulation(model, parameter_values=param, experiment=exp, solver=solver)
4741

48-
def time_setup_SPM_simulation(self, parameters):
49-
self.param = pybamm.ParameterValues(parameters)
50-
self.model = pybamm.lithium_ion.SPM()
51-
exp = pybamm.Experiment(
52-
[("Discharge at C/20 for 1 hour", "Rest for 1 hour")] * 20
53-
)
54-
pybamm.Simulation(self.model, parameter_values=self.param, experiment=exp)
55-
56-
57-
class TimeDFNSimulationGITT:
58-
param_names = ["parameter"]
59-
params = parameters
60-
61-
def time_setup_SPM_simulation(self, parameters):
62-
self.param = pybamm.ParameterValues(parameters)
63-
self.model = pybamm.lithium_ion.DFN()
64-
exp = pybamm.Experiment(
65-
[("Discharge at C/20 for 1 hour", "Rest for 1 hour")] * 20
66-
)
67-
pybamm.Simulation(self.model, parameter_values=self.param, experiment=exp)
42+
def time_solve(self, experiment, parameters, model_class, solver_class):
43+
self.sim.solve()

0 commit comments

Comments
 (0)