8000 MAINT: Remove the RELAXED_STRIDES_CHECKING env variable · numpy/numpy@f6d9577 · GitHub
[go: up one dir, main page]

Skip to content

Commit f6d9577

Browse files
committed
MAINT: Remove the RELAXED_STRIDES_CHECKING env variable
An error is for now raised in `setup.py` if this is set, eventually we should just delete that.
1 parent f69ddd7 commit f6d9577

File tree

16 files changed

+56
-168
lines changed

16 files changed

+56
-168
lines changed

.github/actions/action.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ runs:
77
shell: bash
88
run: |
99
echo NPY_RELAXED_STRIDES_DEBUG $NPY_RELAXED_STRIDES_DEBUG
10-
echo NPY_RELAXED_STRIDES_CHECKING $NPY_RELAXED_STRIDES_CHECKING
1110
echo CHECK_BLAS $CHECK_BLAS
1211
echo DOWNLOAD_OPENBLAS $DOWNLOAD_OPENBLAS
1312
echo USE_DEBUG $USE_DEBUG

.github/workflows/build_test.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ jobs:
140140
needs: [smoke_test]
141141
runs-on: ubuntu-latest
142142
env:
143-
NPY_RELAXED_STRIDES_CHECKING: 0
144143
CHECK_BLAS: 1
145144
NPY_USE_BLAS_ILP64: 1
146145
steps:

doc/source/reference/arrays.ndarray.rst

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -161,26 +161,15 @@ An array is considered aligned if the memory offsets for all elements and the
161161
base offset itself is a multiple of `self.itemsize`. Understanding
162162
`memory-alignment` leads to better performance on most hardware.
163163

164-
.. note::
165-
166-
Points (1) and (2) can currently be disabled by the compile time
167-
environmental variable ``NPY_RELAXED_STRIDES_CHECKING=0``,
168-
which was the default before NumPy 1.10.
169-
No users should have to do this. ``NPY_RELAXED_STRIDES_DEBUG=1``
170-
can be used to help find errors when incorrectly relying on the strides
171-
in C-extension code (see below warning).
172-
173-
You can check whether this option was enabled when your NumPy was
174-
built by looking at the value of ``np.ones((10,1),
175-
order='C').flags.f_contiguous``. If this is ``True``, then your
176-
NumPy has relaxed strides checking enabled.
177-
178164
.. warning::
179165

180166
It does *not* generally hold that ``self.strides[-1] == self.itemsize``
181167
for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for
182168
Fortran-style contiguous arrays is true.
183169

170+
``NPY_RELAXED_STRIDES_DEBUG=1`` can be used to help find errors when
171+
incorrectly relying on the strides in C-extension code (see below warning).
172+
184173
Data in new :class:`ndarrays <ndarray>` is in the :term:`row-major`
185174
(C) order, unless otherwise specified, but, for example, :ref:`basic
186175
array slicing <arrays.indexing>` often produces :term:`views <view>`

doc/source/reference/global_state.rst

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,15 @@ Debugging-Related Options
7070
Relaxed Strides Checking
7171
------------------------
7272

73-
The *compile-time* environment variables::
73+
The *compile-time* environment variable::
7474

7575
NPY_RELAXED_STRIDES_DEBUG=0
76-
NPY_RELAXED_STRIDES_CHECKING=1
77-
78-
control how NumPy reports contiguity for arrays.
79-
The default that it is enabled and the debug mode is disabled.
80-
This setting should always be enabled. Setting the
81-
debug option can be interesting for testing code written
82-
in C which iterates through arrays that may or may not be
83-
contiguous in memory.
84-
Most users will have no reason to change these; for details
85-
see the :ref:`memory layout <memory-layout>` documentation.
76+
77+
can be set to help debug code written in C which iteraters through arrays
78+
manually. When an array is contiguous and iterated in a contiguous manner,
79+
its ``strides`` should not be queried. This option can help find errors where
80+
the ``strides`` are incorrectly used.
81+
For details see the :ref:`memory layout <memory-layout>` documentation.
8682

