Skip to content

Keep only the corner mesh on CurvilinearCellIndex - #287

Open
dcherian wants to merge 1 commit into
mainfrom
dcherian/curvilinear-index-memory
Open

dcherian wants to merge 1 commit into
mainfrom
dcherian/curvilinear-index-memory

Conversation

@dcherian

@dcherian dcherian commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

CurvilinearCellIndex cached nine full-grid arrays: float64 copies of the cell centers (X, Y), the corner mesh, per-cell (min, max) of the corners along each axis, and a seam mask. Only the corner mesh is a source of truth. sel read the others for a narrow band of rows.

This PR keeps the corner mesh and drops the rest:

  • _lat_mask_for_rows derives per-cell bounds and the seam mask from the corner band it needs, using the existing _cell_min_max helper.
  • The 1D per-row lat bounds (row_y_min, row_y_max) come from 1D reductions of the corner rows.
  • sel reads the grid shape from the corner mesh. equals compares corner meshes.

The constructor signature does not change.

Context

The tiles service for esip-workshop-2026 OOM-killed on the root request for a global 1/12° RTOFS dataset (3298 × 4500 cells, float32 lat/lon). Grid detection alone retained 0.96 GB and peaked at 1.7 GB on a 2 GiB pod that already held another dataset.

Measured on a synthetic grid of that shape:

Before After
Retained on the index 0.96 GB 0.24 GB
Peak during detection 1.72 GB 1.34 GB
sel for one tile 6 ms

Peak is still dominated by the float64 casts in Curvilinear.from_dataset and the two-pass infer_interval_breaks. Keeping the input dtype for the corner mesh would roughly halve both numbers again. I left that for a separate PR so a precision regression is easy to bisect.

Tests

  • tests/test_grids.py: 390 passed.
  • Full suite: 241 passed. Two Hypothesis property tests fail (test_property_global_render_no_transparent_tile on HEALPix, test_rectilinear_triangular_equivalency). Neither exercises the curvilinear index, and replaying the same falsifying examples against main fails identically, so they are pre-existing.
  • ruff, ty, and pre-commit pass.

[This is Claude Code on behalf of Deepak Cherian]

🤖 Generated with Claude Code

The index cached nine full-grid arrays: float64 copies of the cell
centers, the corner mesh, per-cell (min, max) of the corners along
each axis, and a seam mask. Only the corner mesh is a source of
truth. The rest were read by `sel` for a narrow band of rows.

Drop the cached centers, per-cell bounds, and seam mask. `sel` now
derives per-cell bounds from the corner band it needs. The 1D per-row
lat bounds come from 1D reductions of the corner rows.

On a 3298x4500 curvilinear grid (RTOFS global 1/12 degree) this cuts
retained index memory from 0.96 GB to 0.24 GB and peak memory during
grid detection from 1.7 GB to 1.3 GB. `sel` for a tile costs ~6 ms.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.43%. Comparing base (d00c1a2) to head (c65ce38).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #287   +/-   ##
=======================================
  Coverage   81.42%   81.43%           
=======================================
  Files          31       31           
  Lines        6542     6538    -4     
=======================================
- Hits         5327     5324    -3     
+ Misses       1215     1214    -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

1 participant