Skip to content

Add multifile row group pruning with stats and byte ranges - #22715

Merged
rapids-bot[bot] merged 24 commits into
NVIDIA:mainfrom
mhaseeb123:fea/hybrid-scan-multifile-row-group-filter-part-1
Jun 4, 2026
Merged

Add multifile row group pruning with stats and byte ranges#22715
rapids-bot[bot] merged 24 commits into
NVIDIA:mainfrom
mhaseeb123:fea/hybrid-scan-multifile-row-group-filter-part-1

Conversation

@mhaseeb123

@mhaseeb123 mhaseeb123 commented May 29, 2026

Copy link
Copy Markdown
Contributor

Description

Contributes to #22583

This PR adds hybrid scan multifile reader APIs to filter row groups using column chunk stats and byte ranges.

Checklist

@mhaseeb123
mhaseeb123 requested review from a team as code owners May 29, 2026 19:26
@mhaseeb123
mhaseeb123 requested review from bdice and igorpeshansky May 29, 2026 19:26
@github-actions github-actions Bot added libcudf Affects libcudf (C++/CUDA) code. CMake CMake build issue labels May 29, 2026
@mhaseeb123
mhaseeb123 marked this pull request as draft May 29, 2026 19:26
@copy-pr-bot

copy-pr-bot Bot commented May 29, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds new byte-range and stats-based row-group pruning APIs plus secondary filter byte-range retrieval to the public hybrid_scan_multifile wrapper, implements them as thin forwards to the internal reader, updates helper validation for row-group indices, and adds tests for byte-range error handling and stats-based pruning across multiple Parquet sources.

Changes

Public multi-file hybrid scan API

Layer / File(s) Summary
Public API declaration
cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
Declares new methods: filter_row_groups_with_byte_range, filter_row_groups_with_stats (with CUDA stream), and secondary_filters_byte_ranges on hybrid_scan_multifile.
Wrapper implementation and forwarding methods
cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp
Implements constructors/destructor, metadata/page-index accessors, setup_page_indexes, row-group enumeration/aggregation, reset_column_selection, and the new filtering APIs as forwards to detail::hybrid_scan_reader_impl (with CUDF_FUNC_RANGE() instrumentation on filtering paths).
Helpers: row-group index validation
cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp
Adds <utility> include and validates per-source requested row-group indices in aggregate_reader_metadata::all_row_groups, failing with std::invalid_argument for out-of-bounds indices.
Impl doc @copydoc updates
cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp
Updates Doxygen @copydoc targets to reference the hybrid_scan_multifile public declarations for several methods.
Row-group filtering tests
cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
Adds tests: ErrorFilterRowGroupsWithByteRanges asserting std::invalid_argument for byte-range filtering when ambiguous per-source byte-range settings exist, and FilterRowGroupsWithStats validating stats-based pruning and empty-per-source scenarios with AST filters.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • rapidsai/cudf#22616: Implements the underlying multi-source hybrid_scan_reader_impl infrastructure that this PR wraps with a public API.

Suggested labels

4 - Needs Review

Suggested reviewers

  • qbacpey
  • PointKernel
  • bdice
  • lamarrr
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding multifile row group pruning capabilities using stats and byte ranges.
Description check ✅ Passed The description directly relates to the changeset, explaining that the PR adds hybrid scan multifile reader APIs for filtering row groups using column chunk stats and byte ranges.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp (1)

379-382: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Use aggregate schema mapping here, not source-0/raw local schema ids.

Lines 381 and 611 still build the equality-literal collector from per_file_metadata[0].schema, and Lines 489-499 walk row_group.columns by raw schema_idx. That breaks the new multifile path when schemas differ across sources: a filter column that only exists in later files is typed against the wrong schema, and dictionary pruning can fail to find the matching local column chunk for that source. Please resolve these lookups through the aggregate schema tree / per-source schema maps instead of source 0 or raw local ids.

Also applies to: 489-499, 609-612

🤖 Prompt for 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.

In `@cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp` around lines 379 -
382, The equality literal collector and the code walking row_group.columns use
per_file_metadata[0].schema and raw schema_idx (e.g.,
equality_literals_collector{... per_file_metadata[0].schema}.get_literals() and
loops over row_group.columns by schema_idx), which breaks multifile handling
when source schemas differ; update these lookups to resolve types and column
mappings through the aggregate schema tree and the per-source schema maps (use
the aggregate mapping that produced output_dtypes/output_column_schemas to
translate output column ids into the correct local column/chunk ids for each
per_file_metadata entry) so equality_literals_collector is constructed with the
aggregate-resolved schema mapping for that source and the row_group.column
iteration uses the per-source local id mapped from the aggregate schema rather
than raw schema_idx.
🧹 Nitpick comments (2)
cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp (1)

