Skip to content
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

Fail loudly to avoid data corruption with unsupported input in read_orc #12325

Merged

Conversation

vuule
Copy link
Contributor

@vuule vuule commented Dec 6, 2022

Description

Issue #11890

Motivating issue: The ORC reader reads nulls in row groups after the first one when reading a string column encoded with Pandas, with direct encoding. The root cause is that cuDF reads offsets from the row group index as larger then the stream sizes.

This PR does not fix the issue, but ensures that the reader fails loudly when the row group index offsets are read as too large to be correct. This should prevent data corruption until the fix is implemented.

This PR also sets up a mechanism to report decode errors from unsupported data.

Checklist

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

@vuule vuule added bug Something isn't working cuIO cuIO issue breaking Breaking change labels Dec 6, 2022
@vuule vuule self-assigned this Dec 6, 2022
@github-actions github-actions bot added Python Affects Python cuDF API. libcudf Affects libcudf (C++/CUDA) code. labels Dec 6, 2022
@codecov
Copy link

codecov bot commented Dec 7, 2022

Codecov Report

Base: 88.37% // Head: 86.56% // Decreases project coverage by -1.80% ⚠️

Coverage data is based on head (4653907) compared to base (a9f9958).
Patch coverage: 96.19% of modified lines in pull request are covered.

❗ Current head 4653907 differs from pull request most recent head 5bf0f37. Consider uploading reports for the commit 5bf0f37 to get more accurate results

Additional details and impacted files
@@               Coverage Diff                @@
##           branch-23.02   #12325      +/-   ##
================================================
- Coverage         88.37%   86.56%   -1.81%     
================================================
  Files               137      155      +18     
  Lines             22657    24510    +1853     
================================================
+ Hits              20022    21218    +1196     
- Misses             2635     3292     +657     
Impacted Files Coverage Δ
python/cudf/cudf/core/column/column.py 87.95% <ø> (-0.03%) ⬇️
python/dask_cudf/dask_cudf/core.py 73.90% <ø> (-0.31%) ⬇️
python/dask_cudf/dask_cudf/groupby.py 97.36% <ø> (ø)
python/dask_cudf/dask_cudf/io/tests/test_csv.py 100.00% <ø> (ø)
python/dask_cudf/dask_cudf/io/tests/test_json.py 100.00% <ø> (ø)
python/dask_cudf/dask_cudf/io/tests/test_orc.py 100.00% <ø> (ø)
...ython/dask_cudf/dask_cudf/io/tests/test_parquet.py 100.00% <ø> (ø)
python/dask_cudf/dask_cudf/tests/test_core.py 95.42% <ø> (-0.02%) ⬇️
python/cudf/cudf/core/dataframe.py 93.49% <66.66%> (-0.18%) ⬇️
python/cudf/cudf/core/_base_index.py 81.38% <100.00%> (+0.22%) ⬆️
... and 35 more

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.
📢 Do you have feedback about the report comment? Let us know in this issue.

@vuule vuule changed the title Fail loudly to avoid data corruption in read_orc Fail loudly to avoid data corruption with unsupported input in read_orc Dec 8, 2022
@vuule vuule marked this pull request as ready for review December 8, 2022 01:17
@vuule vuule requested review from a team as code owners December 8, 2022 01:17
@@ -287,6 +287,7 @@ void DecodeNullsAndStringDictionaries(ColumnDesc* chunks,
* @param[in] num_rowgroups Number of row groups in row index data
* @param[in] rowidx_stride Row index stride
* @param[in] level Current nesting level being processed
* @param[out] error_count Number of errors during decode
Copy link
Contributor

@ttnghia ttnghia Dec 8, 2022

Choose a reason for hiding this comment

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

Why not just return this number, instead of using the void return type and modifying this parameter? I understand that this may be a pointer to device memory but we will read it to host anyway, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

DecodeOrcColumnData is asynchronous. The fact that we copy chunks to host immediately after calling DecodeOrcColumnData should not impact how its implemented. If we return the error code we are enforcing this synchronization even though it might not be required otherwise.

Copy link
Contributor

@wence- wence- left a comment

Choose a reason for hiding this comment

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

Comment on the xfail in the test (sorry this was a bit delayed)

Comment on lines 1847 to 1855
try:
got = cudf.read_orc(buffer)
except RuntimeError:
pytest.mark.xfail(
reason="Unsupported file, "
"see https://github.com/rapidsai/cudf/issues/11890"
)
else:
assert_eq(expected, got)
Copy link
Contributor

Choose a reason for hiding this comment

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

This block of code is probably not doing what you want. I think the conditions you want to handle are:

  1. The read fails with RuntimeError (this is an expected failure)
  2. The read succeeds (and then we expect the data to match)
  3. The read fails with some other error (this is an unexpected failure)

To handle this I think you want:

@pytest.mark.xfail(reason="https://github.com/rapidsai/cudf/issues/11890", raises=RuntimeError)
def test_reader_unsupported_offsets():
     expect = ...
     got = ...
     assert_eq(expect, got)

pytest.mark.xfail Doesn't do anything programmatically, so as written your "except RuntimeError" block just turns into a test pass.

With #12244, as soon as the bug is fixed, this marked test will turn into a failure (an unexpected pass) so we will be reminded to remove the mark.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, thank you

@vuule vuule changed the base branch from branch-23.02 to branch-22.12 December 9, 2022 20:22
@vuule vuule changed the base branch from branch-22.12 to branch-23.02 December 9, 2022 20:22
Copy link
Contributor

@hyperbolic2346 hyperbolic2346 left a comment

Choose a reason for hiding this comment

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

I think IO is a special beast as far as the cudf mantra of not validating input. I also think in this case there isn't really any extra overhead to do it. I like this change.

@vuule vuule added the 5 - Ready to Merge Testing and reviews complete, ready to merge label Dec 12, 2022
@vuule
Copy link
Contributor Author

vuule commented Dec 12, 2022

@gpucibot merge

@rapids-bot rapids-bot bot merged commit 8a40902 into rapidsai:branch-23.02 Dec 12, 2022
@vuule vuule deleted the bug-read_orc-strm-ofst-loud-fail branch August 10, 2023 03:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5 - Ready to Merge Testing and reviews complete, ready to merge breaking Breaking change bug Something isn't working cuIO cuIO issue libcudf Affects libcudf (C++/CUDA) code. Python Affects Python cuDF API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants