10000 ENH: Make 1-dimensional axes not matter for contiguous flags by seberg · Pull Request #2694 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Make 1-dimensional axes not matter for contiguous flags #2694

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

Merged
merged 12 commits into from
Oct 25, 2012
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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.
  • Loading branch information
seberg committed Oct 21, 2012
commit c48156dfdc408f0a1e59ef54ac490cccbd6b8d73
107 changes: 45 additions & 62 deletions numpy/core/src/multiarray/flagsobject.c
8F4E
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@

#include "common.h"

static int
_IsContiguous(PyArrayObject *ap);

static int
_IsFortranContiguous(PyArrayObject *ap);
static void
_UpdateContiguousFlags(PyArrayObject *ap);

/*NUMPY_API
*
Expand Down Expand Up @@ -62,28 +59,9 @@ PyArray_NewFlagsObject(PyObject *obj)
NPY_NO_EXPORT void
PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
{

if (flagmask & NPY_ARRAY_F_CONTIGUOUS) {
if (_IsFortranContiguous(ret)) {
PyArray_ENABLEFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
if (PyArray_NDIM(ret) > 1) {
PyArray_CLEARFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
}
}
else {
PyArray_CLEARFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
}
}
if (flagmask & NPY_ARRAY_C_CONTIGUOUS) {
if (_IsContiguous(ret)) {
PyArray_ENABLEFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
if (PyArray_NDIM(ret) > 1) {
PyArray_CLEARFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
}
}
else {
PyArray_CLEARFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
}
/* Always update both, as its not trivial to guess one from the other */
if (flagmask & (NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_C_CONTIGUOUS)) {
_UpdateContiguousFlags(ret);
}
if (flagmask & NPY_ARRAY_ALIGNED) {
if (_IsAligned(ret)) {
Expand All @@ -110,66 +88,71 @@ PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)

/*
* Check whether the given array is stored contiguously
* (row-wise) in memory.
* in memory. And update the passed in ap apropriately.
*
* 0-strided arrays are not contiguous (even if dimension == 1)
* 0-strided arrays are not contiguous. A dimension == 1 is always ok.
*/
static int
_IsContiguous(PyArrayObject *ap)
static void
_UpdateContiguousFlags(PyArrayObject *ap)
{
npy_intp sd;
npy_intp dim;
int i;
npy_bool is_c_contig = 1;

if (PyArray_NDIM(ap) == 0) {
return 1;
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
return;
}
sd = PyArray_DESCR(ap)->elsize;
if (PyArray_NDIM(ap) == 1) {
return PyArray_DIMS(ap)[0] == 1 || sd == PyArray_STRIDES(ap)[0];
if (PyArray_DIMS(ap)[0] == 1 || sd == PyArray_STRIDES(ap)[0]) {
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
return;
}
PyArray_CLEARFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to just delete these special cases for 0- and 1-d arrays, since it's simpler to just handle them as part of the general case?

}

for (i = PyArray_NDIM(ap) - 1; i >= 0; --i) {
dim = PyArray_DIMS(ap)[i];
/* contiguous by definition */
if (dim == 0) {
return 1;
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
return;
}
if (PyArray_STRIDES(ap)[i] != sd) {
return 0;
if (dim != 1) {
if (PyArray_STRIDES(ap)[i] != sd) {
is_c_contig = 0;
}
sd *= dim;
}
sd *= dim;
}
return 1;
}


/* 0-strided arrays are not contiguous (even if dimension == 1) */
static int
_IsFortranContiguous(PyArrayObject *ap)
{
npy_intp sd;
npy_intp dim;
int i;

if (PyArray_NDIM(ap) == 0) {
return 1;
if (is_c_contig) {
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
}
sd = PyArray_DESCR(ap)->elsize;
if (PyArray_NDIM(ap) == 1) {
return PyArray_DIMS(ap)[0] == 1 || sd == PyArray_STRIDES(ap)[0];
else {
PyArray_CLEARFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
}

/* check if fortran contiguous */
sd = PyArray_DESCR(ap)->elsize;
for (i = 0; i < PyArray_NDIM(ap); ++i) {
dim = PyArray_DIMS(ap)[i];
/* fortran contiguous by definition */
if (dim == 0) {
return 1;
}
if (PyArray_STRIDES(ap)[i] != sd) {
return 0;
if (dim != 1) {
if (PyArray_STRIDES(ap)[i] != sd) {
PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
return;
}
sd *= dim;
}
sd *= dim;
}
return 1;
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
return;
}

static void
Expand Down
0