28-58: ⚡ Quick win

Add CUDF_FUNC_RANGE() to all remaining public forwarding methods.

parquet_metadatas, page_index_byte_ranges, all_row_groups, total_rows_in_row_groups, and reset_column_selection currently delegate without CUDF_FUNC_RANGE(), unlike the other public methods in this file.

As per coding guidelines "Add CUDF_FUNC_RANGE() in public functions before delegating to detail:: functions".

🤖 Prompt for 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.

In `@cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp` around lines 28 -
58, The public forwarding methods parquet_metadatas, page_index_byte_ranges,
setup_page_indexes, all_row_groups, total_rows_in_row_groups, and
reset_column_selection lack the CUDF_FUNC_RANGE() macro; add CUDF_FUNC_RANGE()
as the first statement in each of these functions (e.g., inside
hybrid_scan_multifile::parquet_metadatas(), ::page_index_byte_ranges(),
::all_row_groups(), ::total_rows_in_row_groups(), and
::reset_column_selection()) before delegating to _impl->... so they match the
file's other public functions and follow the coding guideline.
cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp (1)

54-168: ⚡ Quick win

Complete Doxygen tags for public API declarations.

Several public methods have @brief/@param/@return, but the guideline requires full tag coverage (@throw, and @tparam where applicable) on public API functions.

As per coding guidelines "Add Doxygen documentation tags (@param, @return, @throw, @tparam, @brief) on all public API functions".

🤖 Prompt for 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.

In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp` around lines 54 -
168, Update the Doxygen comments for all public APIs in class
hybrid_scan_multifile to include the full set of required tags: ensure each
constructor (hybrid_scan_multifile), destructor (~hybrid_scan_multifile), and
methods (parquet_metadatas, page_index_byte_ranges, setup_page_indexes,
all_row_groups, total_rows_in_row_groups, reset_column_selection,
filter_row_groups_with_byte_range, filter_row_groups_with_stats,
secondary_filters_byte_ranges) have `@brief`, `@param` for each parameter, `@return`
where applicable, and add `@throw` descriptions for exceptions the method may
propagate (and `@tparam` if any template params are introduced later); keep
descriptions concise and accurate and mention thrown exception types or
conditions for each method.
🤖 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/include/cudf/io/experimental/hybrid_scan_multifile.hpp`:
- Around line 114-115: total_rows_in_row_groups currently returns a 32-bit
size_type which can overflow; change the function signature to return a 64-bit
count (e.g., std::int64_t) and update its implementation to use a 64-bit
accumulator (std::int64_t) when summing row counts from the provided
cudf::host_span<std::vector<size_type> const> row_group_indices, and propagate
that 64-bit type to any related local variables and return sites (and update
callers if needed) so totals cannot be truncated; refer to the function
total_rows_in_row_groups and its implementation when making these changes.

In `@cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp`:
- Around line 203-206: The code returns opts_row_groups unchanged, allowing
invalid row-group indices to cause OOB later; update the branch that returns
options.get_row_groups() (opts_row_groups) to validate every supplied id against
per_file_metadata[src].row_groups.size() before returning: for each source index
src and each rg_index in opts_row_groups[src] ensure 0 <= rg_index <
per_file_metadata[src].row_groups.size(), and invoke CUDF_EXPECTS with a clear
message (e.g., "Requested row-group index out of range for data source") on
failure so callers like get_dictionary_page_bytes() cannot hit host-side OOB.

In `@cpp/src/io/parquet/experimental/page_index_filter.cu`:
- Around line 1001-1003: The precondition computing row_mask_offset + total_rows
can overflow; replace the single unsafe check with two safe checks: first ensure
row_mask_offset is <= row_mask.size(), then ensure total_rows <= row_mask.size()
- row_mask_offset (so the subtraction is safe). Update the CUDF_EXPECTS call(s)
around the row-mask validation in page_index_filter.cu (referencing
row_mask_offset, total_rows, row_mask.size(), and CUDF_EXPECTS) to perform these
two comparisons and throw the same std::invalid_argument message on failure.

