-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve Parquet reader pass construction #23446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
26ec29f
ae04386
9515372
0cfda5b
a0e3a14
f35b314
cbb013b
993e2a1
c084960
ce37e4a
65275ae
709a5fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -793,59 +793,49 @@ hybrid_scan_reader_impl::construct_row_group_passes( | |
| CUDF_EXPECTS( | ||
| pass_read_limit > 0, "Pass read limit must be greater than 0", std::invalid_argument); | ||
|
|
||
| auto row_groups_info = std::vector<row_group_info>{}; | ||
| row_groups_info.reserve(total_row_groups); | ||
| size_t start_row = 0; | ||
| auto row_group_ids = std::vector<std::pair<size_type, size_type>>{}; | ||
| auto row_group_sizes = std::vector<cudf::io::parquet::detail::row_group_size_info>{}; | ||
| row_group_ids.reserve(total_row_groups); | ||
| row_group_sizes.reserve(total_row_groups); | ||
|
|
||
| std::for_each(cuda::counting_iterator<cudf::size_type>(0), | ||
| cuda::counting_iterator<cudf::size_type>(row_group_indices.size()), | ||
| [&](auto const source_index) { | ||
| auto const& src_row_groups = row_group_indices[source_index]; | ||
| std::transform( | ||
| src_row_groups.begin(), | ||
| src_row_groups.end(), | ||
| std::back_inserter(row_groups_info), | ||
| [&](auto const rg_index) { | ||
| auto const& row_group = | ||
| _extended_metadata->get_row_group(rg_index, source_index); | ||
| auto const [compressed_size, total_size, num_rows, max_leaf_values] = | ||
| _extended_metadata->get_row_group_properties(row_group); | ||
| auto rg_info = row_group_info{.index = rg_index, | ||
| .start_row = start_row, | ||
| .unadjusted_num_rows = num_rows, | ||
| .source_index = source_index, | ||
| .compressed_size = compressed_size, | ||
| .max_leaf_values = max_leaf_values}; | ||
| start_row += num_rows; | ||
| return rg_info; | ||
| }); | ||
| for (auto const rg_index : row_group_indices[source_index]) { | ||
| row_group_ids.emplace_back(rg_index, source_index); | ||
| // TODO(mh): Compute the row group size information over the selected columns | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Next PR thing |
||
| // instead | ||
| row_group_sizes.push_back(_extended_metadata->get_row_group_size_info( | ||
| rg_index, source_index, std::nullopt)); | ||
| } | ||
| }); | ||
|
|
||
| auto const comp_read_limit = static_cast<std::size_t>( | ||
| pass_read_limit * cudf::io::parquet::detail::input_limit_compression_reserve); | ||
|
|
||
| auto const pass_data = | ||
| cudf::io::parquet::detail::compute_row_group_passes(row_groups_info, comp_read_limit, 0); | ||
| cudf::io::parquet::detail::compute_row_group_passes(row_group_sizes, comp_read_limit, 0); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| // Convert offset-based pass boundaries back to vectors of row group indices | ||
| auto const& offsets = pass_data.pass_row_group_offsets; | ||
| auto passes = std::vector<std::vector<cudf::size_type>>{}; | ||
| passes.reserve(offsets.size() - 1); | ||
| auto row_group_source_map = std::vector<cudf::size_type>{}; | ||
| auto const has_multiple_sources = row_group_indices.size() > 1; | ||
| if (has_multiple_sources) { row_group_source_map.reserve(row_groups_info.size()); } | ||
| if (has_multiple_sources) { row_group_source_map.reserve(row_group_ids.size()); } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| std::transform(offsets.begin(), | ||
| offsets.end() - 1, | ||
| offsets.begin() + 1, | ||
| std::back_inserter(passes), | ||
| [&](auto const start, auto const end) { | ||
| auto pass = std::vector<cudf::size_type>{}; | ||
| pass.reserve(end - start); | ||
| std::for_each(row_groups_info.begin() + start, | ||
| row_groups_info.begin() + end, | ||
| [&](auto const& rg_info) { | ||
| pass.emplace_back(rg_info.index); | ||
| std::for_each(row_group_ids.begin() + start, | ||
| row_group_ids.begin() + end, | ||
| [&](auto const& row_group_id) { | ||
| pass.emplace_back(row_group_id.first); | ||
| if (has_multiple_sources) { | ||
| row_group_source_map.emplace_back(rg_info.source_index); | ||
| row_group_source_map.emplace_back(row_group_id.second); | ||
| } | ||
| }); | ||
| return pass; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -953,7 +953,7 @@ rmm::device_uvector<size_t> compute_level_decode_sizes(device_span<ColumnChunkDe | |
| return level_decode_sizes; | ||
| } | ||
|
|
||
| row_group_pass_data compute_row_group_passes(cudf::host_span<row_group_info const> row_groups_info, | ||
| row_group_pass_data compute_row_group_passes(std::span<row_group_size_info const> row_group_sizes, | ||
| std::size_t comp_read_limit, | ||
| int64_t skip_rows) | ||
| { | ||
|
|
@@ -970,14 +970,18 @@ row_group_pass_data compute_row_group_passes(cudf::host_span<row_group_info cons | |
| std::size_t cur_rg_start = 0; | ||
| std::size_t cur_row_count = 0; | ||
|
|
||
| for (std::size_t cur_rg_index = 0; cur_rg_index < row_groups_info.size(); cur_rg_index++) { | ||
| auto const& rgi = row_groups_info[cur_rg_index]; | ||
| for (std::size_t cur_rg_index = 0; cur_rg_index < row_group_sizes.size(); cur_rg_index++) { | ||
| auto const& rgi = row_group_sizes[cur_rg_index]; | ||
|
|
||
| // We must use the effective size of the first row group we are reading to accurately calculate | ||
| // the first non-zero `input_pass_start_row_count` unless we are reading only one row group | ||
| auto const row_group_rows = (skip_rows and row_groups_info.size() > 1) | ||
| ? (rgi.start_row + rgi.unadjusted_num_rows - skip_rows) | ||
| : rgi.unadjusted_num_rows; | ||
| auto row_group_rows = rgi.unadjusted_num_rows; | ||
| if (row_group_sizes.size() > 1) { | ||
| CUDF_EXPECTS(std::cmp_greater_equal(rgi.unadjusted_num_rows, skip_rows), | ||
| "Row groups must contribute non-negative effective rows", | ||
| std::invalid_argument); | ||
| row_group_rows -= skip_rows; | ||
| } | ||
|
Comment on lines
+978
to
+984
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
|
||
| auto const compressed_rg_size = rgi.compressed_size; | ||
| auto const row_group_leaf_values = rgi.max_leaf_values; | ||
|
|
@@ -1026,8 +1030,8 @@ row_group_pass_data compute_row_group_passes(cudf::host_span<row_group_info cons | |
| } | ||
|
|
||
| // Add the last pass if necessary | ||
| if (result.pass_row_group_offsets.back() != row_groups_info.size()) { | ||
| result.pass_row_group_offsets.push_back(row_groups_info.size()); | ||
| if (result.pass_row_group_offsets.back() != row_group_sizes.size()) { | ||
| result.pass_row_group_offsets.push_back(row_group_sizes.size()); | ||
| result.pass_start_row_counts.push_back(cur_row_count); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| #include <cstddef> | ||
| #include <functional> | ||
| #include <optional> | ||
| #include <span> | ||
| #include <string> | ||
| #include <string_view> | ||
| #include <tuple> | ||
|
|
@@ -66,19 +67,26 @@ struct column_chunk_info { | |
| * @brief The row_group_info class | ||
| */ | ||
| struct row_group_info { | ||
| size_type index; // row group index within a file. aggregate_reader_metadata::get_row_group() is | ||
| // called with index and source_index | ||
| size_t start_row; | ||
| size_type index; // row group index within a file. aggregate_reader_metadata::get_row_group() is | ||
| // called with index and source_index | ||
| size_t start_row; // global start row of this row group | ||
| size_t source_start_row; // file-local start row of this row group within its source file | ||
| size_t unadjusted_num_rows; // number of unadjusted rows in the row group | ||
| size_type source_index; // file index. | ||
| size_t compressed_size; // compressed size of the row group | ||
| size_t max_leaf_values; // maximum number of leaf values in the row group | ||
|
|
||
| // Optional metadata pulled from the column and offset indexes, if present. | ||
| std::optional<std::vector<column_chunk_info>> column_chunks; | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Row group size information for pass partitioning. | ||
| */ | ||
| struct row_group_size_info { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separated size related fields from |
||
| size_t unadjusted_num_rows; // number of unadjusted rows in this row group | ||
| size_t compressed_size; // compressed size of the selected columns in this row group | ||
| size_t max_leaf_values; // maximum number of leaf values over the selected columns | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Translates Parquet datatype to cuDF type enum | ||
| */ | ||
|
|
@@ -434,6 +442,22 @@ class aggregate_reader_metadata { | |
| */ | ||
| [[nodiscard]] RowGroup const& get_row_group(size_type row_group_index, size_type src_idx) const; | ||
|
|
||
| /** | ||
| * @brief Computes row group size information over selected columns | ||
| * | ||
| * When `input_columns` is specified, computes the compressed size and maximum leaf value count | ||
| * over only those columns. Otherwise, over all columns in the row group. | ||
| * | ||
| * @param row_group_index Index of the row group within its source | ||
| * @param src_idx Index of the input source | ||
| * @param input_columns Optional selected leaf columns | ||
| * @return Row group size information | ||
| */ | ||
| [[nodiscard]] row_group_size_info get_row_group_size_info( | ||
| size_type row_group_index, | ||
| size_type src_idx, | ||
| std::optional<std::span<input_column_info const>> input_columns) const; | ||
|
|
||
| /** | ||
| * @brief Check if all row groups have an offset index | ||
| * | ||
|
|
@@ -622,18 +646,6 @@ class aggregate_reader_metadata { | |
| */ | ||
| [[nodiscard]] std::vector<std::string> get_pandas_index_names() const; | ||
|
|
||
| /** | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove in favor of |
||
| * @brief Computes the compressed and total size, the number of rows, and the maximum number of | ||
| * leaf values in the specified row group | ||
| * | ||
| * @param row_group The row group | ||
| * | ||
| * @return A tuple of row group compressed size, total size, number of rows, and maximum leaf | ||
| * values | ||
| */ | ||
| [[nodiscard]] std::tuple<size_t, size_t, size_t, size_t> get_row_group_properties( | ||
| RowGroup const& rg) const; | ||
|
|
||
| /** | ||
| * @brief Filters the row groups using stats and bloom filters based on predicate filter | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated this loop to collect required info using the new
get_row_group_size_infoAPI.