Avatar for the xtensor-stack user
xtensor-stack
xtensor
BlogDocsChangelog

Performance History

Latest Results

Updated find strides
spectre-ns:sfinae-to-constexpr
4 hours ago
formatting
spectre-ns:sfinae-to-constexpr
13 hours ago
Formatting
spectre-ns:sfinae-to-constexpr
13 hours ago
first stage of eliminating sfinae
spectre-ns:sfinae-to-constexpr
13 hours ago
Fix infinite loop in xt::roll on arrays with a zero-length dimension (#2922) # Checklist - [x] The title and commit message(s) are descriptive. - [x] Small commits made to fix your PR have been squashed to avoid history pollution. - [x] Tests have been added for new features or bug fixes. - [x] API of new functions and classes are documented. *(N/A — bug fix only, no API change)* # Description `xt::roll` enters an infinite loop (and then divides by zero) when the input has a zero-length axis: - No-axis overload `roll(e, shift)` when `e.size() == 0`: `while (shift < 0) shift += flat_size;` loops forever with `flat_size == 0`, then `shift %= 0` is undefined behaviour. - Axis-aware overload `roll(e, shift, axis)` when the rolled axis has length 0: same issue on `axis_dim == 0`. ### Fix For a shape $s = (s_0, \dots, s_{n-1})$, if $\exists k: s_k = 0$, then $\mathrm{roll}(a, \mathrm{shift}, \mathrm{axis}) = a$, i.e. roll is the identity. In both overloads, after constructing `cpy = empty_like(e)`, return `cpy` early when `cpy.size() == 0`. The no-axis overload's hand-rolled `std::accumulate(shape, 1L, multiplies<size_t>())` is replaced by `cpy.size()` (numerically equivalent, and O(1) on contiguous layouts). When the rolled axis is non-empty but another axis has length 0 (e.g. `shape={3,0,4}` rolled along axis 0), the original code didn't loop — `detail::roll`'s inner loops became no-ops because the stride product collapses to 0 — but the recursion was wasted work. The widened guard `cpy.size() == 0` skips it cleanly. Observable output is unchanged. ### Tests Three regression cases in `test_xmanipulation.cpp`, one per code path: | Shape | Axis | Path exercised | |-------------|---------|-----------------------------------------------| | `{0}` | (ravel) | no-axis overload's empty-input guard | | `{3, 0}` | `1` | axis-aware overload, rolled axis itself is 0 | | `{3, 0, 4}` | `0` | axis-aware overload, *other* axis is 0 | All `test_xmanipulation` tests pass: 28 cases, 188 assertions. Verified against `numpy.roll`, which returns a same-shape empty array for these inputs.
master
9 days ago
fix: handle empty arrays in xt::roll to avoid infinite loop
f14XuanLv:fix/roll-empty-array
10 days ago
fix format
Alex-PLACET:codspeed_runner
10 days ago

Latest Branches

CodSpeed Performance Gauge
0%
Partial elimination of TMP from xutils.hpp and patches for dependencies#2923
4 hours ago
62d19f4
spectre-ns:sfinae-to-constexpr
CodSpeed Performance Gauge
0%
Fix infinite loop in xt::roll on arrays with a zero-length dimension#2922
11 days ago
10a24af
f14XuanLv:fix/roll-empty-array
CodSpeed Performance Gauge
N/A
10 days ago
2d08eb6
Alex-PLACET:codspeed_runner
© 2026 CodSpeed Technology
Home Terms Privacy Docs