Skip to content

fix(gfql): the fused grouped-aggregate lane keeps the group_by plan on the GPU target (#2064) - #2066

Closed
lmeyerov wants to merge 1 commit into
masterfrom
fix/gfql-2064-fused-count-groupby
Closed

fix(gfql): the fused grouped-aggregate lane keeps the group_by plan on the GPU target (#2064)#2066
lmeyerov wants to merge 1 commit into
masterfrom
fix/gfql-2064-fused-count-groupby

Conversation

@lmeyerov

@lmeyerov lmeyerov commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Closes the fused-lane half of #2064. Independent of the release stack (base master).

What it was. Not a dtype and not a GPU capability gap in our checks: the fused single-hop grouped-aggregate lane's low-cardinality count(*) alternative lowers to col(key).value_counts() + unnest, and cudf-polars 26.02 has no unnest map function (NotImplementedError: Unhandled map function unnest from raise_on_fail=True). _run_fast_path_on_requested_target converted that into "declined; plan not GPU-executable", so on engine='polars-gpu' every fused count(*) shape fell to the generic route; the values were right (the generic route answered), and the 71 + 8 + 2 + 2 fused pins failed on their served-by assertion. Found by dumping the failing frame's plan at the lane's collect on dgx.

Fix. _low_cardinality_pure_count_plan declines on the GPU target, so the lane keeps the group_by(...).agg(pl.len()) formulation there, which cudf-polars executes (verified directly on the engine). CPU keeps the value_counts plan unchanged.

Pin. test_low_cardinality_count_plan_declines_on_the_gpu_target: under target_mode(GPU) the alternative returns None; under CPU it still yields the UNNEST plan. Runs without a GPU.

Not in scope. The test_strictness_levels.py polars-gpu cases fail on the CPU polars engine too (select rows op not natively supported on polars); and the absent-property placeholder in gfql_unified.py:340 is an untyped pl.lit(None), which cudf-polars rejects (Invalid type_id) once that path is reachable; both stay on #2064.

Receipts: local fused file 252 pass; guards + mypy green; GPU receipt below.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QztW7jYsDd66e8rb8pJNQA

@lmeyerov

lmeyerov commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

GPU receipt (dgx-spark, graphistry/test-rapids-official:26.02-gfql-polars, cudf 26.02.01 / polars 1.35.2, safe_run, TEST_CUDF=1) at a4b6b4b on test_grouped_aggregate_fused_polars.py + test_strictness_levels.py: 607 passed / 5 failed, versus 520 passed / 91 failed on master 86de0f5 for the same two files. Every fused grouped-aggregate pin now passes on polars-gpu; the 5 left are the strictness polars-gpu cases (MATCH (n) RETURN n.nope_col), which raise the polars engine's select rows-op decline on CPU polars too and stay on #2064.

@lmeyerov

lmeyerov commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

CI receipt at a4b6b4b: 65 check-runs success, 4 path-skipped (tck-gfql, test-polars ×6, test-gfql-core, gfql-benchmarks and the guards green). GPU receipt above (607 / 5 vs master 520 / 91 on the two files).

…n the GPU target (#2064)

The low-cardinality count(*) alternative lowers to value_counts + unnest,
and cudf-polars has no unnest map function, so on engine='polars-gpu' every
fused count(*) shape raised inside the lane and declined to the generic
route. On the GPU target the lane now keeps the group_by formulation, which
cudf-polars executes. Pin: the alternative declines under the GPU target and
still produces the UNNEST plan on CPU.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QztW7jYsDd66e8rb8pJNQA
@lmeyerov
lmeyerov force-pushed the fix/gfql-2064-fused-count-groupby branch from a4b6b4b to e1eb737 Compare September 6, 2026 13:04
@lmeyerov

lmeyerov commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

CI receipt at e1eb737 (union-rebased onto master after #2055 landed; own delta unchanged): 65 check-runs success, 4 path-skipped. GPU receipt above stands (the change is in the lane's plan choice only).

@lmeyerov

lmeyerov commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Folded into #2062 (owner asked for a shallower stack); the commits, receipts and CHANGELOG entries live there unchanged.

@lmeyerov lmeyerov closed this Sep 6, 2026
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.

1 participant