fix(gfql): graceful numpy fallback when cupy cannot JIT (NVRTC-less CUDA) - #1855
fix(gfql): graceful numpy fallback when cupy cannot JIT (NVRTC-less CUDA)#1855lmeyerov wants to merge 5 commits into
Conversation
…UDA) cudf imports and runs precompiled ops on hosts without libnvrtc, but cupy's kernel compiler -- needed by the index/count kernels' bincount and searchsorted -- raises at first use. array_namespace probes one JIT op per process and falls back to numpy host arrays for the cudf engine (col_to_array aligned): identical values, no crash. Verified on a real NVRTC-less box (3 previously-crashing cudf suite tests now pass there). Pins: forced fallback, probe run-once caching. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
|
DGX container matrix ( 🤖 Generated with Claude Code |
…ework) Scoping audit answered: on an NVRTC-less CUDA install, essentially ALL cupy compute fails (arith, comparisons, trig, astype, sort/search/ bincount) -- not just the two ops the first patch guarded -- while cudf's dataframe engine (precompiled libcudf) is fully usable. The distinction is architectural: cupy JIT-compiles elementwise kernels via NVRTC; cudf does not (its JIT is only in numba UDF paths our engine avoids). lazy_cupy_import() in utils/lazy_import.py is the one gate: available iff cupy can COMPUTE (cached probe, reason preserved). Consumers fixed: engine_arrays (private probe deleted), layout/mercator (except- ImportError could not catch the compute-time RuntimeError), layout/ ring/util (unconditional crash -> routes to its existing numpy branch). Audited safe: layout/circle (allocation APIs only), umap/ai_utils (cuml-produced arrays imply a working stack). Flagged follow-ups: cluster.py + Engine.py s_sqrt/s_arange (cuml-coupled), cudf numba-JIT expression paths (round/temporal raise GFQLTypeError on NVRTC-less boxes today, pre-existing on master). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
|
Scoping audit done — you were right that the first patch treated a symptom. Reworked: Diagnosis (measured on the NVRTC-less box): essentially ALL cupy compute fails there — arithmetic, comparisons, trig, astype, sort/search/bincount; only allocation and cub-backed Solution (library-level, not module-local):
Verification: mypy + hygiene clean; gate + fallback pins refit to the library gate and green on the NVRTC-less box; layout suites 410 green locally; the 27 local conformance failures reproduce identically on pristine master (pre-existing box artifact, green in the DGX container). Fresh container matrix queued. 🤖 Generated with Claude Code |
|
Container matrix on the gate rework ( 🤖 Generated with Claude Code |
|
Generalization follow-through, two more hazard-class members found and fixed (both repro'd on the NVRTC-less box):
Receipts: the local NVRTC-less conformance matrix goes 27 failed → 270 passed / 0 failed. mypy + hygiene clean. Container matrix re-queue waits behind the benchmark lane chain currently holding the dgx box (also still owing the 🤖 Generated with Claude Code |
Owner review: typical cudf-path code should ask ONE question. cudf_runtime_caps() bundles cudf importability + cupy compute capability (+ modules and reasons); all consumer sites switch to it, lazy_cupy_import stays as the low-level probe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
…low-through) Two more members of the runtime-capability hazard class, both repro'd and fixed on the NVRTC-less box: 1. Scalar fns (floor/ceil/round tails) applied numpy ufuncs to cudf Series -- dispatching into cupy kernel compilation -- because the legacy cuDF-native Series.floor/ceil branch died silently when cudf 26.02 removed those methods. _unary_ufunc_on_series routes through host numpy when cupy cannot compute (values identical, nulls preserved); healthy GPU stacks keep the on-device path. 2. Temporal date/time predicates called Series.dt.date/.dt.time, both removed in cudf 26.02. Day-truncated datetimes now pair with a midnight Timestamp and time-of-day timedeltas with a Timedelta -- dtype-driven pairing, engine-agnostic, exact same comparison semantics. Local NVRTC-less conformance matrix: 27 failed -> 270 passed / 0 failed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
|
Encapsulation per review: 🤖 Generated with Claude Code |
…branch CHANGELOG keeps both entries; gfql_fast_paths.py auto-merged (the projection work and the fact consult touch different regions of the count path). Verified locally: the affected suites pass apart from the 69 cudf cases that fail IDENTICALLY on origin/master here (libnvrtc.so.12 absent on this box -- #1855's territory), baselined before attributing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
The NVRTC-less-cudf follow-up from the benchmark campaign. cudf imports and runs precompiled libcudf ops on a host whose CUDA install lacks NVRTC, but cupy's kernel compiler — which the GFQL index/count kernels'
bincount/searchsortedrequire — raisesRuntimeError: CuPy failed to load libnvrtc.so.12at first use, deep inside a query.array_namespacenow probes one JIT-compiled cupy op per process (cached) and falls back to numpy host arrays for the cudf engine,col_to_arrayaligned to the same probe: identical values, host-side compute, no crash — decline-not-serve. Diagnosed empirically on a real NVRTC-less box (cudf constructs/merges/groupbys pass; cupy bincount/searchsorted raise); with the fix, the three previously-crashing cudf suite tests pass there. Pins: forced-fallback backend + array types, probe run-once caching. No new casts, no new Any (ratchets clean).For owner review.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi