refactor(parquet): introduce string_offset_scan_state for preprocess_string_offsets_kernel - #23495
Conversation
…rocess_string_offsets_kernel via string_offset_scan_state
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughParquet decoding now stores cumulative counters and row-bound state in ChangesParquet progress-state migration
Estimated code review effort: 3 (Moderate) | ~30 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cpp/src/io/parquet/page_decode.cuh`:
- Around line 204-207: Update the Doxygen blocks for is_bounds_page and the
other affected helper declarations to document the actual s parameter, replacing
the obsolete page and chunk_start_row entries. Ensure every documented parameter
matches its corresponding signature, including start_row, num_rows, and
has_repetition.
In `@cpp/src/io/parquet/page_state_composed.cuh`:
- Around line 47-50: Update the static_assert involving string_offset_scan_state
to compare its size directly against sizeof(page_state_s), removing the
additional page_decode_* size terms so the assertion detects shared-memory size
regressions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: aeb3f98f-cc50-4e63-8a04-2c5908743ce3
📒 Files selected for processing (7)
cpp/src/io/parquet/decode_fixed.cucpp/src/io/parquet/decode_preprocess.cucpp/src/io/parquet/page_data.cucpp/src/io/parquet/page_decode.cuhcpp/src/io/parquet/page_delta_decode.cucpp/src/io/parquet/page_state_composed.cuhcpp/src/io/parquet/page_string_decode.cu
| CUDF_PARQUET_PAGE_STATE_ERROR_METHODS | ||
| }; | ||
| static_assert(sizeof(string_offset_scan_state) < sizeof(page_state_s), | ||
| "string_offset_scan_state did not shrink after removing output conversion state"); |
There was a problem hiding this comment.
Is this meant to be left in?
There was a problem hiding this comment.
It can be removed, but since CI already passed here unless another reviewer requests changes I'll just leave it for now and clean it up in a follow-up PR. We'll be either renaming/removing page_state_s so this'll have to change then.
|
/merge |
…_assert Addresses review comment on NVIDIA#23495: the sizeof(string_offset_scan_state) < sizeof(page_state_s) static_assert was verification scaffold from the initial struct extraction. Neither level_scan_state nor string_size_scan_state have an equivalent assert, and the shmem win is already covered by the resource-usage measurements in the PR description. Drop it for consistency.
…_page_decode_state replacing page_state_s (#23610) This PR completes the incremental narrowing pattern from #23471, #23479, #23495, and #23496 by retiring `page_state_s` entirely. It extracts `page_decode_nesting_state` (the nesting decode cache and pointer) and composes `full_page_decode_state` from `page_decode_setup_state`, `page_decode_stream_state`, `page_decode_nesting_state`, `page_decode_progress_state`, and `page_decode_output_state`. Every full-decode kernel (`decode_page_data`, `decode_split_page_data_kernel`, `decode_page_data_generic`, `decode_delta_binary`, `decode_delta_byte_array`, `decode_delta_length_byte_array`, `compute_string_page_bounds`, `compute_page_sizes`) now takes this composed state instead of the ad-hoc `page_state_s`, and the old struct is deleted. The composition also folds `page_state_s`'s stand-alone level-decoding fields (`lvl_start[2]`, `lvl_end`) into the already-existing `page_decode_stream_state::abs_lvl_start` / `abs_lvl_end` arrays, and drops the unused `first_output_value` field. Together with the composition's tighter layout this removes 32 bytes of shared memory from every full-decode kernel on every generated architecture, with no register-count regressions. A fresh `cuobjdump -res-usage` comparison against `upstream/main` shows the same 32-byte shmem reduction on all eight migrated kernels on every generated architecture. Register usage does not increase anywhere; one variant of `decode_split_page_data_kernel` on `sm_86` drops by 8 registers: | Kernel | Arch summary | shmem delta | register changes | |---|---|---:|---| | `decode_page_data` | all generated arch variants | -32 bytes | unchanged | | `decode_split_page_data_kernel` | all generated arch variants | -32 bytes | unchanged except `sm_86`: one template variant 48 -> 40 | | `decode_page_data_generic` | all generated arch variants (44 template variants) | -32 bytes | unchanged | | `compute_page_sizes` | all generated arch variants | -32 bytes | unchanged | | `compute_string_page_bounds` | all generated arch variants | -32 bytes | unchanged | | `decode_delta_binary` | all generated arch variants | -32 bytes | unchanged | | `decode_delta_byte_array` | all generated arch variants | -32 bytes | unchanged | | `decode_delta_length_byte_array` | all generated arch variants | -32 bytes | unchanged | Representative sm_80 measurements: | Kernel | shmem before | shmem after | delta | regs before | regs after | |---|---:|---:|---:|---:|---:| | `decode_page_data` | 4112 | 4080 | -32 | 56 | 56 | | `decode_split_page_data_kernel` | 4112 | 4080 | -32 | 56 | 56 | | `decode_page_data_generic` (min variant) | 2104 | 2072 | -32 | 62 | 62 | | `decode_page_data_generic` (max variant) | 13024 | 12992 | -32 | 64 | 64 | | `compute_page_sizes` | 3240 | 3208 | -32 | 32 | 32 | | `compute_string_page_bounds` | 3256 | 3224 | -32 | 32 | 32 | | `decode_delta_binary` | 2700 | 2668 | -32 | 56 | 56 | | `decode_delta_byte_array` | 5068 | 5036 | -32 | 72 | 72 | | `decode_delta_length_byte_array` | 3392 | 3360 | -32 | 64 | 64 | With this PR the `page_state_s` type is fully removed. All Parquet decode and preprocess kernels now use one of four purpose-built shared-memory states (`level_scan_state`, `string_size_scan_state`, `string_offset_scan_state`, `full_page_decode_state`), each holding only the substructs it actually needs. Authors: - Vyas Ramasubramani (https://github.com/vyasr) Approvers: - Bradley Dice (https://github.com/bdice) URL: #23610
Description
This PR builds on #23479 to continue narrowing the shared state used by Parquet preprocessing kernels. It extracts
page_decode_progress_statefrompage_state_s, grouping the decode-position/progress fields that are needed by string-offset preprocessing.The primary addition is
string_offset_scan_state, composed frompage_decode_setup_state,page_decode_stream_state, andpage_decode_progress_state.preprocess_string_offsets_kernelnow uses this smaller composed state instead of the fullpage_state_s, which drops unrelated output-conversion, nesting, and level-scratch fields from that kernel's shared-memory state. This follows the same pattern as #23479: pull one coherent sub-state out ofpage_state_s, migrate the target kernel to the minimal composed state it actually needs, and leave the remaining full decode state for a later PR.A fresh
cuobjdump -res-usagecomparison againstupstream/mainshowspreprocess_string_offsets_kernelsaves 512 bytes of shared memory on every generated architecture, with no register-count changes:Checklist