Skip to content

Model.store_cls construction seam, Store.to_sparse(reason) for mixed merges (#1045) - #1056

Merged
FabianHofmann merged 8 commits into
masterfrom
store/3-construction-seam
Oct 23, 2026
Merged

FabianHofmann merged 8 commits into
masterfrom
store/3-construction-seam

Conversation

@FabianHofmann

Copy link
Copy Markdown
Collaborator

Note

The following content was generated by AI.

Stacked on #1052 (step 2b); base switches to master once #1052 is merged. Step 3 of #1019.

Closes #1045.

Changes proposed in this Pull Request

  • Model.store_cls (DenseStore or CSRStore) is the single construction seam. Variable.to_linexpr, groupby(...).sum() and @/dot build on it through the store classmethods from_labels, from_grouper and the new from_matmul; the netcdf reader builds each linear expression through it, so a named expression of a sparse model reads back sparse unless it carries coordinates the sparse grid cannot hold, in which case it stays dense.
  • Variable.to_linexpr loses its private _dense parameter. Quadratic products, rolling and cumsum build the dense expression explicitly through DenseStore.from_labels, without a notice.
  • Store.to_sparse(reason) returns CSRStore | Reason: a dense store with coordinates the grid cannot hold refuses with coordinates the Grid cannot hold: <names> instead of dropping them. A mixed merge converts its dense operands through it and emits one Dense backing sparsified: merge with a sparse operand notice under warn_on_densify, only once the sparse merge succeeds; a refusal makes the whole merge dense with the named reason. A dense-only merge stays dense also in a sparse model. @ on a dense operand with such coordinates now keeps them on the dense path instead of dropping them.
  • Dense groupby of a dense model stays on the xarray path: routing it through DenseStore.from_grouper changed dask laziness and aux-coordinate handling.
  • Tests: conformance rows for mixed merges (sparse operand pulls sparse with one notice, dense operands around a sparse one, dense-only stays dense, dense operand with a 2-D coordinate falls back with the named reason, non-unique labels after conversion emit only the densify notice); to_linexpr returns the model's store class; netcdf round trip on both backends with and without a 2-D coordinate; matmul keeping a 2-D coordinate; Store.to_sparse refusal and notice.

Checklist

  • AI-generated content is marked (see AGENTS.md).
  • Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in doc.
  • Unit tests for new features were added (if applicable).
  • A note for the release notes doc/release_notes.rst of the upcoming release is included.
  • I consent to the release of this PR's code under the MIT license.

Base automatically changed from store/2b-fallbacks to master October 23, 2026 09:07
@FabianHofmann
FabianHofmann force-pushed the store/3-construction-seam branch from 3545b55 to 8add12a Compare October 23, 2026 09:12
@FabianHofmann
FabianHofmann marked this pull request as ready for review October 23, 2026 09:12
@codspeed

codspeed Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 181 untouched benchmarks
⏩ 181 skipped benchmarks1


Comparing store/3-construction-seam (c9c3bd3) with master (9a67427)

Open in CodSpeed

Footnotes

  1. 181 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

…sence

Restores the peak memory of to_linexpr on dense models to master:
no broadcast, no always-present const array, no absorb_absence pass.
… construction

A constant op producing NaN (0*inf, 0/0, inf-inf) at a live cell raises
ValueError on both stores instead of reading it as absence; sparse /0
emits no numpy warnings. _set_data absorbs absence so a dataset with
terms under a NaN const or a vars assignment cannot revive a cell.
@FabianHofmann
FabianHofmann merged commit b45f1ad into master Oct 23, 2026
22 checks passed
@FabianHofmann
FabianHofmann deleted the store/3-construction-seam branch October 23, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Model.store_cls as the construction seam; Store.to_sparse(reason) for mixed operands

1 participant