Skip to content

Commit 87cd435

Browse files
authored
Add An Open Energy Modeling update (#165)
1 parent dd9e59d commit 87cd435

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

_posts/2025-01-27-oem_update.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
layout: post
3+
title: "An Open Energy Modeling update"
4+
date: 2025-01-27
5+
categories: [open-energy-modeling]
6+
author: "Oscar Dowson, Ivet Galabova, Joaquim Dias Garcia, Julian Hall"
7+
---
8+
9+
We're now four months into our [Open Energy Modeling project](/announcements/open-energy-modeling/2024/09/16/oem/).
10+
This blog post is a summary of some of things that we have been up to.
11+
12+
## Community engagement
13+
14+
We have increased engagement between the developers of JuMP and HiGHS and the
15+
open energy modeling community. We have done this by holding fortnightly
16+
stakeholder calls, publishing bi-monthly updates on the JuMP blog (like this
17+
one), and interacting with the developers of energy modeling frameworks by
18+
opening issues and pull requests on GitHub. As a general comment, we (the
19+
developers of JuMP and HiGHS) now have a much better understanding of the types
20+
of problems that are of interest to energy modelers, and these problems have
21+
"unusual" characteristics that are not typical of the wider optimization
22+
community.
23+
24+
If you are an open energy modeller who uses JuMP or HiGHS and you want to stay
25+
in touch with our progress or provide us with feedback and examples, write to
26+
`jump-highs-energy-models@googlegroups.com`. We'd love to hear how you are using
27+
JuMP or HiGHS to solve problems related to open energy modelling.
28+
29+
## JuMP-dev
30+
31+
We held an energy modeling session at [JuMP-dev 2024](/meetings/jumpdev2024/),
32+
which was held in July in Montreal, Canada. All talks from the workshop are
33+
[available on YouTube](https://youtube.com/playlist?list=PLP8iPy9hna6TAzZJvloYK9NBD5qgFJ1PQ&feature=shared).
34+
We [published a report](/open-energy-modeling/2024/09/19/open-energy-models/)
35+
summarizing energy modeling talks from all past JuMP-dev workshops. We plan to
36+
hold further sessions at the [HiGHS Workshop](https://workshop25.highs.dev) in
37+
July and [JuMP-dev 2025](/meetings/jumpdev2025/) in November.
38+
39+
## open-energy-modeling-benchmarks
40+
41+
In collaboration with energy modelers from GenX, Sienna, Tulipa, and others, we
42+
built [open-energy-modeling-benchmarks](https://github.com/jump-dev/open-energy-modeling-benchmarks).
43+
This GitHub repository is both a collection of energy-focused benchmark
44+
instances for MIP solvers, and a collection of scripts for the end-to-end
45+
profiling of JuMP-based energy modeling frameworks.
46+
47+
## Open Energy Transition
48+
49+
We have started a collaboration with [Open Energy Transition](https://openenergytransition.org)
50+
(OET) on their [solver-benchmark](https://github.com/open-energy-transition/solver-benchmark)
51+
project. In particular, we have shared our benchmark instances with them and
52+
[adopted their metadata format](https://github.com/jump-dev/open-energy-modeling-benchmarks/issues/42)
53+
for structuring benchmarks so that OET can import any future updates to our
54+
benchmarks with minimal effort. In addition, we have incorporated their
55+
benchmarks from PyPSA into our analysis of HiGHS, and we have maintained a
56+
back-and-forth dialog on how to appropriately benchmark MIP solvers. We have
57+
also chimed in on some issues for their linopy modeling framework ([linopy#402](https://github.com/PyPSA/linopy/issues/402)).
58+
59+
## Profiling
60+
61+
We used HiGHS to profile the benchmark instances from
62+
open-energy-modeling-benchmarks, OET, and Hans Mittelmann’s MIPLIB. These
63+
benchmarks revealed a significant difference between the performance of HiGHS on
64+
the general purpose MIPLIB set and the performance of HiGHS on the
65+
energy-focused models. We will have more to share publicly at a later date.
66+
67+
## Performance improvements
68+
69+
Using the initial results of our benchmarks, we have begun implementing
70+
performance improvements to HiGHS. As one example, a model from Tulipa that did
71+
not solve in a time limit of 3 hours can now be solved in 250 seconds
72+
([HiGHS#2049](https://github.com/ERGO-Code/HiGHS/issues/2049)).
73+
74+
## Critical bugs
75+
76+
Working with the developers of Sienna and Tulipa, we found and fixed a number of
77+
critical bugs in HiGHS. This included multiple segfaults
78+
([HiGHS#1990](https://github.com/ERGO-Code/HiGHS/issues/1990),
79+
[HiGHS#2109](https://github.com/ERGO-Code/HiGHS/issues/2109)), a case where
80+
HiGHS failed to detect that the problem did not have a solution
81+
([HiGHS#1962](https://github.com/ERGO-Code/HiGHS/issues/1962)), and a case where
82+
HiGHS returned an incorrect solution because the energy modeler was running with
83+
a set of non-default options in an attempt to improve performance
84+
([HiGHS#1935](https://github.com/ERGO-Code/HiGHS/issues/1935)).
85+
86+
As part of this work, we implemented a new way to debug the interaction of JuMP
87+
and HiGHS that allowed us to reproduce and fix a segfault that had been
88+
undiagnosed for one year
89+
([HiGHS.jl#258](https://github.com/jump-dev/HiGHS.jl/issues/258)).
90+
91+
## GenX
92+
93+
Working with the developers of GenX, we identified a number of possible
94+
performance improvements to the GenX codebase
95+
([GenX#773](https://github.com/GenXProject/GenX.jl/pull/773)). As a result, we
96+
made a number of changes to both GenX
97+
([GenX#815](https://github.com/GenXProject/GenX.jl/pull/815)) and JuMP
98+
([MutableArithmetics#302](https://github.com/jump-dev/MutableArithmetics.jl/issues/302)),
99+
with the result that GenX models are now 12% faster to build.
100+
101+
## Sienna
102+
103+
Working with the developers of Sienna, we identified a number of performance
104+
bottlenecks in their code and in JuMP:
105+
106+
* Saving models to disk (for later reproducibility) was a critical bottleneck
107+
in their optimization pipeline. Since this is an uncommon operation for a
108+
performance sensitive application, this code in JuMP was not optimized. We
109+
rewrote the relevant parts of JuMP
110+
([MathOptInterface#2606](https://github.com/jump-dev/MathOptInterface.jl/pull/2606),
111+
[MathOptInterface#2613](https://github.com/jump-dev/MathOptInterface.jl/pull/2613)).
112+
This lead to a 5x speedup in saving models to disk.
113+
* In addition to saving models to disk for reproducibility, Sienna also
114+
serializes the version of every package and dependency. We modified Sienna to
115+
use a faster code path
116+
([InfrastructureSystems#423](https://github.com/NREL-Sienna/InfrastructureSystems.jl/pull/423)).
117+
* Sienna performed a number of redundant computations when importing
118+
time-series data. These computations are now performed once and then caching
119+
the values for future time-steps
120+
([InfrastructureSystems#409](https://github.com/NREL-Sienna/InfrastructureSystems.jl/issues/409),
121+
[InfrastructureSystems#410](https://github.com/NREL-Sienna/InfrastructureSystems.jl/pull/410))
122+
123+
The net impact of these changes is that the time spent by Sienna outside of the
124+
HiGHS solver is reduced by half. The overall benchmark time depends on the
125+
specific model and how long HiGHS takes to solve the model. Currently, the total
126+
runtime improvement is approximately 5% faster with 15% less memory required,
127+
but this percentage will increase as HiGHS becomes faster.
128+
129+
Working with the developers of Sienna, we identified a number of common Julia
130+
and JuMP-related anti-patterns in the Sienna code base
131+
([PowerSimulations#1218](https://github.com/NREL-Sienna/PowerSimulations.jl/pull/1218)).
132+
This included unnecessary array copies when indexing, suboptimal loop order
133+
when iterating over matrices, and type stability issues when re-using variable
134+
names within a function. Although each of these issues have a minor runtime
135+
impact, their cumulative effect can be large, if hard to benchmark. Therefore,
136+
our suggested best practice is to avoid these issues in the first place. In
137+
addition to providing guidance to the Sienna developers, we will update the JuMP
138+
documentation to better highlight these anti-patterns for the benefit of all
139+
energy system developers ([JuMP#2348](https://github.com/jump-dev/JuMP.jl/issues/2348#issuecomment-2618076446)).
140+
141+
We also identified that an optional check of the input data was a critical
142+
performance bottleneck in Sienna's optimization pipeline. The check iterated
143+
over the data in HiGHS to identify common mistakes such as mis-matched units, or
144+
trivially infeasible solutions such as initial generator setpoints outside their
145+
operating bounds. The way this algorithm was implemented in HiGHS meant that the
146+
time taken increased with the square of the problem size, so larger models were
147+
particularly affected. We rewrote the algorithm so that the time taken now
148+
increases linearly with problem size and, in our initial benchmarking, the check
149+
went from taking minutes to never taking more than a few seconds
150+
([HiGHS#2114](https://github.com/ERGO-Code/HiGHS/issues/2114)). Benchmarking
151+
this in the context of an end-to-end run of Sienna will require a new release of
152+
HiGHS.
153+
154+
## Tulipa
155+
156+
Working with the developers of Tulipa, we identified a bottleneck in their model
157+
building pipeline that was caused by the informative string names of variables
158+
and constraints used when debugging. Turning off these names when not debugging
159+
led to a 30% decrease in the time taken to build the model
160+
([Tulipa#936](https://github.com/TulipaEnergy/TulipaEnergyModel.jl/pull/936)).
161+
162+
## SpineOpt
163+
164+
Working with the developers of SpineOpt, we identified an issue with their code
165+
base that leads to non-deterministic model creation
166+
([SpineOpt#1143](https://github.com/spine-tools/SpineOpt.jl/issues/1143)). This
167+
can mean that, all else equal, the same model solved on two different machines
168+
can return different solutions. This can make benchmarking and reproducibility
169+
difficult. The Spine developers are investigating.
170+
171+
## HiGHS.jl
172+
173+
The profiling of energy system models revealed that adding variables to a HiGHS
174+
model can be a bottleneck. We implemented changes to JuMP and HiGHS.jl so that
175+
adding bounded variables is now three times faster than before
176+
([HiGHS.jl#248](https://github.com/jump-dev/HiGHS.jl/pull/248)).
177+
178+
## Other changes
179+
180+
We have extended the local testing of HiGHS, making it possible to run unit
181+
tests from an external repository. The external unit tests are built with CMak
182+
and Catch2, consistent with the ones already in HiGHS. It is also possible to
183+
use private problem instances for additional checks, as we consider introducing
184+
modifications to the code. A thorough analysis of updates is very helpful as we
185+
implement more major updates to the solution algorithms. The separation of new
186+
tests from the HiGHS code allows for more comprehensive testing with no
187+
additional code shipped to the users, keeping the solver lightweight and easy to
188+
integrate within other systems.
189+
190+
The code coverage functionality in HiGHS was updated and coverage reports are
191+
now generated and uploaded to Codecov on each PR to our development and master
192+
branches ([HiGHS#2112](https://github.com/ERGO-Code/HiGHS/issues/2112),
193+
[HiGHS#2138](https://github.com/ERGO-Code/HiGHS/issues/2138)).
194+
195+
We have developed local benchmarking infrastructure for use during the
196+
development of HiGHS. Running specific test sets, we record output from the
197+
HiGHS library, as well as collecting additional debugging and development
198+
output, to test the correctness and speed of HiGHS and any potential
199+
improvements. For some of the experiment results presented here, a dedicated
200+
local server was used, with no other tasks running, required for reliable timing
201+
results. The new benchmark infrastructure will allow us to gather such results
202+
much faster, in an automated and reproducible way.

0 commit comments

Comments
 (0)