Skip to content

Add LLC CPU data canonicalization - #670

Merged
fomo-bot merged 22 commits into
mainfrom
llc-stack-03-llc-cpu-canonicalization
Jul 24, 2026
Merged

Add LLC CPU data canonicalization#670
fomo-bot merged 22 commits into
mainfrom
llc-stack-03-llc-cpu-canonicalization

Conversation

@jder

@jder jder commented Apr 8, 2026

Copy link
Copy Markdown
Member

Add LLC data support (preprocessing, etc). Brings time configuration down into the data source since LLC data has different time formats than OM4, and we likely want to use different time ranges even for different resolutions of OM4 data.

It looks big but a lot of it is mechanical config changes and tests; happy to walk through live and/or break up further if desired!

@jder jder mentioned this pull request Apr 8, 2026
@oa-jder-bot
oa-jder-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 509b762 to 91815a4 Compare April 8, 2026 20:01
@oa-jder-bot
oa-jder-bot force-pushed the llc-stack-02-dataset-specs branch from d201ce9 to 8aa8e76 Compare April 8, 2026 21:07
@oa-jder-bot
oa-jder-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 91815a4 to 7440baa Compare April 8, 2026 21:07
@fomo-bot
fomo-bot force-pushed the llc-stack-02-dataset-specs branch from 8aa8e76 to d738b00 Compare April 13, 2026 15:22
@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch 4 times, most recently from 6aa69de to 35caa19 Compare April 15, 2026 21:12
@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch 2 times, most recently from a21e9c9 to 4276e4a Compare April 22, 2026 19:42
@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 4276e4a to 5c2d900 Compare April 29, 2026 18:19
Base automatically changed from llc-stack-02-dataset-specs to main April 30, 2026 18:48
@jder

jder commented May 7, 2026

Copy link
Copy Markdown
Member Author

@fomo-bot can you please rebase this PR into a single clean commit on top of the latest main?

@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 5c2d900 to 47d5ed9 Compare May 7, 2026 14:16
@fomo-bot

fomo-bot commented May 7, 2026

Copy link
Copy Markdown
Collaborator

Done. PR #670 is now a single commit on top of latest main:



47d5ed9e Add LLC CPU data canonicalization



I force-pushed with lease to llc-stack-03-llc-cpu-canonicalization. Local validation passed:



uv run pytest tests/test_config.py tests/test_utils_data.py -m "not manual and not cuda"

37 passed, 1 warning.



GitHub checks have started and were still queued when I checked.

Codex work

Codex transcript

- I’ll inspect the current branch state, fetch the latest base branch, then squash the PR changes into one commit and update the remote branch with a lease-protected force push.
- The branch is clean and the PR targets `main`. I see the PR history includes several older stack commits plus merge commits, so I’m fetching `origin/main` now and will squash the actual branch diff against the fresh base rather than preserving that noisy ancestry.
- I’m going to keep a local backup ref at the current branch tip, then replay only the three LLC canonicalization commits onto `origin/main`. That should avoid carrying the old pre-merge dataset-spec history into the rewritten PR.
- The replay onto latest `origin/main` completed without conflicts. I’m checking the rewritten history and staged diff now before collapsing it to one commit.
- The rebased branch now has exactly the three LLC commits on top of current `origin/main`, with a five-file diff. I’m squashing those into a single commit named after the PR.
- The branch is now one local commit on top of current `origin/main`. I’m going to run a focused validation on the affected config/data tests before pushing the rewritten branch.
- `uv` had to create the local virtualenv, so the focused pytest run is still in progress. I’ll wait for that result before updating the remote branch.
- The focused tests passed: 37 tests in `tests/test_config.py` and `tests/test_utils_data.py`. I’m doing a final status check, then I’ll force-push with lease to update the PR branch.
- The force-with-lease push succeeded, updating the PR branch from `5c2d9008` to `47d5ed9e`. I’m verifying GitHub now reports the PR as a single commit on the rewritten branch.
- Done. PR #670 is now a single commit on top of latest `main`:

`47d5ed9e Add LLC CPU data canonicalization`

I force-pushed with lease to `llc-stack-03-llc-cpu-canonicalization`. Local validation passed:

