mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #22445: PyBuffer_IsContiguous() now implements precise contiguity
tests, compatible with NumPy's NPY_RELAXED_STRIDES_CHECKING compilation flag. Previously the function reported false negatives for corner cases.
This commit is contained in:
parent
a5e1dbef14
commit
363af44a4a
4 changed files with 90 additions and 29 deletions
|
@ -367,16 +367,35 @@ _IsFortranContiguous(const Py_buffer *view)
|
|||
Py_ssize_t sd, dim;
|
||||
int i;
|
||||
|
||||
if (view->ndim == 0) return 1;
|
||||
if (view->strides == NULL) return (view->ndim == 1);
|
||||
/* 1) len = product(shape) * itemsize
|
||||
2) itemsize > 0
|
||||
3) len = 0 <==> exists i: shape[i] = 0 */
|
||||
if (view->len == 0) return 1;
|
||||
if (view->strides == NULL) { /* C-contiguous by definition */
|
||||
/* Trivially F-contiguous */
|
||||
if (view->ndim <= 1) return 1;
|
||||
|
||||
/* ndim > 1 implies shape != NULL */
|
||||
assert(view->shape != NULL);
|
||||
|
||||
/* Effectively 1-d */
|
||||
sd = 0;
|
||||
for (i=0; i<view->ndim; i++) {
|
||||
if (view->shape[i] > 1) sd += 1;
|
||||
}
|
||||
return sd <= 1;
|
||||
}
|
||||
|
||||
/* strides != NULL implies both of these */
|
||||
assert(view->ndim > 0);
|
||||
assert(view->shape != NULL);
|
||||
|
||||
sd = view->itemsize;
|
||||
if (view->ndim == 1) return (view->shape[0] == 1 ||
|
||||
sd == view->strides[0]);
|
||||
for (i=0; i<view->ndim; i++) {
|
||||
dim = view->shape[i];
|
||||
if (dim == 0) return 1;
|
||||
if (view->strides[i] != sd) return 0;
|
||||
if (dim > 1 && view->strides[i] != sd) {
|
||||
return 0;
|
||||
}
|
||||
sd *= dim;
|
||||
}
|
||||
return 1;
|
||||
|
@ -388,16 +407,22 @@ _IsCContiguous(const Py_buffer *view)
|
|||
Py_ssize_t sd, dim;
|
||||
int i;
|
||||
|
||||
if (view->ndim == 0) return 1;
|
||||
if (view->strides == NULL) return 1;
|
||||
/* 1) len = product(shape) * itemsize
|
||||
2) itemsize > 0
|
||||
3) len = 0 <==> exists i: shape[i] = 0 */
|
||||
if (view->len == 0) return 1;
|
||||
if (view->strides == NULL) return 1; /* C-contiguous by definition */
|
||||
|
||||
/* strides != NULL implies both of these */
|
||||
assert(view->ndim > 0);
|
||||
assert(view->shape != NULL);
|
||||
|
||||
sd = view->itemsize;
|
||||
if (view->ndim == 1) return (view->shape[0] == 1 ||
|
||||
sd == view->strides[0]);
|
||||
for (i=view->ndim-1; i>=0; i--) {
|
||||
dim = view->shape[i];
|
||||
if (dim == 0) return 1;
|
||||
if (view->strides[i] != sd) return 0;
|
||||
if (dim > 1 && view->strides[i] != sd) {
|
||||
return 0;
|
||||
}
|
||||
sd *= dim;
|
||||
}
|
||||
return 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue