diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2013-04-14 07:23:52 -0700 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2013-04-14 07:23:52 -0700 |
commit | f62bc39d25eb827b4245ddfeb25b2ff6afbb838d (patch) | |
tree | dce6f8fe69b44cb5734ff678eede2b369780efd0 /doc | |
parent | 01ed88af5b784d52f4fcf383e319cde67c8a22fb (diff) | |
parent | 5cdf8410fc4d2ed05d22e6831023c40a30d9ebe7 (diff) | |
download | numpy-f62bc39d25eb827b4245ddfeb25b2ff6afbb838d.tar.gz |
Merge pull request #3221 from seberg/document-relaxed-strides
DOC: Document NPY_RELAXED_STRIDES_CHECKING changes
Diffstat (limited to 'doc')
-rw-r--r-- | doc/release/1.8.0-notes.rst | 33 | ||||
-rw-r--r-- | doc/source/reference/arrays.ndarray.rst | 44 | ||||
-rw-r--r-- | doc/source/reference/c-api.array.rst | 32 | ||||
-rw-r--r-- | doc/source/reference/ufuncs.rst | 6 |
4 files changed, 101 insertions, 14 deletions
diff --git a/doc/release/1.8.0-notes.rst b/doc/release/1.8.0-notes.rst index ad33b5513..c2fc57e6c 100644 --- a/doc/release/1.8.0-notes.rst +++ b/doc/release/1.8.0-notes.rst @@ -42,6 +42,39 @@ case, now indicates a 0-D iteration and ``op_axes`` being NULL and the old usage is deprecated. This does not effect the ``NpyIter_New`` or ``NpyIter_MultiNew`` functions. +NPY_RELAXED_STRIDES_CHECKING +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There is a new compile time environment variable +``NPY_RELAXED_STRIDES_CHECKING``. If this variable is set to 1, then +numpy will consider more arrays to be C- or F-contiguous -- for +example, it becomes possible to have a column vector which is +considered both C- and F-contiguous simultaneously. The new definition +is more accurate, allows for faster code that makes fewer unnecessary +copies, and simplifies numpy's code internally. However, it may also +break third-party libraries that make too-strong assumptions about the +stride values of C- and F-contiguous arrays. (It is also currently +known that this breaks Cython code using memoryviews, which will be +fixed in Cython.) THIS WILL BECOME THE DEFAULT IN A FUTURE RELEASE, SO +PLEASE TEST YOUR CODE NOW AGAINST NUMPY BUILT WITH:: + + NPY_RELAXED_STRIDES_CHECKING=1 python setup.py install + +You can check whether NPY_RELAXED_STRIDES_CHECKING is in effect by +running:: + + np.ones((10, 1), order="C").flags.f_contiguous + +This will be ``True`` if relaxed strides checking is enabled, and +``False`` otherwise. The typical problem we've seen so far is C code +that works with C-contiguous arrays, and assumes that the itemsize can +be accessed by looking at the last element in the ``PyArray_STRIDES(arr)`` +array. When relaxed strides are in effect, this is not true (and in +fact, it never was true in some corner cases). Instead, use +``PyArray_ITEMSIZE(arr)``. + +For more information check the "Internal memory layout of an ndarray" +section in the documentation. + New Features ============ diff --git a/doc/source/reference/arrays.ndarray.rst b/doc/source/reference/arrays.ndarray.rst index 535ce8faa..5a528cbf6 100644 --- a/doc/source/reference/arrays.ndarray.rst +++ b/doc/source/reference/arrays.ndarray.rst @@ -115,7 +115,7 @@ array. Here, :math:`s_k` are integers which specify the :obj:`strides <ndarray.strides>` of the array. The :term:`column-major` order (used, for example, in the Fortran language and in *Matlab*) and :term:`row-major` order (used in C) schemes are just specific kinds of -strided scheme, and correspond to the strides: +strided scheme, and correspond to memory that can be *addressed* by the strides: .. math:: @@ -124,12 +124,51 @@ strided scheme, and correspond to the strides: .. index:: single-segment, contiguous, non-contiguous -where :math:`d_j` = `self.itemsize * self.shape[j]`. +where :math:`d_j` `= self.itemsize * self.shape[j]`. Both the C and Fortran orders are :term:`contiguous`, *i.e.,* :term:`single-segment`, memory layouts, in which every part of the memory block can be accessed by some combination of the indices. +While a C-style and Fortran-style contiguous array, which has the corresponding +flags set, can be addressed with the above strides, the actual strides may be +different. This can happen in two cases: + 1. If ``self.shape[k] == 1`` then for any legal index ``index[k] == 0``. + This means that in the formula for the offset + :math:`n_k = 0` and thus :math:`s_k n_k = 0` and the value of + :math:`s_k` `= self.strides[k]` is arbitrary. + 2. If an array has no elements (``self.size == 0``) there is no legal index + and the strides are never used. Any array with no elements may be + considered C-style and Fortran-style contiguous. + +Point 1. means that ``self``and ``self.squeeze()`` always have the same +contiguity and :term:`aligned` flags value. This also means that even a high +dimensional array could be C-style and Fortran-style contiguous at the same +time. + +.. index:: aligned + +An array is considered aligned if the memory offsets for all elements and the +base offset itself is a multiple of `self.itemsize`. + +.. note:: + + Points (1) and (2) are not yet applied by default. Beginning with + Numpy 1.8.0, they are applied consistently only if the environment + variable ``NPY_RELAXED_STRIDES_CHECKING=1`` was defined when NumPy + was built. Eventually this will become the default. + + You can check whether this option was enabled when your NumPy was + built by looking at the value of ``np.ones((10,1), + order='C').flags.f_contiguous``. If this is ``True``, then your + NumPy has relaxed strides checking enabled. + +.. warning:: + + It does *not* generally hold that ``self.strides[-1] == self.itemsize`` + for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for + Fortran-style contiguous arrays is true. + Data in new :class:`ndarrays <ndarray>` is in the :term:`row-major` (C) order, unless otherwise specified, but, for example, :ref:`basic array slicing <arrays.indexing>` often produces :term:`views <view>` @@ -144,7 +183,6 @@ in a different scheme. irregularly strided array is passed in to such algorithms, a copy is automatically made. - .. _arrays.ndarray.attributes: Array attributes diff --git a/doc/source/reference/c-api.array.rst b/doc/source/reference/c-api.array.rst index 85cf3c317..8b918f9dd 100644 --- a/doc/source/reference/c-api.array.rst +++ b/doc/source/reference/c-api.array.rst @@ -1310,11 +1310,21 @@ of the constant names is deprecated in 1.7. The data area is in Fortran-style contiguous order (first index varies the fastest). -Notice that contiguous 1-d arrays are always both Fortran contiguous -and C contiguous. Both of these flags can be checked and are convenience -flags only as whether or not an array is :cdata:`NPY_ARRAY_C_CONTIGUOUS` -or :cdata:`NPY_ARRAY_F_CONTIGUOUS` can be determined by the ``strides``, -``dimensions``, and ``itemsize`` attributes. +.. note:: + + Arrays can be both C-style and Fortran-style contiguous simultaneously. + This is clear for 1-dimensional arrays, but can also be true for higher + dimensional arrays. + + Even for contiguous arrays a stride for a given dimension + ``arr.strides[dim]`` may be *arbitrary* if ``arr.shape[dim] == 1`` + or the array has no elements. + It does *not* generally hold that ``self.strides[-1] == self.itemsize`` + for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for + Fortran-style contiguous arrays is true. The correct way to access the + ``itemsize`` of an array from the C API is ``PyArray_ITEMSIZE(arr)``. + + .. seealso:: :ref:`Internal memory layout of an ndarray <arrays.ndarray>` .. cvar:: NPY_ARRAY_OWNDATA @@ -1322,7 +1332,7 @@ or :cdata:`NPY_ARRAY_F_CONTIGUOUS` can be determined by the ``strides``, .. cvar:: NPY_ARRAY_ALIGNED - The data area is aligned appropriately (for all strides). + The data area and all array elements are aligned appropriately. .. cvar:: NPY_ARRAY_WRITEABLE @@ -1432,14 +1442,20 @@ For all of these macros *arr* must be an instance of a (subclass of) :cdata:`NPY_ARRAY_OWNDATA`, :cdata:`NPY_ARRAY_ALIGNED`, :cdata:`NPY_ARRAY_WRITEABLE`, :cdata:`NPY_ARRAY_UPDATEIFCOPY`. -.. cfunction:: PyArray_ISCONTIGUOUS(arr) +.. cfunction:: PyArray_IS_C_CONTIGUOUS(arr) Evaluates true if *arr* is C-style contiguous. -.. cfunction:: PyArray_ISFORTRAN(arr) +.. cfunction:: PyArray_IS_F_CONTIGUOUS(arr) Evaluates true if *arr* is Fortran-style contiguous. +.. cfunction:: PyArray_ISFORTRAN(arr) + + Evaluates true if *arr* is Fortran-style contiguous and *not* + C-style contiguous. :cfunc:`PyArray_IS_F_CONTIGUOUS` + is the correct way to test for Fortran-style contiguity. + .. cfunction:: PyArray_ISWRITEABLE(arr) Evaluates true if the data area of *arr* can be written to diff --git a/doc/source/reference/ufuncs.rst b/doc/source/reference/ufuncs.rst index afcb1302b..dcd4ae6d0 100644 --- a/doc/source/reference/ufuncs.rst +++ b/doc/source/reference/ufuncs.rst @@ -321,9 +321,9 @@ advanced usage and will not typically be used. Specifies the calculation iteration order/memory layout of the output array. Defaults to 'K'. 'C' means the output should be C-contiguous, 'F' means - F-contiguous, 'A' means F-contiguous if the inputs are F-contiguous, C-contiguous - otherwise, and 'K' means to match the element ordering of the inputs - as closely as possible. + F-contiguous, 'A' means F-contiguous if the inputs are F-contiguous and + not also not C-contiguous, C-contiguous otherwise, and 'K' means to match + the element ordering of the inputs as closely as possible. *dtype* |