In `@cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp`:
- Around line 264-274: The string predicate uses an ASCII-only literal
("000010000"); add a UTF-8 non-ASCII test case by creating another
cudf::string_scalar with a multibyte string (e.g., containing accented or CJK
characters), wrap it as cudf::ast::literal (similar to literal2), and build a
corresponding column reference/operation (like col_ref2 and filter2) so the test
exercises multibyte string pruning; update or append to the existing
literals/filters (literal_value2, literal2, col_ref2, filter2) to include this
non-ASCII variant and ensure it follows the same construction pattern and stream
handling as the ASCII case.
- Around line 82-303: Add focused TEST_F cases under
HybridScanMultifileFiltersTest that exercise the multifile path with null
values, sliced columns, boundary-size row groups, and multi-block parquet files:
for nulls create_parquet_with_stats with nullable columns and assert
filter_row_groups_with_stats prunes correctly; for sliced columns build buffers
then pass subspans from build_multifile_inputs and ensure
hybrid_scan_multifile->parquet_metadatas and page_index_byte_ranges still match
and setup_page_indexes succeeds; for boundary sizes generate files whose row
groups are exactly at page_size_for_ordered_tests and just over it and validate
all_row_groups, total_rows_in_row_groups and stats filtering; for multi-block
produce parquet files spanning multiple blocks and verify page_index_byte_ranges
are non-empty and filter_row_groups_with_stats/
filter_row_groups_with_byte_range behave as expected (including throwing when
appropriate). Use existing helpers (create_parquet_with_stats,
create_empty_parquet_with_stats, build_multifile_inputs) and methods
(cudf::io::parquet::experimental::hybrid_scan_multifile, page_index_byte_ranges,
setup_page_indexes, filter_row_groups_with_stats, all_row_groups,
total_rows_in_row_groups) and follow the pattern of the existing tests for
assertions and seeding.

---

Outside diff comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp`:
- Around line 379-382: The equality literal collector and the code walking
row_group.columns use per_file_metadata[0].schema and raw schema_idx (e.g.,
equality_literals_collector{... per_file_metadata[0].schema}.get_literals() and
loops over row_group.columns by schema_idx), which breaks multifile handling
when source schemas differ; update these lookups to resolve types and column
mappings through the aggregate schema tree and the per-source schema maps (use
the aggregate mapping that produced output_dtypes/output_column_schemas to
translate output column ids into the correct local column/chunk ids for each
per_file_metadata entry) so equality_literals_collector is constructed with the
aggregate-resolved schema mapping for that source and the row_group.column
iteration uses the per-source local id mapped from the aggregate schema rather
than raw schema_idx.

---

Nitpick comments:
In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp`:
- Around line 54-168: Update the Doxygen comments for all public APIs in class
hybrid_scan_multifile to include the full set of required tags: ensure each
constructor (hybrid_scan_multifile), destructor (~hybrid_scan_multifile), and
methods (parquet_metadatas, page_index_byte_ranges, setup_page_indexes,
all_row_groups, total_rows_in_row_groups, reset_column_selection,
filter_row_groups_with_byte_range, filter_row_groups_with_stats,
secondary_filters_byte_ranges) have `@brief`, `@param` for each parameter, `@return`
where applicable, and add `@throw` descriptions for exceptions the method may
propagate (and `@tparam` if any template params are introduced later); keep
descriptions concise and accurate and mention thrown exception types or
conditions for each method.

In `@cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp`:
- Around line 28-58: The public forwarding methods parquet_metadatas,
page_index_byte_ranges, setup_page_indexes, all_row_groups,
total_rows_in_row_groups, and reset_column_selection lack the CUDF_FUNC_RANGE()
macro; add CUDF_FUNC_RANGE() as the first statement in each of these functions
(e.g., inside hybrid_scan_multifile::parquet_metadatas(),
::page_index_byte_ranges(), ::all_row_groups(), ::total_rows_in_row_groups(),
and ::reset_column_selection()) before delegating to _impl->... so they match
the file's other public functions and follow the coding guideline.
🪄 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: 4da93e7c-3073-4ebd-b381-17afa9f36198

📥 Commits

Reviewing files that changed from the base of the PR and between 836530c and e013fda.

📒 Files selected for processing (12)
  • cpp/CMakeLists.txt
  • cpp/include/cudf/io/experimental/hybrid_scan.hpp
  • cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_helpers.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp
  • cpp/src/io/parquet/experimental/page_index_filter.cu
  • cpp/tests/CMakeLists.txt
  • cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp

