-
Notifications
You must be signed in to change notification settings - Fork 917
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
Fix page size calculation in Parquet writer #12182
Fix page size calculation in Parquet writer #12182
Conversation
level info into account when calculating page sizes
Can one of the admins verify this patch? Admins can comment |
Pull requests from external contributors require approval from a |
I ran the NDS conversion from csv to parquet/zstd at scale=100. The total output size was 27G, consistent with the output before this change. Individual files sizes are:
compared to the following provided by @jbrennan333
|
@vuule the benchmarks really are a mixed bag. I'll have to test with 5000 again, but maybe we should hold off on the fragment size change in favor of trying the per-column approach. |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## branch-23.02 #12182 +/- ##
===============================================
Coverage ? 88.18%
===============================================
Files ? 137
Lines ? 22653
Branches ? 0
===============================================
Hits ? 19977
Misses ? 2676
Partials ? 0 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
This is my summary of results with just the fragment size change:
Are you seeing something similar? This is without ZSTD (de)compression, so maybe you're seeing a different picture. |
My number are just a bit more extreme. I'm seeing more like a 13-15% slowdown on integral/time types and as much as 50% increase for list. This is on my workstation w/ an A6000, so I should probably try repeating on the A100s at work. That and I should try benchmarking with some different datasets. (Also need to dump to CSV so I can get harder performance numbers). |
As you suggested earlier, let's take the L on the fragment size and just fix the page size for now :) |
@vuule the fix is mostly ready for review then...do you think there are any unit tests to add? I can't think of anything beyond write a file then read all the page headers to confirm that all uncompressed sizes are below the threshold. I don't know if there's any value there. |
cpp/src/io/parquet/page_enc.cu
Outdated
// subtract size of rep and def level vectors | ||
auto num_vals = values_in_page + frag_g.num_values; | ||
this_max_page_size -= max_RLE_page_size(col_g.num_def_level_bits(), num_vals) + | ||
max_RLE_page_size(col_g.num_rep_level_bits(), num_vals); | ||
|
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.
Please make sure to merge upstream with the latest changes in this file.
…than wrap when subtracting rep and def level sizes
…feature/page_size_fix
size_t this_max_page_size = (values_in_page * 2 >= ck_g.num_values) ? 256 * 1024 | ||
: (values_in_page * 3 >= ck_g.num_values) ? 384 * 1024 | ||
: 512 * 1024; | ||
long this_max_page_size = (values_in_page * 2 >= ck_g.num_values) ? 256 * 1024 |
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.
You may also need to modify the line 360 below to avoid comparing between size_t
and long
:
if(this_max_page_size > static_cast<long>(max_page_size_bytes)) {
this_max_page_size = static_cast<long>(max_page_size_bytes);
}
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.
The should also be similar issue with comparing this_max_page_size
with other variables below but I can't figure out an efficient way to fix all.
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.
Huh. Doesn't compiler complain about signed-unsigned comparison?
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.
I have no idea. Sometimes it is very aggressive. Some other times it just silently ignored.
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.
tbh I expected the compiler to yell at me about this...didn't realize min()
was overloaded so much (unlike std::min
). Fixed.
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.
Yeah I've been working with cuda code/nvcc
long enough time and no longer trust in its ability to yell at me for non-critical warnings.
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.
I believe that the remaining usage of this_max_page_size
is at line 369. Can you please check for signed/unsigned comparison there (and fix if necessary)?
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.
I think the comparison at line 369 is ok since it's checking whether the sum of two 32-bit unsigneds is greater than a 64-bit signed.
Ofc that raises the question of whether using 32 bits for page size is sufficient. But since pages really should be in the kilobytes, it shouldn't be an issue. Maybe we should just change the max_page_size_bytes
parameter to be a size_type
instead? But that's getting a little out-of-scope maybe.
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.
size_type
is meant to be used for the number of rows (I'm sure there are many places where it's misused). I prefer to use 64-bit types for byte counting, as much as I agree that page size should never be over 2GB :D
Agreed that this would be out-of-scope for this, very focused, PR.
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.
I take that back...if the addition overflows, then the test at 369 might never evaluate true 😮
Maybe there should be a follow-on PR to clean this up.
@gpucibot merge |
Reverts a change made in #12182 which exposed some potential issues with calculating page boundaries. Instead, checks are added to ensure that page sizes will not exceed what can be represented by a signed 32-bit integer. Also fixes some bounds checking that is no longer correct given changes made to the max page fragment size, and changes the column_index_truncation_length from `size_type` (which was used incorrectly) to `int32_t`. Authors: - Ed Seidl (https://github.com/etseidl) Approvers: - Vukasin Milovanovic (https://github.com/vuule) - Bradley Dice (https://github.com/bdice) URL: #12277
Description
When calculating page boundaries, the current Parquet writer does not take into account storage needed per page for repetition and definition level data. As a consequence pages may sometimes exceed the specified limit, which in turn impacts the ability to compress these pages with codecs that have a maximum buffer size. This PR fixes the page size calculation to take repetition and definition levels into account.
This also incorporates the fragment size reduction from 5000 to 1000 that was suggested in #12130Checklist