[BUG] Segmentation fault when working on a transposed numpy array with first dimension 1.
Issue raised as follow-up to: https://github.com/pydata/xarray/issues/6002
Reproduce
import numpy as np
import bottleneck as bn
n_time = 1
spec_data = np.random.random(size=(n_time,192,121))
bn.nanmax(spec_data.transpose(0, 2, 1))
---> Segmentation fault
numpy.transpose returns a view, so I guess that's what causes bottleneck to segfault? Not sure, though, especially since changing the order does not trigger the segfault: spec_data.transpose(1, 0, 2)... maybe bottleneck doesn't like views with a first dimension of size 1?
Expected behaviour Should not crash
Environment Confirmed Windows & Linux , P37 and P39.
confirmed with: bottleneck: 1.3.2 numpy: 1.21.4
The issue seems that the transposed array is F_CONTIGUOUS and bottleneck wrongly uses the first non-zero stride for iteration. This patch fixes this issue for me ~~but I have not tested it thoroughly~~ on Windows:
diff --git a/bottleneck/include/iterators.h b/bottleneck/include/iterators.h
index 1f5120a..c70c46a 100644
--- a/bottleneck/include/iterators.h
+++ b/bottleneck/include/iterators.h
@@ -108,7 +108,7 @@ static inline void init_iter_all(iter *it, PyArrayObject *a, int ravel, int anyo
for (i = ndim - 1; i > -1; i--) {
/* protect against length zero strides such as in
* np.ones((2, 2))[..., np.newaxis] */
- if (strides[i] == 0) {
+ if ((strides[i] == 0) || (shape[i] == 1)) {
continue;
}
it->astride = strides[i];
@@ -122,7 +122,7 @@ static inline void init_iter_all(iter *it, PyArrayObject *a, int ravel, int anyo
for (i = 0; i < ndim; i++) {
/* protect against length zero strides such as in
* np.ones((2, 2), order='F')[np.newaxis, ...] */
- if (strides[i] == 0) {
+ if ((strides[i] == 0) || (shape[i] == 1)) {
continue;
}
it->astride = strides[i];
The shape, strides, and flags of the transposed array are:
(1, 121, 192)
(185856, 8, 968)
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : False
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
Probably a duplicate of #381 and fixed by #382.