Comment thread cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
Comment thread cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp
Comment thread cpp/src/io/parquet/experimental/page_index_filter.cu Outdated
Comment thread cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
Comment thread cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp Outdated
@igorpeshansky

Copy link
Copy Markdown
Contributor

@mhaseeb123 This is still marked as a draft. Is it ready for review?

@mhaseeb123

mhaseeb123 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

This is still marked as a draft. Is it ready for review?

Hi @igorpeshansky, Not yet, this PR includes code from another one still in review (the line count of this PR would significantly reduce once we pull in from it). I will mark it ready and ping you once ready

@mhaseeb123
mhaseeb123 marked this pull request as ready for review June 2, 2026 01:34
@mhaseeb123

Copy link
Copy Markdown
Contributor Author

@igorpeshansky @bdice the PR is ready to review now. Should be pretty straightforward :)

@mhaseeb123 mhaseeb123 added feature request New feature or request 3 - Ready for Review Ready for review by team cuIO cuIO issue non-breaking Non-breaking change labels Jun 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp (1)

149-152: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add default value for stream parameter.

The stream parameter lacks a default value. Public APIs in cuDF must provide defaults for stream and MR parameters.

As per coding guidelines: "public APIs must have defaults" for stream parameters.

🔧 Proposed fix
   [[nodiscard]] std::vector<std::vector<size_type>> filter_row_groups_with_stats(
     cudf::host_span<std::vector<size_type> const> row_group_indices,
     parquet_reader_options const& options,
-    rmm::cuda_stream_view stream) const;
+    rmm::cuda_stream_view stream = cudf::get_default_stream()) const;
🤖 Prompt for 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.

In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp` around lines 149
- 152, The public method filter_row_groups_with_stats currently requires an
explicit rmm::cuda_stream_view stream argument; update its signature to provide
a default stream value (e.g., rmm::cuda_stream_view{} or
rmm::cuda_stream_default according to project convention) so callers need not
pass a stream; modify the declaration of filter_row_groups_with_stats to set the
default for the stream parameter and ensure any matching definitions/overloads
in the corresponding .cpp remain consistent with the new default.
🧹 Nitpick comments (3)
cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp (3)

167-168: ⚡ Quick win

Consider documenting input validation expectations.

Like the other filter methods, this signature lacks documentation about input preconditions. Consider adding a @throw tag or notes for edge cases such as empty row_group_indices or invalid row group indices.

As per coding guidelines, public APIs should document input validation for invalid parameters.

🤖 Prompt for 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.

In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp` around lines 167
- 168, Add input-validation documentation to the public API for
secondary_filters_byte_ranges(cudf::host_span<std::vector<size_type> const>
row_group_indices, parquet_reader_options const& options) const: describe
preconditions (e.g., that row_group_indices must be non-empty and each size_type
must be within valid row-group range for the file), specify behavior for empty
or out-of-range indices, and include a `@throw` tag indicating which exception(s)
will be raised for invalid parameters (or state that invalid inputs result in
undefined behavior if intentional); reference the function name
secondary_filters_byte_ranges and the parameter row_group_indices in the doc
comment so callers know what is validated.

149-152: ⚡ Quick win

Consider documenting input validation expectations.

Similar to filter_row_groups_with_byte_range, this method lacks documentation about input preconditions or validation behavior. Consider adding a @throw tag or notes for edge cases like empty spans or invalid indices.

As per coding guidelines, public APIs should document input validation for invalid parameters.

🤖 Prompt for 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.

In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp` around lines 149
- 152, Add documentation for input validation and preconditions to the public
API for filter_row_groups_with_stats: describe expected inputs (e.g., that
row_group_indices (cudf::host_span<std::vector<size_type> const>) must be
non-empty and contain valid row-group indices), what happens for empty spans,
out-of-range or duplicate indices, and whether parquet_reader_options is
validated; include explicit `@throw` tags for parameter validation failures (e.g.,
std::invalid_argument or out_of_range) and any behavior on empty input to match
the style used by filter_row_groups_with_byte_range so callers know the contract
for filter_row_groups_with_stats.

137-139: ⚡ Quick win

Consider documenting input validation expectations.

The method signature lacks documentation about input preconditions or validation. Consider adding a @throw tag or notes clarifying how the API handles edge cases such as empty row_group_indices, out-of-range indices, or invalid options.

As per coding guidelines, public APIs in headers should document input validation for invalid parameters.

🤖 Prompt for 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.

In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp` around lines 137
- 139, Add documentation above the declaration of
filter_row_groups_with_byte_range clarifying input validation and expected
behavior: document `@param` row_group_indices expectations (e.g., may be empty),
`@param` options expected valid state, return behavior for empty input (e.g.,
returns empty vector), and explicit `@throw` clauses for invalid inputs (e.g.,
throw std::out_of_range for out-of-range indices and std::invalid_argument for
invalid options). Also add brief notes about whether the function performs
bounds checking and ownership/immutability assumptions of the cudf::host_span to
make the API contract clear.
🤖 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.

