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

[BUG] Segmentation fault when working on a transposed numpy array with first dimension 1. #393

Open
RubendeBruin opened this issue Nov 19, 2021 · 2 comments
Assignees
Labels

Comments

@RubendeBruin
Copy link

Issue raised as follow-up to: pydata/xarray#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

@cgohlke
Copy link
Contributor

cgohlke commented Nov 21, 2021

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

@cgohlke
Copy link
Contributor

cgohlke commented Nov 24, 2021

Probably a duplicate of #381 and fixed by #382.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants