Repository navigation
perf: dense fast paths in the core and a faster spec build - #1078
Merged
Merged
Conversation
Store/expression/model fast paths skip alignment and copies on shared coordinates. from_spec reuses evaluated nodes, skips constraints whose where keeps no row, and groups dense sum-by in numpy.
Merging this PR will improve performance by ×2.71 warning
Performance Changes
Tip Curious why performance improved? Comment Comparing |
on_cells, laid_on, transposed, coords_within, DenseStore._own and DenseStore.normalized replace the per-site copies; to_constraint moves its numpy step into DenseStore.moved. Drop the unreachable helper-dim guard in where and tune the _stacked slab copy to two terms. Document the three dense-store conventions in contributing.rst.
A scalar sign, scaling or rhs on a constraint grid is a stride-0 view again, as on master, rather than a filled array. The dense to_constraint computes the moved constant once instead of negating a copy. Peak memory of con_le_array drops from 299 KB to 138 KB locally.
1 of 2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following content was generated by AI.
Follow-up to #958.
Changes proposed in this Pull Request
Speeds up model building on the dense path, both for linopy's core and for
Model.from_spec.Core (dense store, expressions, model)
DenseStore/mergegain fast paths that skip xarray alignment,Datasetconstruction and copies when operands already share their coordinates.Variableto expression conversion, constant arithmetic,whereand subtraction onLinearExpressionuse these paths.add_variablesandadd_constraintsallocate labels and check infinities and masks in numpy.on_coordsinlinopy/store.pybuilds a dataset from fields on given coordinates with the publicDatasetconstructor, reusing the coordinates' indexes. The dataset dims follow the field layout, soexpr.expand_dims("new").coord_dimsnow listsnewfirst.Spec builder
where:keeps no row is skipped before its sides are evaluated. It adds no constraint group and reserves no labels. Itsdual(...)reads as all NaN.sum(..., by=...)on a dense linear expression groups in numpy. The result is identical to thegroupby().sum()path, including dim and term order.Behaviour change: fully masked spec constraints no longer appear in
model.constraints, and later constraints are numbered consecutively. On the PyPSA spec the LP differs from the previous output only in constraint row numbers. This was checked by mapping old labels to new ones.Results (PyPSA spec, minimum build time)
create_model, same corePyPSA's own
create_modelalso builds about twice as fast on this core (0.87 s → 0.44 s small). The remaining gap to PyPSA comes from the spec's larger number of constraint groups (122 vs 24) and per-operation xarray overhead.Core memory. The first push of this PR raised peak memory on the core micro-benchmarks, e.g.
kvl_cycles87.7 MB → 121.5 MB. The cause wasVariable._dense_term. It builtconstandcoeffswithnp.whereeven when no label was absent, where master kept stride-0 broadcast views until the next reduction. It now keeps the views when no label is absent:kvl_cyclesbuildsparse_networkn=250var_mul_array_bcast(local
tracemallocpeak and best-of-5 time)A constraint built as
2 * x >= 4now holds read-only coefficient arrays, as master already did for broadcast cases such asa * xwith a new dim or(flow * C).sum(...). Raw in-place writes likec.coeffs.values[...] = ...stay unsupported and now raise there.test_preview_detects_raw_mutation_apply_skips_itreplaces the array instead of writing into it.test/test_repr.pynow builds the transposed-dataset fixture with integer coefficients. That keeps it on the generic path the test is about, rather than the new float fast path.Checklist
AGENTS.md).doc.doc/release_notes.rstof the upcoming release is included.