Outside diff comments:
In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp`:
- Around line 149-152: The public method filter_row_groups_with_stats currently
requires an explicit rmm::cuda_stream_view stream argument; update its signature
to provide a default stream value (e.g., rmm::cuda_stream_view{} or
rmm::cuda_stream_default according to project convention) so callers need not
pass a stream; modify the declaration of filter_row_groups_with_stats to set the
default for the stream parameter and ensure any matching definitions/overloads
in the corresponding .cpp remain consistent with the new default.

---

Nitpick comments:
In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp`:
- Around line 167-168: Add input-validation documentation to the public API for
secondary_filters_byte_ranges(cudf::host_span<std::vector<size_type> const>
row_group_indices, parquet_reader_options const& options) const: describe
preconditions (e.g., that row_group_indices must be non-empty and each size_type
must be within valid row-group range for the file), specify behavior for empty
or out-of-range indices, and include a `@throw` tag indicating which exception(s)
will be raised for invalid parameters (or state that invalid inputs result in
undefined behavior if intentional); reference the function name
secondary_filters_byte_ranges and the parameter row_group_indices in the doc
comment so callers know what is validated.
- Around line 149-152: Add documentation for input validation and preconditions
to the public API for filter_row_groups_with_stats: describe expected inputs
(e.g., that row_group_indices (cudf::host_span<std::vector<size_type> const>)
must be non-empty and contain valid row-group indices), what happens for empty
spans, out-of-range or duplicate indices, and whether parquet_reader_options is
validated; include explicit `@throw` tags for parameter validation failures (e.g.,
std::invalid_argument or out_of_range) and any behavior on empty input to match
the style used by filter_row_groups_with_byte_range so callers know the contract
for filter_row_groups_with_stats.
- Around line 137-139: Add documentation above the declaration of
filter_row_groups_with_byte_range clarifying input validation and expected
behavior: document `@param` row_group_indices expectations (e.g., may be empty),
`@param` options expected valid state, return behavior for empty input (e.g.,
returns empty vector), and explicit `@throw` clauses for invalid inputs (e.g.,
throw std::out_of_range for out-of-range indices and std::invalid_argument for
invalid options). Also add brief notes about whether the function performs
bounds checking and ownership/immutability assumptions of the cudf::host_span to
make the API contract clear.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b4661033-a02d-40dd-b6a1-e803155135cc

📥 Commits

Reviewing files that changed from the base of the PR and between c164897 and 7a35f6e.

📒 Files selected for processing (1)
  • cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp

@igorpeshansky igorpeshansky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @pmattione-nvidia for awareness, as he was implementing something similar.

Comment thread cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp Outdated
Comment thread cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
Comment thread cpp/src/io/parquet/experimental/hybrid_scan_helpers.cpp Outdated
Comment thread cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp Outdated
Comment thread cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp Outdated
Comment thread cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp Outdated

@bdice bdice left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really great ideas from @igorpeshansky -- I have no additional commentary.

@mhaseeb123
mhaseeb123 requested a review from igorpeshansky June 2, 2026 21:14
@mhaseeb123 mhaseeb123 added 4 - Needs Review Waiting for reviewer to review or respond and removed 3 - Ready for Review Ready for review by team labels Jun 2, 2026
Comment thread cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp Outdated
Comment thread cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp Outdated
@mhaseeb123
mhaseeb123 requested a review from igorpeshansky June 3, 2026 02:50

@igorpeshansky igorpeshansky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

Comment thread cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp
@mhaseeb123

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit fbfc39b into NVIDIA:main Jun 4, 2026
115 checks passed
@mhaseeb123
mhaseeb123 deleted the fea/hybrid-scan-multifile-row-group-filter-part-1 branch June 4, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4 - Needs Review Waiting for reviewer to review or respond CMake CMake build issue cuIO cuIO issue feature request New feature or request libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants