You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Task graphs on .map_blocks with many chunks can be huge #8409
I'm getting task graphs > 1GB, I think possibly because the full indexes are being included in every task?
What did you expect to happen?
Only the relevant sections of the index would be included
Minimal Complete Verifiable Example
da=xr.tutorial.load_dataset('air_temperature')
# Dropping the index doesn't generally matter that much...len(cloudpickle.dumps(da.chunk(lat=1, lon=1)))
# 15569320len(cloudpickle.dumps(da.chunk().drop_vars(da.indexes)))
# 15477313# But with `.map_blocks`, it really matters — it's really big with the indexes, and the same size without:len(cloudpickle.dumps(da.chunk(lat=1, lon=1).map_blocks(lambdax: x)))
# 79307120len(cloudpickle.dumps(da.chunk(lat=1, lon=1).drop_vars(da.indexes).map_blocks(lambdax: x)))
# 16016173
MVCE confirmation
Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
Complete example — the example is self-contained, including all data and the text of any traceback.
Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
New issue — a search of GitHub Issues suggests this is not a duplicate.
Recent environment — the issue occurs with the latest version of xarray and its dependencies.
Relevant log output
No response
Anything else we need to know?
No response
Environment
Details
INSTALLED VERSIONS
commit: None
python: 3.9.18 (main, Aug 24 2023, 21:19:58)
[Clang 14.0.3 (clang-1403.0.22.14.1)]
python-bits: 64
OS: Darwin
OS-release: 22.6.0
machine: arm64
processor: arm
byteorder: little
LC_ALL: en_US.UTF-8
LANG: None
LOCALE: ('en_US', 'UTF-8')
libhdf5: 1.12.2
libnetcdf: None
changed the title [-]Huge task graphs on `.map_blocks` with many chunks[/-][+]Task graphs on `.map_blocks` with many chunks can be huge[/+]on Nov 3, 2023
Quick question re a workaround, if anyone knows off-hand — would creating the job from a delayed task get around this?
My (low-confidence) understanding is that there are two downsides of big task graphs:
A task graph that's huge in number of tasks, even though each task is small. This slows the scheduler down because it has to process the graph.
A task graph that contains big objects, even though there aren't many tasks. This requires sending big objects to the scheduler. But possibly if the job is created from a worker, then the objects are already tracked by the scheduler, and it doesn't need to transfer them?
I've generally had a lot of trouble with the first, so have been trying to increase chunk size and break jobs into multiple sections (and using rechunker to avoid rechunking within a job, thanks rechunker!). But is this a case of the 2nd?
A bit late to the conversation here but ... I've had some success in this arena by telling dask to use the threaded or synchronous scheduler within the map-blocks function. It ends up looking like this:
I'm seem to remember folks telling me this was a bad idea but it made sense for my applications where I wanted to think about my arrays inside my function as numpy-arrays, not dask-arrays.
Activity
[-]Huge task graphs on `.map_blocks` with many chunks[/-][+]Task graphs on `.map_blocks` with many chunks can be huge[/+]dcherian commentedon Nov 3, 2023
They should be getting subset here:
xarray/xarray/core/parallel.py
Line 421 in 83fbcf0
It's possible that index vars are getting duplicated a bunch, since they're "broadcast" out to every chunk. We might be able to be clever here.
dcherian commentedon Nov 3, 2023
Yes that's exactly what's happening 🤦🏾♂️
The
timevector is included in the graph 18 times, even though there is only a single chunk along thetimedimensionsMinimize duplication in `map_blocks` task graph
dcherian commentedon Nov 3, 2023
The other piece of duplication is here:
xarray/xarray/core/parallel.py
Lines 497 to 500 in 83fbcf0
If I comment that out, I get close to the expected size with no indexes
max-sixty commentedon Dec 8, 2023
Quick question re a workaround, if anyone knows off-hand — would creating the job from a
delayedtask get around this?My (low-confidence) understanding is that there are two downsides of big task graphs:
I've generally had a lot of trouble with the first, so have been trying to increase chunk size and break jobs into multiple sections (and using rechunker to avoid rechunking within a job, thanks rechunker!). But is this a case of the 2nd?
jhamman commentedon Dec 8, 2023
A bit late to the conversation here but ... I've had some success in this arena by telling dask to use the threaded or synchronous scheduler within the map-blocks function. It ends up looking like this:
I'm seem to remember folks telling me this was a bad idea but it made sense for my applications where I wanted to think about my arrays inside my function as numpy-arrays, not dask-arrays.
dcherian commentedon Dec 15, 2023
#8412 is the right solution here IMO.
Minimize duplication in `map_blocks` task graph
Minimize duplication in `map_blocks` task graph (#8412)
Share map_blocks coordinate tasks across calls
Share map_blocks coordinate tasks across calls