Skip to content

Feature: netcdf chunked reads - #984

Merged
hellkite500 merged 3 commits into
NOAA-OWP:masterfrom
hellkite500:split/netcdf-chunked-reads
Jun 26, 2026
Merged

Feature: netcdf chunked reads#984
hellkite500 merged 3 commits into
NOAA-OWP:masterfrom
hellkite500:split/netcdf-chunked-reads

Conversation

@hellkite500

Copy link
Copy Markdown
Contributor

This is the core of #944 after factoring out #982 and #983. The 18 remaining commits were logically grouped into the 6 on this branch. Note that this is based on the HEAD of #982 currently, will need rebased once that merges.

Additions

  • Catchment-id hinting (hint_shared_provider_id) so the provider reads only the catchments a simulation requests, not every feature in the file.
  • A time-dimension value cache that reads a span of time slices per access instead of repeated single-step reads.
  • align_cache_with_chunks() to size the cache from the variable's on-disk chunking when present.
  • Unit tests for the chunked/hinted read paths (...UsingIds, ...Span, ...MultiSpan, etc.).

Removals

  • Reading all features in the file regardless of the simulation domain — only required catchments are now read.
  • The default constructor (= delete) — there is no valid un-parameterized provider.

Changes

  • get_value reworked to read through, and serve from, the chunked time-dimension cache.
  • Cache size expressed as a named const (N_EXPECTED_FORCING_VARS) rather than a magic number.

Testing

  1. All netcdf provider tests pass locally

Known issue: cache sizing

Per @PhilMiller's profiling note on #944: the cache is currently sized to match the working set. A functional cache needs to be larger than the working set — a request spanning more than one time step will thrash an exactly-matched cache. Carried over from #944.

Coordination

Checklist

  • PR has an informative and human-readable title
  • Changes are limited to a single goal (no scope creep)
  • Code can be automatically merged (no conflicts)
  • Code follows project standards
  • Passes all existing automated tests
  • Any change in functionality is tested
  • New functions are documented
  • Placeholder code is flagged / future todos are captured in comments
  • Project documentation has been updated (CHANGELOG "Unreleased")
  • Reviewers requested

Target Environment support

  • Linux
  • MacOS

aaraney and others added 2 commits June 26, 2026 13:50
The feature enables reading chunks of netcdf variable values instead of
reading all values for a given variable. A 'hint_shared_provider_id'
method is added that enables 'hinting' to a provider one of the id's
that it must provide. this method can be repeatedly called to add
necessary catchments. the netcdf provider keeps a set of the id's that
have been hinted and rebuilds it's chunking index on the first timestep
which is used to read only the necessary data.

I am not satisfied with the hinting approach, but it gets the job done
for now. Alternative approaches are:

- pass down list of catchments when constructing a provider. This would
  require a lot of refactoring and extra fiddling that is currently not
  required.
  - or, create the shared forcing provider from all the id's and pass
    that down. has the same issues as described.
- include the catchment-id to the factory forcing provider. This would
  enable this functionality but transparently.

Co-authored-by: hellkite500 <nfrazier@lynker.com>
First cut at caching across the Time dimension in the netcdf data
provider. We now cache 18 time slices when we read from disk. The access
pattern in for each netcdf variable: n sim catchments x 18.

I found in a crude runtime analysis on a HF with 160 divides simulating
over the periods of 1 month _and_ 1 year that 18 was the sweet spot on
my M2 Pro w/ 10 cpu & 32 GiB ram. This is for sure a tunable parameter
that _seems_ highly dependent on how variables in your HDF5 enabled
netcdf file are chunked and if they are compressed.

Co-authored-by: hellkite500 <nfrazier@lynker.com>
@hellkite500
hellkite500 force-pushed the split/netcdf-chunked-reads branch from 0846019 to 8cb46f1 Compare June 26, 2026 19:55
aaraney
aaraney previously approved these changes Jun 26, 2026

@aaraney aaraney 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 good to me!

if(cache_slice_t_size > num_times){
cache_slice_t_size = num_times;
}else if(cache_slice_t_size <= 0){
cache_slice_t_size = 24; // default to 24 if no chunking info found

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think this case can ever be hit, because there's the in-class initializer cache_slice_t_size = 18;. Did you mean to change that to = 0 when you added this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed and squashed.

const std::string& var_name = var_pair.first;
auto var = var_pair.second;
// Skip the Time variable itself and ids, look for data variables with at least 2 dimensions
if (var_name == "Time" || var_name == "ids" || var_name == "catchment-id" || var.getDimCount() < 2) continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think the DimCount check covers all of this?

@PhilMiller PhilMiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm concerned about cache_slice_t_size as noted above

Co-authored-by: Austin Raney <austin.raney@noaa.gov>
@hellkite500
hellkite500 merged commit 74998c3 into NOAA-OWP:master Jun 26, 2026
22 checks passed
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.

3 participants