You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$ cargo run --profile=devOne 1thread 'main' has overflowed its stackfatal runtime error: stack overflow
$ cargo run --profile=releaseOne 1Two 1thread 'main' has overflowed its stackfatal runtime error: stack overflow
Expected behavior
One 1
Two 1
Three 1
Additional context
I'm able to reproduce this issue on both Linux and macOS with the default stack limit of 8 MiB. (ulimit -s reports 8192)
The result is non-deterministic. Re-running the executable can succeed sometimes and fail sometimes. The larger the vector the more likely it is to fail.
The result depends on whether optimization is enabled.
Exceeding the stack limit suggests to me either infinite recursion or a large data structure is being placed on the heap. I don't see an obvious source of either of those causes in the code. It's possible that more generalized memory corruption could cause this behaviour.
Looks like this recursive function call _get_many_from_sorted_mut_unchecked is recursing probably not infinitely but once per size of the vector, and blowing through the stack, perhaps because all the elements in the array are equal. (thanks to @evolvedmicrobe for discovering)
I checked, and #80 doesn't fix this issue as-is. It's a bit tricky to avoid stack overflow with the recursive algorithm for large arrays with all equal elements. At first glance, I suspect that the best fix would be for partitioning to handle == pivot and > pivot elements separately, instead of grouping them together. Please feel free to contribute a fix. Otherwise, I'll work on it when I get a chance (which may be a while).
Thank you for checking, Jim! I have a work around for now using slice:sort_unstable. I'd like to get to fixing this issue, but it similarly may be a while. I'll post my workaround below, in case anyone else stumbles on this issue.
/// Return the median. Sorts its argument in place.pubfnmedian_mut<T>(xs:&mutArray1<T>) -> Result<T,QuantileError>whereT:Clone + Copy + Ord + FromPrimitive,T:Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T> + Rem<Output = T>,{iffalse{// quantile_mut may fail with the error: fatal runtime error: stack overflow// See https://github.com/rust-ndarray/ndarray-stats/issues/86
xs.quantile_mut(n64(0.5),&Midpoint)}else{if xs.is_empty(){returnErr(QuantileError::EmptyInput);}
xs.as_slice_mut().unwrap().sort_unstable();Ok(if xs.len() % 2 == 0{(xs[xs.len() / 2] + xs[xs.len() / 2 - 1]) / (T::from_u64(2).unwrap())}else{
xs[xs.len() / 2]})}}
Activity
sjackman commentedon Mar 4, 2022
Exceeding the stack limit suggests to me either infinite recursion or a large data structure is being placed on the heap. I don't see an obvious source of either of those causes in the code. It's possible that more generalized memory corruption could cause this behaviour.
ndarray-stats/src/quantile/mod.rs
Lines 437 to 498 in 9ed9373
sjackman commentedon Mar 5, 2022
ndarray-stats/src/sort.rs
Line 293 in b6628c6
Looks like this recursive function call
_get_many_from_sorted_mut_uncheckedis recursing probably not infinitely but once per size of the vector, and blowing through the stack, perhaps because all the elements in the array are equal. (thanks to @evolvedmicrobe for discovering)jturner314 commentedon Mar 5, 2022
I think this issue may be fixed by #80; I'll take another look at that PR this weekend to see if we can get it merged.
jturner314 commentedon Mar 7, 2022
I checked, and #80 doesn't fix this issue as-is. It's a bit tricky to avoid stack overflow with the recursive algorithm for large arrays with all equal elements. At first glance, I suspect that the best fix would be for partitioning to handle
== pivotand> pivotelements separately, instead of grouping them together. Please feel free to contribute a fix. Otherwise, I'll work on it when I get a chance (which may be a while).sjackman commentedon Mar 7, 2022
Thank you for checking, Jim! I have a work around for now using
slice:sort_unstable. I'd like to get to fixing this issue, but it similarly may be a while. I'll post my workaround below, in case anyone else stumbles on this issue.