8783

8884
Warn if no memory allocation policy when deallocating data

numpy/core/include/numpy/ndarraytypes.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -834,11 +834,9 @@ typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
834834
* 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with
835835
* more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS
836836
* at the same time if they have either zero or one element.
837-
* If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional
838-
* array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements
839-
* and the array is contiguous if ndarray.squeeze() is contiguous.
840-
* I.e. dimensions for which `ndarray.shape[dimension] == 1` are
841-
* ignored.
837+
* A higher dimensional array is always C_CONTIGUOUS and F_CONTIGUOUS if it
838+
* has zero elements or when `array.squeeze()` is contiguous.
839+
* I.e. dimensions for which `array.shape[dimension] == 1` are ignored.
842840
*/
843841

844842
/*

numpy/core/setup.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
# Set to True to enable relaxed strides checking. This (mostly) means
1818
# that `strides[dim]` is ignored if `shape[dim] == 1` when setting flags.
1919
NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "1") != "0")
20+
if not NPY_RELAXED_STRIDES_CHECKING:
21+
raise SystemError(
22+
"Support for NPY_RELAXED_STRIDES_CHECKING=0 has been remove as of "
23+
"NumPy 1.23. This error will eventually be removed entirely.")
2024

2125
# Put NPY_RELAXED_STRIDES_DEBUG=1 in the environment if you want numpy to use a
2226
# bogus value for affected strides in order to help smoke out bad stride usage
@@ -481,13 +485,9 @@ def generate_config_h(ext, build_dir):
481485
if can_link_svml():
482486
moredefs.append(('NPY_CAN_LINK_SVML', 1))
483487

484-
# Use relaxed stride checking
485-
if NPY_RELAXED_STRIDES_CHECKING:
486-
moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
487-
else:
488-
moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 0))
489-
490-
# Use bogus stride debug aid when relaxed strides are enabled
488+
# Use bogus stride debug aid to flush out bugs where users use
489+
# strides of dimensions with length 1 to index a full contiguous
490+
# array.
491491
if NPY_RELAXED_STRIDES_DEBUG:
492492
moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1))
493493
else:
@@ -583,9 +583,6 @@ def generate_numpyconfig_h(ext, build_dir):
583583
moredefs.extend(cocache.check_ieee_macros(config_cmd)[1])
584584
moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1])
585585

586-
if NPY_RELAXED_STRIDES_CHECKING:
587-
moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
588-
589586
if NPY_RELAXED_STRIDES_DEBUG:
590587
moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1))
591588

numpy/core/src/common/array_assign.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ raw_array_is_aligned(int ndim, npy_intp const *shape,
110110
int i;
111111

112112
for (i = 0; i < ndim; i++) {
113-
#if NPY_RELAXED_STRIDES_CHECKING
114113
/* skip dim == 1 as it is not required to have stride 0 */
115114
if (shape[i] > 1) {
116115
/* if shape[i] == 1, the stride is never used */
@@ -120,9 +119,6 @@ raw_array_is_aligned(int ndim, npy_intp const *shape,
120119
/* an array with zero elements is always aligned */
121120
return 1;
122121
}
123-
#else /* not NPY_RELAXED_STRIDES_CHECKING */
124-
align_check |= (npy_uintp)strides[i];
125-
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
126122
}
127123

128124
return npy_is_aligned((void *)align_check, alignment);

numpy/core/src/multiarray/buffer.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,11 @@ _buffer_info_new(PyObject *obj, int flags)
498498
assert((size_t)info->shape % sizeof(npy_intp) == 0);
499499
info->strides = info->shape + PyArray_NDIM(arr);
500500

