Skip to content

fix(groupby): preserve grouped-dim position in groupby-sum#860

Merged
FabianHofmann merged 9 commits into
masterfrom
fix/groupby-preserve-dim-order
Jul 21, 2026
Merged

fix(groupby): preserve grouped-dim position in groupby-sum#860
FabianHofmann merged 9 commits into
masterfrom
fix/groupby-preserve-dim-order

Conversation

@FabianHofmann

Copy link
Copy Markdown
Collaborator

Note

The following content was generated by AI.

Changes proposed in this Pull Request

LinearExpression.groupby(...).sum() moved the grouped dimension to the trailing
position instead of replacing it in place, diverging from xarray's native
groupby-reduce and from linopy <= 0.8.0 (regressed in #802). assert_linequal
aligns dimension order, so existing tests missed the reorder.

Root cause: both the apply_ufunc scatter kernel (fast path) and the groupby.map
fallback append the new group dimension at the end. The LinearExpression
constructor's xr.broadcast then reorders every variable to the dataset's
canonical dim order — which is driven by coordinate-insertion order — so a plain
transpose alone doesn't stick.

The fix adds _restore_group_dim_position, applied to both paths:

  • Transposes the terms so the group dimension(s) sit where the grouped
    dimension(s) were, surviving dims keeping their relative order.
  • Reorders the dimension coordinates so the constructor's canonical order matches.
  • Leaves MultiIndex group coordinates untouched, so multikey / observed=True
    results (which are order-agnostic) are unaffected and no FutureWarning is
    emitted.

The strict xfail marker on test_linear_expression_groupby_preserves_dim_position
is removed; the test now passes for both use_fallback=False and True.

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.

FabianHofmann and others added 3 commits July 21, 2026 11:31
groupby-sum moves the group dim to the trailing position instead of
keeping the grouped dim's slot, diverging from xarray's native
groupby-reduce and linopy <= 0.8.0 (regressed in #802). Existing tests
use assert_linequal, which aligns dims and misses the reorder.

Strict xfail: remove the marker once grouping preserves dim position.
groupby-sum moved the group dim to the trailing position; both the
apply_ufunc scatter kernel and the fallback append it there, and the
LinearExpression constructor's broadcast then locks that order.

Restore the grouped dim's original slot via _restore_group_dim_position:
transpose the terms and reorder the dimension coordinates so the
constructor's canonical dim order matches. MultiIndex group coords are
left untouched (multikey/observed results stay order-agnostic).

Drops the strict xfail; adds a release note.
@codspeed-hq

codspeed-hq Bot commented Jul 21, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 173 untouched benchmarks
⏩ 173 skipped benchmarks1


Comparing fix/groupby-preserve-dim-order (8cfa6f8) with master (c2607b6)

Open in CodSpeed

Footnotes

  1. 173 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.

The dim-position transpose left coeffs/vars as non-contiguous views, so
LP/solver export had to materialise a contiguous copy on ravel (CodSpeed
flagged ~4x export memory on the nodal_balance padding benchmark).

Force numpy-backed terms C-contiguous after the reorder so downstream
flattening ravels a view. ascontiguousarray is a no-op when no reorder
moved data; dask arrays are left lazy (chunks preserved).
@FBumann

FBumann commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

@FabianHofmann Good catch, but it seems like this needs to be fixed differently to keep the memory low

FabianHofmann and others added 2 commits July 21, 2026 12:53
Make _grouped_sum emit the grouped dimension in place directly: pass all
surviving dims as core dims so apply_ufunc's output order is fully chosen,
and build the padded array with the group axis in its target slot. The
result is contiguous in a single allocation, so the downstream reorder and
contiguity coercion become no-ops (no copy).

Removes the build-memory regression from the previous force-contiguous
approach: build and export peak now match master (~10MB / ~3MB) on
nodal_balance instead of 19MB / 3MB.

Trade-off: every dim is now a core dim, so dask inputs collapse to a
single chunk (no per-surviving-dim parallelism). Kept lazy.
@FBumann

FBumann commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Ill fix the memory issue!

FBumann and others added 2 commits July 21, 2026 13:41
…parity

Inlining group_sum(data.const) into the Dataset literal made it evaluate
after the coeffs/vars scatters, stacking its nan-masking temporaries on
top of the retained padded arrays (+31% peak in expr_groupby_sum).
Reducing const first frees them before the padded arrays exist, restoring
the exact peak of master (verified with memray: 171 KB vs 275 KB).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…im's name

Restoring the group dim's position inferred the consumed dims as those
absent from the result, so a grouper named like the dim it groups (e.g.
relabelling 'name' to a coarser 'name') shadowed the consumed dim, the
restore early-returned and the dim drifted to the trailing position on
both paths. Pass the grouper's own dims (DataArray/IndexVariable dims,
Series/DataFrame index name) through _grouper_dims instead; unknown
grouper types (grouper mappings, multi-key lists under use_fallback)
keep the inference.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@FBumann

FBumann commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

@FabianHofmann fixed the memory issue in c5d08f4

@FabianHofmann

Copy link
Copy Markdown
Collaborator Author

@FBumann great, thanks!

@FabianHofmann
FabianHofmann merged commit 4711206 into master Jul 21, 2026
23 checks passed
@FabianHofmann
FabianHofmann deleted the fix/groupby-preserve-dim-order branch July 21, 2026 12:32
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.

2 participants