Repository navigation
Persist ORC calendar metadata and support legacy DATE rebasing in C++ #24733
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
base: main
Are you sure you want to change the base?
Changes from 3 commits
3468260
70eeb18
db4aedb
c941fc6
f33c38b
82fec42
3e8599b
d430a1e
c3d622a
7703f64
f2595dc
4105b7e
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 |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cudf/types.hpp> | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| namespace cudf::io::orc::detail { | ||
|
|
||
| // Epoch days of 1582-10-15. Earlier hybrid dates use the Julian calendar. | ||
| constexpr int32_t calendar_cutover = -141'427; | ||
|
|
||
| CUDF_HOST_DEVICE constexpr int64_t floor_div(int64_t value, int64_t divisor) | ||
| { | ||
| return value / divisor - (value % divisor < 0); | ||
| } | ||
|
|
||
| /** | ||
| * @brief Convert epoch days while preserving the civil year, month, and day. | ||
| * | ||
| * March-based 400-year Gregorian and 4-year Julian cycles keep intermediate values positive | ||
| * within each cycle, including for astronomical years zero and below. All arithmetic is 64 bit | ||
| * so that the complete int32 DATE domain can be checked before narrowing the result. | ||
| */ | ||
| template <bool to_hybrid> | ||
| CUDF_HOST_DEVICE constexpr int64_t rebase_days(int64_t days) | ||
|
Contributor
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 direction only shows up as a bool at the call sites (
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. Added. |
||
| { | ||
| if (days >= calendar_cutover) { return days; } | ||
|
|
||
| constexpr int64_t gregorian_epoch_offset = 719'468; | ||
| constexpr int64_t julian_epoch_offset = 719'470; | ||
| constexpr int64_t gregorian_era_days = 146'097; | ||
| constexpr int64_t julian_era_days = 1'461; | ||
| constexpr auto source_era_days = to_hybrid ? gregorian_era_days : julian_era_days; | ||
| auto const z = days + (to_hybrid ? gregorian_epoch_offset : julian_epoch_offset); | ||
| auto const era = floor_div(z, source_era_days); | ||
| auto const doe = z - era * source_era_days; | ||
| auto const yoe = to_hybrid ? (doe - doe / 1'460 + doe / 36'524 - doe / 146'096) / 365 | ||
| : (doe == 1'460 ? 3 : doe / 365); | ||
|
vuule marked this conversation as resolved.
Resolved
|
||
| auto const year = yoe + era * (to_hybrid ? 400 : 4); | ||
| auto const doy = doe - (365 * yoe + (to_hybrid ? yoe / 4 - yoe / 100 : 0)); | ||
| auto const mp = (5 * doy + 2) / 153; | ||
|
vuule marked this conversation as resolved.
Resolved
|
||
| auto const day = doy - (153 * mp + 2) / 5 + 1; | ||
|
|
||
| if constexpr (to_hybrid) { | ||
| return 365 * year + floor_div(year, 4) + (153 * mp + 2) / 5 + day - 1 - julian_epoch_offset; | ||
| } else { | ||
| return 365 * year + floor_div(year, 4) - floor_div(year, 100) + floor_div(year, 400) + | ||
| (153 * mp + 2) / 5 + day - 1 - gregorian_epoch_offset; | ||
| } | ||
| } | ||
|
|
||
| template <bool to_hybrid> | ||
| CUDF_HOST_DEVICE constexpr bool is_representable_date(int64_t original, int64_t rebased) | ||
| { | ||
| // The hybrid cutover gap and Julian-only leap days have no lossless counterpart. | ||
| return rebased >= INT32_MIN and rebased <= INT32_MAX and | ||
| rebase_days<!to_hybrid>(rebased) == original; | ||
| } | ||
|
|
||
| } // namespace cudf::io::orc::detail | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cudf/types.hpp> | ||
|
|
||
| #include <cuda/atomic> | ||
|
|
||
| namespace cudf::io::orc::detail { | ||
|
|
||
| /** | ||
| * @brief Record a decoding failure without a shared error count wrapping back to zero. | ||
| * | ||
| * The reader checks for any error after synchronizing the decoding stream. Columns and | ||
| * stripes share the same status, so their combined number of failures is not row-count bounded. | ||
| */ | ||
| inline __device__ void set_decode_error(size_type* status) | ||
|
vuule marked this conversation as resolved.
Resolved
|
||
| { | ||
| cuda::atomic_ref<size_type, cuda::thread_scope_device> error{*status}; | ||
| error.fetch_or(1, cuda::std::memory_order_relaxed); | ||
| } | ||
|
|
||
| } // namespace cudf::io::orc::detail | ||
Uh oh!
There was an error while loading. Please reload this page.