Author: Stefan H. Muller <shmuell...@gmail.com> Branch: pypy-pyarray Changeset: r66344:232f215b317d Date: 2013-08-08 16:16 +0200 http://bitbucket.org/pypy/pypy/changeset/232f215b317d/
Log: Implement PyArray_FLAGS() - ndarrayobject.py: Implement PyArray_FLAGS() instead of PyArray_ISCONTIGUOUS(). This should yield correct results w.r.t. CPython. - arrayobject.h: Literally copy many more macros from numpy, which can be all traced back to PyArray_FLAGS(). diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h b/pypy/module/cpyext/include/numpy/arrayobject.h --- a/pypy/module/cpyext/include/numpy/arrayobject.h +++ b/pypy/module/cpyext/include/numpy/arrayobject.h @@ -10,12 +10,15 @@ #include "old_defines.h" #define NPY_INLINE +#define NPY_UNUSED(x) x +#define PyArray_MAX(a,b) (((a)>(b))?(a):(b)) +#define PyArray_MIN(a,b) (((a)<(b))?(a):(b)) /* fake PyArrayObject so that code that doesn't do direct field access works */ #define PyArrayObject PyObject #define PyArray_Descr PyObject -PyTypeObject PyArray_Type; +//PyTypeObject PyArray_Type; typedef unsigned char npy_bool; typedef unsigned char npy_uint8; @@ -95,35 +98,79 @@ #define PyArray_ISCOMPLEX(arr) (PyTypeNum_ISCOMPLEX(PyArray_TYPE(arr))) -/* selection of flags */ -#define NPY_CONTIGUOUS 0x0001 -#define NPY_FORTRAN 0x0002 -#define NPY_OWNDATA 0x0004 -#define NPY_FORCECAST 0x0010 -#define NPY_ALIGNED 0x0100 -#define NPY_NOTSWAPPED 0x0200 -#define NPY_WRITEABLE 0x0400 -#define NPY_C_CONTIGUOUS NPY_CONTIGUOUS -#define NPY_F_CONTIGUOUS NPY_FORTRAN -#define NPY_IN_ARRAY (NPY_C_CONTIGUOUS | NPY_ALIGNED) -#define NPY_BEHAVED (NPY_ALIGNED | NPY_WRITEABLE) -#define NPY_CARRAY (NPY_CONTIGUOUS | NPY_BEHAVED) -#define NPY_FARRAY (NPY_FORTRAN | NPY_BEHAVED) -#define NPY_DEFAULT NPY_CARRAY +/* flags */ +#define NPY_ARRAY_C_CONTIGUOUS 0x0001 +#define NPY_ARRAY_F_CONTIGUOUS 0x0002 +#define NPY_ARRAY_OWNDATA 0x0004 +#define NPY_ARRAY_FORCECAST 0x0010 +#define NPY_ARRAY_ENSURECOPY 0x0020 +#define NPY_ARRAY_ENSUREARRAY 0x0040 +#define NPY_ARRAY_ELEMENTSTRIDES 0x0080 +#define NPY_ARRAY_ALIGNED 0x0100 +#define NPY_ARRAY_NOTSWAPPED 0x0200 +#define NPY_ARRAY_WRITEABLE 0x0400 +#define NPY_ARRAY_UPDATEIFCOPY 0x1000 + +#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE) +#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE | \ + NPY_ARRAY_NOTSWAPPED) +#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO) +#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) +#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO) +#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY) +#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) + +#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) + +#define NPY_FARRAY NPY_ARRAY_FARRAY +#define NPY_CARRAY NPY_ARRAY_CARRAY + +#define PyArray_CHKFLAGS(m, flags) (PyArray_FLAGS(m) & (flags)) + +#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE) +#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED) + +#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) + +#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \ + PyArray_ISNOTSWAPPED(m)) + +#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY) +#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO) +#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY) +#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO) +#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED) +#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED) + +#define PyArray_ISONESEGMENT(arr) (1) +#define PyArray_ISNOTSWAPPED(arr) (1) +#define PyArray_ISBYTESWAPPED(arr) (0) + /* functions */ #ifndef PyArray_NDIM #define PyArray_Check _PyArray_Check #define PyArray_CheckExact _PyArray_CheckExact - -#define PyArray_ISONESEGMENT(arr) (1) -#define PyArray_FLAGS(arr) (0) - -#define PyArray_ISCONTIGUOUS _PyArray_ISCONTIGUOUS - -#define PyArray_ISCARRAY(arr) PyArray_ISCONTIGUOUS(arr) -#define PyArray_ISFARRAY(arr) (!PyArray_ISCONTIGUOUS(arr)) +#define PyArray_FLAGS _PyArray_FLAGS #define PyArray_NDIM _PyArray_NDIM #define PyArray_DIM _PyArray_DIM diff --git a/pypy/module/cpyext/include/numpy/old_defines.h b/pypy/module/cpyext/include/numpy/old_defines.h --- a/pypy/module/cpyext/include/numpy/old_defines.h +++ b/pypy/module/cpyext/include/numpy/old_defines.h @@ -2,9 +2,11 @@ #ifndef OLD_DEFINES_H #define OLD_DEFINES_H +/* #if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION #error The header "old_defines.h" is deprecated as of NumPy 1.7. #endif +*/ #define NDARRAY_VERSION NPY_VERSION diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py --- a/pypy/module/cpyext/ndarrayobject.py +++ b/pypy/module/cpyext/ndarrayobject.py @@ -8,11 +8,38 @@ from pypy.module.cpyext.pyobject import PyObject from pypy.module.micronumpy.interp_numarray import W_NDimArray, convert_to_array, wrap_impl from pypy.module.micronumpy.interp_dtype import get_dtype_cache +from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray from pypy.module.micronumpy.arrayimpl.scalar import Scalar from rpython.rlib.rawstorage import RAW_STORAGE_PTR -NPY_FORTRAN = 0x0002 -NPY_OWNDATA = 0x0004 +NPY_C_CONTIGUOUS = 0x0001 +NPY_F_CONTIGUOUS = 0x0002 +NPY_OWNDATA = 0x0004 +NPY_FORCECAST = 0x0010 +NPY_ENSURECOPY = 0x0020 +NPY_ENSUREARRAY = 0x0040 +NPY_ELEMENTSTRIDES = 0x0080 +NPY_ALIGNED = 0x0100 +NPY_NOTSWAPPED = 0x0200 +NPY_WRITEABLE = 0x0400 +NPY_UPDATEIFCOPY = 0x1000 + +NPY_BEHAVED = NPY_ALIGNED | NPY_WRITEABLE +NPY_BEHAVED_NS = NPY_ALIGNED | NPY_WRITEABLE | NPY_NOTSWAPPED +NPY_CARRAY = NPY_C_CONTIGUOUS | NPY_BEHAVED +NPY_CARRAY_RO = NPY_C_CONTIGUOUS | NPY_ALIGNED +NPY_FARRAY = NPY_F_CONTIGUOUS | NPY_BEHAVED +NPY_FARRAY_RO = NPY_F_CONTIGUOUS | NPY_ALIGNED +NPY_DEFAULT = NPY_CARRAY +NPY_IN = NPY_CARRAY_RO +NPY_OUT = NPY_CARRAY +NPY_INOUT = NPY_CARRAY | NPY_UPDATEIFCOPY +NPY_IN_FARRAY = NPY_FARRAY_RO +NPY_OUT_FARRAY = NPY_FARRAY +NPY_INOUT_FARRAY = NPY_FARRAY | NPY_UPDATEIFCOPY +NPY_CONTIGUOUS = NPY_C_CONTIGUOUS | NPY_F_CONTIGUOUS +NPY_UPDATE_ALL = NPY_CONTIGUOUS | NPY_ALIGNED + # the asserts are needed, otherwise the translation fails @@ -29,12 +56,19 @@ w_type = space.gettypeobject(W_NDimArray.typedef) return space.is_w(w_obj_type, w_type) - @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def _PyArray_ISCONTIGUOUS(space, w_array): +def _PyArray_FLAGS(space, w_array): assert isinstance(w_array, W_NDimArray) - return w_array.implementation.order == 'C' - + flags = NPY_BEHAVED_NS + if isinstance(w_array.implementation, ConcreteArray): + flags |= NPY_OWNDATA + if len(w_array.get_shape()) < 2: + flags |= NPY_CONTIGUOUS + elif w_array.implementation.order == 'C': + flags |= NPY_C_CONTIGUOUS + else: + flags |= NPY_F_CONTIGUOUS + return flags @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def _PyArray_NDIM(space, w_array): @@ -157,7 +191,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap("strides must be NULL")) - order = 'F' if flags & NPY_FORTRAN else 'C' + order = 'C' if flags & NPY_C_CONTIGUOUS else 'F' owning = True if flags & NPY_OWNDATA else False w_subtype = None diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py --- a/pypy/module/cpyext/test/test_ndarrayobject.py +++ b/pypy/module/cpyext/test/test_ndarrayobject.py @@ -32,11 +32,16 @@ assert not api._PyArray_Check(x) assert not api._PyArray_CheckExact(x) - def test_ISCONTIGUOUS(self, space, api): - a = array(space, [10, 5, 3], order='C') + def test_FLAGS(self, space, api): + s = array(space, [10]) + c = array(space, [10, 5, 3], order='C') f = array(space, [10, 5, 3], order='F') - assert api._PyArray_ISCONTIGUOUS(a) == 1 - assert api._PyArray_ISCONTIGUOUS(f) == 0 + assert api._PyArray_FLAGS(s) & 0x0001 + assert api._PyArray_FLAGS(s) & 0x0002 + assert api._PyArray_FLAGS(c) & 0x0001 + assert api._PyArray_FLAGS(f) & 0x0002 + assert not api._PyArray_FLAGS(c) & 0x0002 + assert not api._PyArray_FLAGS(f) & 0x0001 def test_NDIM(self, space, api): a = array(space, [10, 5, 3]) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit