|
| 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