dask.array.reductions.nanquantile never dispatches float32 input to numbagg, forcing a much slower fallback
Maintainers usually reply within 3 days
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- numpy, python
- Domain
- data, performance
Research direction
Start in dask.array.reductions.nanquantile and inspect the dispatch condition choosing _numbagg_nanquantile versus _custom_nanquantile. Run the minimal float32 and float64 reproduction from the issue, then verify that float32 selects numbagg, preserves the expected quantile results, and avoids the slower fallback.
Written by the indexing model from the issue text.
Description
What we're seeing
dask.array.reductions.nanquantile's dispatch condition only routes to numbagg's nanquantile (GIL-releasing) when the input array is float64 or int:
if (
HAS_NUMBAGG
and (a.dtype.kind in "ui" or a.dtype == np.float64)
and q_arr.dtype == np.float64
...
):
func = _numbagg_nanquantile
else:
func = _custom_nanquantile
float32 input unconditionally falls back to _custom_nanquantile. now numbagg doesn't have an optimised float32 version, but it does happily haldle float32 (NumPy/numba's generic ufunc casting silently upcasts to match the declared signature).
Why it matters
without numbagg, we fall back on _custom_nanquantile. That's slower, and most importantly, holds the GIL much more ~29.6% GIL-free vs. numbagg's ~63.4%.
Casting the array to float64 immediately before the quantile call (and back to float32 after) recovered numbagg dispatch and measured 29–43% faster wall clock and lower GIL contention on our workload, with no functional downside — but it would be much cleaner to just allow dask to dispatch float32 to numbagg.
Question / ask
Could we relax the dispatch condition to also route float32 arrays to numbagg? I'm happy to handle submitting a PR if this is something that would be accepted.
Versions: numbagg 0.9.4
Minimal repro:
import numpy as np, dask.array as da
x32 = da.from_array(np.random.default_rng(0).uniform(size=(20, 1000)).astype(np.float32), chunks=(20, 500))
x64 = x32.astype(np.float64)
# Confirm which function actually runs, e.g. via a quick monkeypatch/profile of
# dask.array.reductions._numbagg_nanquantile vs _custom_nanquantile
da.nanquantile(x32, 0.5, axis=0).compute() # -> _custom_nanquantile
da.nanquantile(x64, 0.5, axis=0).compute() # -> _numbagg_nanquantile
- Dominant language
- Python
- Stars
- 13.9k
- Forks
- 2k
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 1
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dask/dask
-
`dask.array.map_overlap` doesn't produce known chunks with `chunks=None`Possibly taken @AnthonyOlakangil claimed this 3 days ago. Openneeds triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 3 days
-
__version__ resolves to "unknown" when installed via conda due to missing __commit_id__ in _version.pyPossibly taken @ump45nose claimed this 39 days ago. Openneeds attention needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 3 days
-
needs attention needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 3 days
-
Implicit re-exports in `__init__.py`Possibly taken @JeppeKlitgaard claimed this 82 days ago. Openneeds attention needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 3 days
-
dask-expr bug: `dd.drop([], axis=1)` raises `ValueError`Possibly taken @saket3395 claimed this 79 days ago. Openneeds attention needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 3 days
Similar issues
-
documentation good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
drevendev/HungryCrab#273 ·
Maintainers usually reply within 1 day
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
drevendev/BeautifulRepo#19 ·
Maintainers usually reply within 2 days
-
Moonshot: Kimi K3 always sends `reasoning_effort="max"`, though the API now accepts `low` and `high`Openaccepted
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
UKGovernmentBEIS/inspect_ai#5939 ·
Maintainers usually reply within 1 day
-
bug linux
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
area:data data-quality
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
reacher-z/Awesome-CUA#1468 ·
Maintainers usually reply within 1 day