8000 API: Change Flags Updateing to allow C-/F-contiguous arrays · seberg/numpy@c48156d · GitHub
[go: up one dir, main page]

Skip to content

Commit c48156d

Browse files
committed
API: Change Flags Updateing to allow C-/F-contiguous arrays
This changes UpdateFlags to ignore 1-dimensional axis when setting C-/F-contiguous flags. Updates both flags always now.
1 parent 44f83e2 commit c48156d

File tree

1 file changed

+45
-62
lines changed

1 file changed

+45
-62
lines changed

numpy/core/src/multiarray/flagsobject.c

Lines changed: 45 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@
1515

1616
#include "common.h"
1717

18-
static int
19-
_IsContiguous(PyArrayObject *ap);
20-
21-
static int
22-
_IsFortranContiguous(PyArrayObject *ap);
18+
static void
19+
_UpdateContiguousFlags(PyArrayObject *ap);
2320

2421
/*NUMPY_API
2522
*
@@ -62,28 +59,9 @@ PyArray_NewFlagsObject(PyObject *obj)
6259
NPY_NO_EXPORT void
6360
PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
6461
{
65-
66-
if (flagmask & NPY_ARRAY_F_CONTIGUOUS) {
67-
if (_IsFortranContiguous(ret)) {
68-
PyArray_ENABLEFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
69-
if (PyArray_NDIM(ret) > 1) {
70-
PyArray_CLEARFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
71-
}
72-
}
73-
else {
74-
PyArray_CLEARFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
75-
}
76-
}
77-
if (flagmask & NPY_ARRAY_C_CONTIGUOUS) {
78-
if (_IsContiguous(ret)) {
79-
PyArray_ENABLEFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
80-
if (PyArray_NDIM(ret) > 1) {
81-
PyArray_CLEARFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
82-
}
83-
}
84-
else {
85-
PyArray_CLEARFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
86-
}
62+
/* Always update both, as its not trivial to guess one from the other */
63+
if (flagmask & (NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_C_CONTIGUOUS)) {
64+
_UpdateContiguousFlags(ret);
8765
}
8866
if (flagmask & NPY_ARRAY_ALIGNED) {
8967
if (_IsAligned(ret)) {
@@ -110,66 +88,71 @@ PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
11088

11189
/*
11290
* Check whether the given array is stored contiguously
113-
* (row-wise) in memory.
91+
* in memory. And update the passed in ap apropriately.
11492
*
115-
* 0-strided arrays are not contiguous (even if dimension == 1)
93+
* 0-strided arrays are not contiguous. A dimension == 1 is always ok.
11694
*/
117-
static int
118-
_IsContiguous(PyArrayObject *ap)
95+
static void
96+
_UpdateContiguousFlags(PyArrayObject *ap)
11997
{
12098
npy_intp sd;
12199
npy_intp dim;
122100
int i;
101+
npy_bool is_c_contig = 1;
123102

124103
if (PyArray_NDIM(ap) == 0) {
125-
return 1;
104+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
105+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
106+
return;
126107
}
127108
sd = PyArray_DESCR(ap)->elsize;
128109
if (PyArray_NDIM(ap) == 1) {
129-
return PyArray_DIMS(ap)[0] == 1 || sd == PyArray_STRIDES(ap)[0];
110+
if (PyArray_DIMS(ap)[0] == 1 || sd == PyArray_STRIDES(ap)[0]) {
111+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
112+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
113+
return;
114+
}
115+
PyArray_CLEARFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
116+
PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
117+
return;
130118
}
119+
131120
for (i = PyArray_NDIM(ap) - 1; i >= 0; --i) {
132121
dim = PyArray_DIMS(ap)[i];
133122
/* contiguous by definition */
134123
if (dim == 0) {
135-
return 1;
124+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
125+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
126+
return;
136127
}
137-
if (PyArray_STRIDES(ap)[i] != sd) {
138-
return 0;
128+
if (dim != 1) {
129+
if (PyArray_STRIDES(ap)[i] != sd) {
130+
is_c_contig = 0;
131+
}
132+
sd *= dim;
139133
}
140-
sd *= dim;
141134
}
142-
return 1;
143-
}
144-
145-
146-
/* 0-strided arrays are not contiguous (even if dimension == 1) */
147-
static int
148-
_IsFortranContiguous(PyArrayObject *ap)
149-
{
150-
npy_intp sd;
151-
npy_intp dim;
152-
int i;
153-
154-
if (PyArray_NDIM(ap) == 0) {
155-
return 1;
135+
if (is_c_contig) {
136+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
156137
}
157-
sd = PyArray_DESCR(ap)->elsize;
158-
if (PyArray_NDIM(ap) == 1) {
159-
return PyArray_DIMS(ap)[0] == 1 || sd == PyArray_STRIDES(ap)[0];
138+
else {
139+
PyArray_CLEARFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
160140
}
141+
142+
/* check if fortran contiguous */
143+
sd = PyArray_DESCR(ap)->elsize;
161144
for (i = 0; i < PyArray_NDIM(ap); ++i) {
162145
dim = PyArray_DIMS(ap)[i];
163-
/* fortran contiguous by definition */
164-
if (dim == 0) {
165-
return 1;
166-
}
167-
if (PyArray_STRIDES(ap)[i] != sd) {
168-
return 0;
146+
if (dim != 1) {
147+
if (PyArray_STRIDES(ap)[i] != sd) {
148+
PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
149+
return;
150+
}
151+
sd *= dim;
169152
}
170-
sd *= dim;
171153
}
172-
return 1;
154+
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
155+
return;
173156
}
174157

175158
static void

0 commit comments

Comments
 (0)
0