[Numpy-discussion] C-API for non-contiguous arrays
Oliver Kranz
o.kranz at gmx.de
Thu Oct 25 10:23:34 EDT 2007
Timothy Hochberg wrote:
>
>
> On 10/25/07, *Oliver Kranz* <o.kranz at gmx.de <mailto:o.kranz at gmx.de>> wrote:
>
> Hi,
>
> I am working on a Python extension module using of the NumPy C-API. The
> extension module is an interface to an image processing and analysis
> library written in C++. The C++ functions are exported with
> boos::python. Currently I am implementing the support of
> three-dimensional data sets which can consume a huge amount of memory.
> The 3D data is stored in a numpy.ndarray. This array is passed to C++
> functions which do the calculations.
>
> In general, multi-dimensional arrays can be organized in memory in four
> different ways:
> 1. C order contiguous
> 2. Fortran order contiguous
> 3. C order non-contiguous
> 4. Fortran order non-contiguous
>
>
> I believe that this is incorrect. Consider the following:
>
> >>> import numpy as np
> >>> a = np.arange(27).reshape(3,3,3)
> >>> a.strides
> (36, 12, 4)
> >>> a.transpose(2,1,0).strides
> (4, 12, 36)
> >>> a.transpose(0,2,1).strides
> (36, 4, 12)
>
> I believe that the last transpose doesn't fit any of these four
> categories and is simply discontiguous.
Yes, you are right. I did not consider this case.
> Am I right that the NumPy C-API can only distinguish between three ways
> the array is organized in memory? These are:
> 1. C order contiguous e.g. with PyArray_ISCONTIGUOUS(arr)
> 2. Fortran order contiguous e.g. with PyArray_ISFORTRAN(arr)
> 3. non-contiguous e.g. with !PyArray_ISCONTIGUOUS(arr) &&
> !PyArray_ISFORTRAN(arr)
>
> So there is no way to find out if a non-contiguous array has C order or
> Fortran order. The same holds for Python code e.g. by use of the flags.
>
> a.flags.contiguous
> a.flags.fortran
>
> This is very important for me because I just want to avoid to copy
> every
> non-contiguous array into a contiguous array. This would be very
> inefficient. But I can't find an other solution than copying the array.
>
> Also the iterator provided by the C-API only loops over the array in C
> order. Even if the array is in Fortran non-contiguous order.
>
> Or are there just no Fortran order non-contiguous arrays? I think I can
> construct one.
>
> a = numpy.ndarray((3,4,5), order="F")
> b = a[:,1:2,:]
>
> Now, I think b's elements are organized in memory in Fortran
> non-contiguous order. But the flags only tell me that it is
> non-contiguous and not if it is in Fortran order or in C order. And if b
> would be passed to a C++ function it would not be possible to find out
> with the C-API if it is in Fortran order or in C order, too.
>
> Any ideas? Or do I always have to create contiguous arrays?
>
>
>
> By Fortran and C-Order discontiguous, do you simply mean that the
> strides are in increasing and decreasing order respectively? If so, you
> could check for that without too much trouble.
Since I want to support all the different contiguous and non-contiguous
arrays the best solution for me is always checking the strides if the
array is not in C order contiguous.
Thanks,
Oliver
More information about the NumPy-Discussion
mailing list