`uv run pytest tests/test_config.py tests/test_utils_data.py -m "not manual...[truncated]

@jder

jder commented May 29, 2026

Copy link
Copy Markdown
Member Author

@fomo-bot can we unify the two different mock LLC datasets in tests, please?

I also don't really understand all the complexity around the time stuff. Why do we need to change slice if we are already remapping the times in the canonicalize function?

@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 47d5ed9 to 0d2e5f3 Compare May 29, 2026 18:50
@fomo-bot

Copy link
Copy Markdown
Collaborator

Done and pushed.



The PR is still a single commit, now rebased onto current origin/main:



0d2e5f36 Add LLC CPU data canonicalization



I unified the LLC test data in tests/llc_fixtures.py and removed the generic numeric-time DataSource.slice changes from data.py. The LLC path now relies on canonicalize_llc_datasets to remap raw LLC times to Julian cftime, so slice stays on the existing xarray label-slice path.



Local checks passed:



uv run pytest tests/test_config.py tests/test_utils_data.py -m "not manual and not cuda"

uvx pre-commit run --files ...



GitHub checks are running; a couple of data jobs had already passed when I checked, with the longer CI jobs still in progress.

Codex work

Codex transcript

- I’ll inspect the current test helpers and the LLC canonicalization path first, then simplify the tests and the time handling where the code proves it’s redundant.
- The local branch is clean, but the local `origin/main` ref is stale enough that its comparison is misleading. I’m going to fetch current refs before editing so this cleanup lands on the actual current PR state.
- `main` has moved six commits since this PR was last rebased. I’m going to make the requested cleanup against the PR diff, then rebase the single commit onto current `origin/main` if the touched files still merge cleanly.
- I found the duplication: one LLC fixture writes zarr/netcdf in `test_config.py`, while another builds an in-memory copy in `test_utils_data.py`. I’m moving that to one shared test helper, and I’m reverting the generic `DataSource.slice` time-coordinate coercion so LLC time no...[truncated]
- The code now leaves `DataSource.slice` on the existing xarray label-slice implementation and keeps only the LLC-specific time conversion in `canonicalize_llc_datasets`. I’m checking formatting/import fallout before running the focused tests.
- `ruff` is not installed in this uv environment, so I’ll rely on `git diff --check` plus the focused pytest run for now. The cleanup is otherwise syntactically small: the new shared helper is untracked until I stage/amend.
- The focused tests pass with the shared fixture and without the generic numeric-time slice path. I’m amending the single PR commit now, then rebasing that one commit onto today’s `origin/main` because the PR is currently behind.
- The rebase onto current `origin/main` completed without conflicts. I’m rerunning the focused tests on the rebased commit and checking the final one-commit shape before pushing.
- The rebased focused tests pass. `pre-commit` is not installed in the project environment, so I’m trying it through `uvx` to catch the CI pre-commit checks before I push.
- The pre-commit run has passed ruff, formatting, YAML, and basic file checks; it is currently on mypy. I’ll let it finish because this is the same class of check that previously failed on the PR.
- Pre-commit passed on the touched files, including reuse/license lint. I’m force-pushing the rewritten one-commit branch with lease now.
- The branch was updated on GitHub from `47d5ed9e` to `0d2e5f36`. I’m verifying the PR metadata and check status now.
- GitHub checks are running now. I started a short watch to catch any immediate failures, but I won’t block on the longer EC2/GPU jobs unless they fail quickly.
- Done and pushed.

The PR is still a single commit, now rebased onto current `origin/main`:

`0d2e5f36 Add LLC CPU data canonicalization`

I unified the LLC test data in [tests/llc_fixtures.py](/home/fomo-bot/oa-jder-bot/worktrees/github.com/Open-Athena/Ocean_Emulator/670/tests/ll...[truncated]

Comment thread src/ocean_emulators/utils/data.py Outdated
@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 0d2e5f3 to dece93c Compare May 29, 2026 20:22
Comment thread src/ocean_emulators/utils/data.py Outdated
@jder

jder commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

@fomo-bot can you rebase this on the latest main please

@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from fc087cd to d304b25 Compare July 15, 2026 18:05
@fomo-bot

Copy link
Copy Markdown
Collaborator

Rebased PR branch llc-stack-03-llc-cpu-canonicalization onto latest origin/main (8fe8b080) and pushed it with --force-with-lease.

New branch head: d304b256

Validation:

  • uv run pytest for the LLC-specific tests: 5 passed
  • uv run --with ruff ruff check ...: passed
  • Broader focused pytest run had 156 passed and 12 errors, all from missing optional flash_perceiver dependency when perceiver_implementation=auto selected flash.
Debug info

@jder
jder marked this pull request as ready for review July 15, 2026 20:31
@fomo-bot
fomo-bot force-pushed the llc-stack-03-llc-cpu-canonicalization branch from 379d3ab to 16a2638 Compare July 16, 2026 19:09
@jder

jder commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

@fomo-bot please fix precommit

@jder
jder requested a review from alxmrs July 16, 2026 20:12
@fomo-bot

Copy link
Copy Markdown
Collaborator

Fixed pre-commit and pushed b6df79a9.

The failure was ruff-format; it reformatted one line in src/samudra/utils/data.py.

Verification:

  • uv run --with pre-commit pre-commit run --all-files: passed
  • Branch is clean and synced with origin/llc-stack-03-llc-cpu-canonicalization.
Debug info

@alxmrs alxmrs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really great! I mostly have questions about factoring (where to put the new things), and then some conversations with myself to understand the PR.

Thanks for this change, this is really valuable.

Comment thread configs/data/llc.yaml
Comment thread configs/samudra_multi_om4/eval.yaml
Comment thread src/samudra/utils/data.py Outdated

if TYPE_CHECKING:
from samudra.config import TimeConfig
from samudra.config import SourceTimeConfig

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there also a non-source TimeConfig that we're keeping around? If not, then should we just keep the name "TimeConfig"? WDYT?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, makes sense.

Comment thread src/samudra/utils/data.py Outdated
)


def _rename_llc_level_index_vars(ds: xr.Dataset) -> xr.Dataset:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope there are roundtrip tests for these. Nice to see a function and its inverse.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add.

Comment thread src/samudra/utils/data.py Outdated
return mask_vars


def canonicalize_llc_datasets(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea: should we start to create data source specific utility files? e.g. keep data.py generic, and then separate out OM4 vs llc specific utilities? This might help us create better abstractions later on.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also do this after one more dataset gets added (to channel my inner YAGNI).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we're fairly close to creating new overridable abstract methods in DatasetSpec for these kinds of functions, but not quite yet.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this somewhat exists in config.py. Nice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I can break out the LLC-specific stuff.

Comment thread src/samudra/config.py
Comment thread src/samudra/config.py
Comment thread src/samudra/train.py
Comment thread tests/llc_fixtures.py
Comment thread tests/test_utils_data.py
Co-authored-by: Alex Merose <alex@openathena.ai>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee56e6c977

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/samudra/config.py
Comment on lines +241 to +242
train=source.slice(self.train_time),
val=source.slice(self.val_time),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid train/val slicing during eval-only builds

For eval-only runs whose data source contains only the configured inference period, Eval.__init__ calls cfg.data.build() and then only consumes data_container.inference_source, but this return path now slices the train and validation windows for every source first. Because DataSource.slice() raises when those windows are outside the store, standalone evaluation fails before reaching inference even though the train/val splits are unused; defer these slices to training or let eval build just the inference source plus unsliced source metadata.

Useful? React with 👍 / 👎.

@jder

jder commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

@alxmrs I think I did all the things above, RFAL!

@jder jder mentioned this pull request Jul 22, 2026

@alxmrs alxmrs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks!

@jder
jder enabled auto-merge July 22, 2026 22:52
@jder
jder disabled auto-merge July 22, 2026 23:46
…canonicalization

# Conflicts:
#	src/samudra/train.py
#	tests/conftest.py
#	tests/test_datasets.py
@jder
jder force-pushed the llc-stack-03-llc-cpu-canonicalization branch from ba58035 to 1c26183 Compare July 23, 2026 00:12
@jder
jder enabled auto-merge July 23, 2026 00:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c26183151

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/samudra/utils/llc.py

n_levels = data_copy[name].sizes["lev"]
expected_levels = len(dataset_spec.depth_i_levels)
if n_levels != expected_levels:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Select requested LLC levels instead of rejecting full-depth stores

When a raw LLC store contains more k/lev levels than the model spec consumes (for example a full-depth root while single_1 only needs Theta_0), this equality check raises before any requested level can be selected. That makes otherwise usable LLC data/configs fail during canonicalization; flatten the configured level indices and only error when a needed level is missing.

Useful? React with 👍 / 👎.

Comment thread src/samudra/utils/llc.py
Comment on lines +121 to +123
requested_data_vars.update(
[dataset_spec.mask_all_levels_var, "mask_c", *dataset_spec.mask_vars]
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep hFacC as a center wet-mask fallback

When an LLC store uses hFacC for tracer-cell wetness—the center-grid counterpart to the hFacW/hFacS fallbacks handled below—this whitelist drops it before the rename to wetmask, so flatten_masks() later cannot build wetmask_* and LLC loading fails. Include hFacC and rename it like mask_c for stores that do not already provide mask_c.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fomo-bot can you please verify if our LLC mock data includes hFacC? If it does, please fix this comment. Either way let's then get this merged.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified: the LLC mock fixture includes mask_c, hFacW, and hFacS, but not hFacC, so I did not change the comment.



PR #670 was approved, checks passed, and I added it to the merge queue. It merged successfully at 2026-07-24T13:31:33Z: #670

Debug info

@jder
jder disabled auto-merge July 23, 2026 00:25
@fomo-bot
fomo-bot added this pull request to the merge queue Jul 24, 2026
Merged via the queue into main with commit e68ca1a Jul 24, 2026
20 checks passed
@fomo-bot
fomo-bot deleted the llc-stack-03-llc-cpu-canonicalization branch July 24, 2026 13:31
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.

4 participants