501-
#if NPY_RELAXED_STRIDES_CHECKING
502501
/*
503-
* When NPY_RELAXED_STRIDES_CHECKING is used, some buffer users
504-
* may expect a contiguous buffer to have well formatted strides
505-
* also when a dimension is 1, but we do not guarantee this
506-
* internally. Thus, recalculate strides for contiguous arrays.
507-
* (This is unnecessary, but has no effect in the case where
508-
* NPY_RELAXED_STRIDES CHECKING is disabled.)
502+
* Some buffer users may expect a contiguous buffer to have well
503+
* formatted strides also when a dimension is 1, but we do not
504+
* guarantee this internally. Thus, recalculate strides for
505+
* contiguous arrays.
509506
*/
510507
int f_contiguous = (flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS;
511508
if (PyArray_IS_C_CONTIGUOUS(arr) && !(
@@ -526,11 +523,6 @@ _buffer_info_new(PyObject *obj, int flags)
526523
}
527524
}
528525
else {
529-
#else /* NPY_RELAXED_STRIDES_CHECKING */
530-
/* We can always use the arrays strides directly */
531-
{
532-
#endif
533-
534526
for (k = 0; k < PyArray_NDIM(arr); ++k) {
535527
info->shape[k] = PyArray_DIMS(arr)[k];
536528
info->strides[k] = PyArray_STRIDES(arr)[k];
@@ -708,8 +700,8 @@ _buffer_get_info(void **buffer_info_cache_ptr, PyObject *obj, int flags)
708700
if (info->ndim > 1 && next_info != NULL) {
709701
/*
710702
* Some arrays are C- and F-contiguous and if they have more
711-
* than one dimension, the buffer-info may differ between
712-
* the two due to RELAXED_STRIDES_CHECKING.
703+
* than one dimension, the buffer-info may differ between the
704+
* two because strides for length 1 dimension may be adjusted.
713705
* If we export both buffers, the first stored one may be
714706
* the one for the other contiguity, so check both.
715707
* This is generally very unlikely in all other cases, since

numpy/core/src/multiarray/ctors.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4020,7 +4020,6 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
40204020
int inflag, int *objflags)
40214021
{
40224022
int i;
4023-
#if NPY_RELAXED_STRIDES_CHECKING
40244023
npy_bool not_cf_contig = 0;
40254024
npy_bool nod = 0; /* A dim != 1 was found */
40264025

@@ -4034,7 +4033,6 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
40344033
nod = 1;
40354034
}
40364035
}
4037-
#endif /* NPY_RELAXED_STRIDES_CHECKING */
40384036

40394037
/* Only make Fortran strides if not contiguous as well */
40404038
if ((inflag & (NPY_ARRAY_F_CONTIGUOUS|NPY_ARRAY_C_CONTIGUOUS)) ==
@@ -4044,7 +4042,6 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
40444042
if (dims[i]) {
40454043
itemsize *= dims[i];
40464044
}
4047-
#if NPY_RELAXED_STRIDES_CHECKING
40484045
else {
40494046
not_cf_contig = 0;
40504047
}
@@ -4054,13 +4051,8 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
40544051
strides[i] = NPY_MAX_INTP;
40554052
}
40564053
#endif /* NPY_RELAXED_STRIDES_DEBUG */
4057-
#endif /* NPY_RELAXED_STRIDES_CHECKING */
40584054
}
4059-
#if NPY_RELAXED_STRIDES_CHECKING
40604055
if (not_cf_contig) {
4061-
#else /* not NPY_RELAXED_STRIDES_CHECKING */
4062-
if ((nd > 1) && ((strides[0] != strides[nd-1]) || (dims[nd-1] > 1))) {
4063-
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
40644056
*objflags = ((*objflags)|NPY_ARRAY_F_CONTIGUOUS) &
40654057
~NPY_ARRAY_C_CONTIGUOUS;
40664058
}
@@ -4074,7 +4066,6 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
40744066
if (dims[i]) {
40754067
itemsize *= dims[i];
40764068
}
4077-
#if NPY_RELAXED_STRIDES_CHECKING
40784069
else {
40794070
not_cf_contig = 0;
40804071
}
@@ -4084,13 +4075,8 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
40844075
strides[i] = NPY_MAX_INTP;
40854076
}
40864077
#endif /* NPY_RELAXED_STRIDES_DEBUG */
4087-
#endif /* NPY_RELAXED_STRIDES_CHECKING */
40884078
}
4089-
#if NPY_RELAXED_STRIDES_CHECKING
40904079
if (not_cf_contig) {
4091-
#else /* not NPY_RELAXED_STRIDES_CHECKING */
4092-
if ((nd > 1) && ((strides[0] != strides[nd-1]) || (dims[0] > 1))) {
4093-
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
40944080
*objflags = ((*objflags)|NPY_ARRAY_C_CONTIGUOUS) &
40954081
~NPY_ARRAY_F_CONTIGUOUS;
40964082
}

numpy/core/src/multiarray/flagsobject.c

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -105,20 +105,11 @@ PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
105105
*
106106
* According to these rules, a 0- or 1-dimensional array is either both
107107
* C- and F-contiguous, or neither; and an array with 2+ dimensions
108-
* can be C- or F- contiguous, or neither, but not both. Though there
109-
* there are exceptions for arrays with zero or one item, in the first
110-
* case the check is relaxed up to and including the first dimension
111-
* with shape[i] == 0. In the second case `strides == itemsize` will
112-
* can be true for all dimensions and both flags are set.
113-
*
114-
* When NPY_RELAXED_STRIDES_CHECKING is set, we use a more accurate
115-
* definition of C- and F-contiguity, in which all 0-sized arrays are
116-
* contiguous (regardless of dimensionality), and if shape[i] == 1
117-
* then we ignore strides[i] (since it has no affect on memory layout).
118-
* With these new rules, it is possible for e.g. a 10x1 array to be both
119-
* C- and F-contiguous -- but, they break downstream code which assumes
120-
* that for contiguous arrays strides[-1] (resp. strides[0]) always
121-
* contains the itemsize.
108+
* can be C- or F- contiguous, or neither, but not both (unless it has only
109+
* a single element).
110+
* We correct this, however. When a dimension has length 1, its stride is
111+
* never used and thus has no effect on the memory layout.
112+
* The above rules thus only apply when ignorning all size 1 dimenions.
122113
*/
123114
static void
124115
_UpdateContiguousFlags(PyArrayObject *ap)
@@ -131,7 +122,6 @@ _UpdateContiguousFlags(PyArrayObject *ap)
131122
sd = PyArray_ITEMSIZE(ap);
132123
for (i = PyArray_NDIM(ap) - 1; i >= 0; --i) {
133124
dim = PyArray_DIMS(ap)[i];
134-
#if NPY_RELAXED_STRIDES_CHECKING
135125
/* contiguous by definition */
136126
if (dim == 0) {
137127
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
@@ -144,17 +134,6 @@ _UpdateContiguousFlags(PyArrayObject *ap)
144134
}
145135
sd *= dim;
146136
}
147-
#else /* not NPY_RELAXED_STRIDES_CHECKING */
148-
if (PyArray_STRIDES(ap)[i] != sd) {
149-
is_c_contig = 0;
150-
break;
151-
}
152-
/* contiguous, if it got this far */
153-
if (dim == 0) {
154-
break;
155-
}
156-
sd *= dim;
157-
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
158137
}
159138
if (is_c_contig) {
160139
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
@@ -167,24 +146,13 @@ _UpdateContiguousFlags(PyArrayObject *ap)
167146
sd = PyArray_ITEMSIZE(ap);
168147
for (i = 0; i < PyArray_NDIM(ap); ++i) {
169148
dim = PyArray_DIMS(ap)[i];
170-
#if NPY_RELAXED_STRIDES_CHECKING
171149
if (dim != 1) {
172150
if (PyArray_STRIDES(ap)[i] != sd) {
173151
PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
174152
return;
175153
}
176154
sd *= dim;
177155
}
178-
#else /* not NPY_RELAXED_STRIDES_CHECKING */
179-
if (PyArray_STRIDES(ap)[i] != sd) {
180-
PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
181-
return;
182-
}
183-
if (dim == 0) {
184-
break;
185-
}
186-
sd *= dim;
187-
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
188156
}
189157
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
190158
return;

0 commit comments

Comments
 (0)
0