Skip to content

Forward merge release/26.06 into main - #22603

Merged
vyasr merged 4 commits into
NVIDIA:mainfrom
KyleFromNVIDIA:main-merge-release/26.06
May 20, 2026
Merged

Forward merge release/26.06 into main#22603
vyasr merged 4 commits into
NVIDIA:mainfrom
KyleFromNVIDIA:main-merge-release/26.06

Conversation

@KyleFromNVIDIA

Copy link
Copy Markdown
Member

Description

Resolve merge conflicts from #22555.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

madsbk and others added 4 commits May 20, 2026 11:40
…#22252)

Restructure the docs around the new streaming multi-GPU engines and unified configuration model, replacing the legacy execution narrative, add a set of user-facing guides covering usage, engines, configuration, profiling, and legacy workflows.

Authors:
  - Mads R. B. Kristensen (https://github.com/madsbk)

Approvers:
  - Matthew Roeschke (https://github.com/mroeschke)
  - James Lamb (https://github.com/jameslamb)
  - Lawrence Mitchell (https://github.com/wence-)

URL: NVIDIA#22252
)

## Summary
- Remove the `CUDF_EXPECTS` check that was comparing the actual token count against an analytical upper bound
- Expand test coverage for malformed JSON recovery with `{\n` and `{"\n` patterns

### Details
The JSON tokenizer was failing on malformed input like repeated `{\n` lines in recovery mode with:
```
CUDF failure at: nested_json_gpu.cu:1683: Generated token count exceeds the expected token count
```
The analytical bound assumed a worst-case ratio of 6 tokens per 5 characters (based on valid JSON like {"":_}), but recovery mode can produce higher ratios—for example, {"\n produces 5 tokens for 3 characters.
Since the buffer allocation uses the exact count from a sizing FST pass (not the analytical bound), this check served only as a debug assertion. Removing it fixes the failure without any functional impact.

Authors:
  - Shruti Shivakumar (https://github.com/shrshi)

Approvers:
  - Vukasin Milovanovic (https://github.com/vuule)
  - David Wendt (https://github.com/davidwendt)
  - Bradley Dice (https://github.com/bdice)

URL: NVIDIA#22589
)

Closes NVIDIA#18182

This PR adds `streaming_groupby`, a stateful groupby that accumulates partial aggregates across batches using a single persistent hash table.

Users specify `max_groups`, the maximum number of distinct groups expected, and all main data structures are allocated once and reused without resizing. The hash table stores a `size_type` group ID per slot.
The ID is global across the stream: each distinct group, in the order it is first seen, is assigned a stable ID in `[0, distinct_count)` that is shared by the result table (used as the row index) and by the companion array (used as the lookup index). The actual keys live in a list of per-batch compacted key tables. The companion array, of length `max_groups`, holds a `{batch_id, row_id}` pair for each group ID, pointing back to where that group's representative key is stored. Equality probes resolve a slot ID through the companion array into the correct preprocessed batch table and compare via an n-table row comparator.

Each batch is processed in two steps. The first step calls `insert_and_find` against the hash set. Winners write a transient value `max_groups + batch_idx` into their slot, which is distinguishable from any real group ID since real IDs live in `[0, max_groups)`. Existing slots already hold a final ID and are returned as-is. A side flag array marks which rows won their slot, and a slot-offset array records where each row landed for cheap revisits. The newly inserted rows are stream-compacted and gathered into a fresh compacted key table that is appended to the per-batch list. The second step walks only the new keys, atomically rewrites their transient slot values to stable global IDs starting at the current distinct count, and writes the matching `{batch_id, row_id}` entries into the companion array. A final reread converts any remaining transient slot reads into global IDs, so every row in the batch ends up mapped to its stable group ID. Aggregations are updated atomically into a single result table indexed directly by these IDs.

Merging reprobes the other object's compacted keys against this hash table to recover their target group IDs in this object's ID space, then atomically combines the matching result rows. Finalization concatenates the per-batch compacted key tables to produce the distinct-keys output, slices the result table to `[0, distinct_count)` — no gather is needed, since the global IDs are already the row indices — and runs the compound-aggregation finalizers to produce user-facing columns. The internal state is left intact, so further `aggregate` calls remain valid.

Certain trade-offs are intentional. For example, the streaming groupby is designed to deep-copy all distinct keys locally. This enables batch-based processing: once a batch has completed the add step, its input data can be released, which helps reduce memory usage.

Additionally, the current code path does not support shared memory. As a result, inputs with very low cardinality can suffer from poor runtime performance due to high atomic contention, since many updates target the same key or memory location. This is an accepted trade-off. In practice, downstream users can run a standard groupby to estimate cardinality; if it is low, they can concatenate all input data and use a regular groupby instead, which typically yields better performance.

Authors:
  - Yunsong Wang (https://github.com/PointKernel)

Approvers:
  - Devavret Makkar (https://github.com/devavret)
  - Lawrence Mitchell (https://github.com/wence-)
  - Bradley Dice (https://github.com/bdice)

URL: NVIDIA#21924
@KyleFromNVIDIA
KyleFromNVIDIA requested review from a team as code owners May 20, 2026 17:43
@KyleFromNVIDIA KyleFromNVIDIA added the feature request New feature or request label May 20, 2026
@KyleFromNVIDIA
KyleFromNVIDIA requested a review from a team as a code owner May 20, 2026 17:43
@KyleFromNVIDIA KyleFromNVIDIA added the non-breaking Non-breaking change label May 20, 2026
@KyleFromNVIDIA
KyleFromNVIDIA requested review from bdice and shrshi May 20, 2026 17:43
@github-actions github-actions Bot added libcudf Affects libcudf (C++/CUDA) code. Python Affects Python cuDF API. CMake CMake build issue cudf-polars Issues specific to cudf-polars labels May 20, 2026
@GPUtester GPUtester moved this to In Progress in cuDF Python May 20, 2026
coderabbitai[bot]

This comment was marked as off-topic.

@NVIDIA NVIDIA deleted a comment from coderabbitai Bot May 20, 2026
@KyleFromNVIDIA

Copy link
Copy Markdown
Member Author

/merge nosquash

@vyasr
vyasr merged commit 235f69a into NVIDIA:main May 20, 2026
67 of 68 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in cuDF Python May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CMake CMake build issue cudf-polars Issues specific to cudf-polars feature request New feature or request libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change Python Affects Python cuDF API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants