Bradley Froehle | 26 Jul 2012 23:37
Picon
Gravatar

MemoryView questions

Hi Folks,

I've got four questions relating to memoryviews in Cython 0.17.beta1, which hopefully you can help me with.

1. Can typed memory views accept multiple dimensions?

I've noticed that memory views do have an ndim attribute, however defining a function as:
    def f(double[:] x):
        pass
only works if x is one-dimensional.  Can I somehow allow x to have 1, 2, or 3 dimensions?  I'm fine adding an `assert 1 <= x.ndim <= 3` statement.

2. If I have a multidimensional array, why do I have to call `is_f_contig` to see if it is f-contiguous?  It seems like that should be a property, much like `ndim`.

    def f(double[:, :] x):
        print x.is_f_contig()

3. Supposing that I know in advance that my memory is contiguous, how can I get access to the underlying data pointer of the memoryview?

Certainly I could do:
    def f(double[::1, :] x):
        cfunction(&x[0,0])
... but what if I don't know the dimensionality of x?  (See Q 1).

Perhaps there should be a x.data attribute?

4. Can I not have inline memoryview functions in pxd files?

Consider:

### lib.pxd ###
cdef inline void f(double[:,:] x):
    pass
cdef inline f1(x):
    f(x)

### tst.pyx ###
cimport lib

Then compiling tst.pyx fails:

$ python setup.py build_ext --inplace
running build_ext
building 'tst' extension
creating build
creating build/temp.linux-x86_64-2.7
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c tst.c -o build/temp.linux-x86_64-2.7/tst.o
tst.c: In function ‘__pyx_f_3lib_f1’:
tst.c:1232:3: warning: implicit declaration of function ‘__Pyx_PyObject_to_MemoryviewSlice_dsds_double’ [-Wimplicit-function-declaration]
tst.c:1232:13: error: incompatible types when assigning to type ‘__Pyx_memviewslice’ from type ‘int’
tst.c: At top level:
tst.c:13446:12: warning: ‘__Pyx_ValidateAndInit_memviewslice’ defined but not used [-Wunused-function]
error: command 'gcc' failed with exit status 1

Thanks!
-Brad
Dave Hirschfeld | 8 Aug 2012 17:24
Picon

Re: MemoryView questions

Bradley Froehle <brad.froehle <at> gmail.com> writes:

> 
> 
> Hi Folks,
> 
> I've got four questions relating to memoryviews in Cython 0.17.beta1, which 
hopefully you can help me with.
> 1. Can typed memory views accept multiple dimensions?
> I've noticed that memory views do have an ndim attribute, however defining a 
function as:
>     def f(double[:] x):
>         pass
> only works if x is one-dimensional.  Can I somehow allow x to have 1, 2, or 3 
dimensions?  I'm fine adding an `assert 1 <= x.ndim <= 3` statement.
> 
> 2. If I have a multidimensional array, why do I have to call `is_f_contig` to 
see if it is f-contiguous?  It seems like that should be a property, much like 
`ndim`.
> 
>     def f(double[:, :] x):
> 
>         print x.is_f_contig()
> 
> 3. Supposing that I know in advance that my memory is contiguous, how can I 
get access to the underlying data pointer of the memoryview?
> 
> Certainly I could do:
>     def f(double[::1, :] x):
>         cfunction(&x[0,0])
> ... but what if I don't know the dimensionality of x?  (See Q 1).
> 
> 
> Perhaps there should be a x.data attribute?
> 
> 4. Can I not have inline memoryview functions in pxd files?
> 
> Consider:
> 
> ### lib.pxd ###
> cdef inline void f(double[:,:] x):
>     pass
> cdef inline f1(x):
>     f(x)
> 
> ### tst.pyx ###
> cimport lib
> 
> Then compiling tst.pyx fails:
> 
> 
> $ python setup.py build_ext --inplace
> running build_ext
> building 'tst' extension
> creating build
> creating build/temp.linux-x86_64-2.7
> gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-
prototypes -fPIC -I/usr/include/python2.7 -c tst.c -o build/temp.linux-x86_64-
2.7/tst.o
> tst.c: In function ‘__pyx_f_3lib_f1’:
> tst.c:1232:3: warning: implicit declaration of function 
‘__Pyx_PyObject_to_MemoryviewSlice_dsds_double’ [-Wimplicit-function-
declaration]
> tst.c:1232:13: error: incompatible types when assigning to type 
‘__Pyx_memviewslice’ from type ‘int’
> tst.c: At top level:
> tst.c:13446:12: warning: ‘__Pyx_ValidateAndInit_memviewslice’ defined but not 
used [-Wunused-function]
> error: command 'gcc' failed with exit status 1
> 
> 
> Thanks!
> -Brad
> 

Not sure about the answers to your questions in general, but I thought you
might be able to cheat by using fused types. Unfortunately this seems not
to work:

In [32]: %%cython
    ...: cimport cython
    ...: 
    ...: from cpython cimport bool
    ...: 
    ...: import numpy as np
    ...: cimport numpy as np
    ...: 
    ...: ctypedef np.float64_t float64_t
    ...: 
    ...: ctypedef fused myarray:
    ...:     float64_t[:,:]
    ...:     float64_t[:,:,:]
    ...: #
    ...: 
    ...: cpdef myarray nop(myarray array):
    ...:     return array
    ...: 

In [33]: nop(rand(2))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-33-bbba0b03d22e> in <module>()
----> 1 nop(rand(2))

f.pyd in f.__pyx_fused_cpdef (f.c:2503)()

TypeError: No matching signature found

In [34]: nop(rand(2,2))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-34-fa44702cf241> in <module>()
----> 1 nop(rand(2,2))

f.pyd in f.__pyx_fused_cpdef (Cf.c:2503)()

TypeError: No matching signature found

In [35]: nop(rand(2,2,2))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-c6b24e4d9bf8> in <module>()
----> 1 nop(rand(2,2,2))

f.pyd in f.__pyx_fused_cpdef f.c:2503)()

TypeError: No matching signature found

In [36]: 

Is there any reason why this shouldn't work or is this a bug?

-Dave

mark florisson | 8 Aug 2012 18:51
Picon
Gravatar

Re: Re: MemoryView questions

On 8 August 2012 16:24, Dave Hirschfeld <dave.hirschfeld <at> gmail.com> wrote:
> Bradley Froehle <brad.froehle <at> gmail.com> writes:
>
>>
>>
>> Hi Folks,
>>
>> I've got four questions relating to memoryviews in Cython 0.17.beta1, which
> hopefully you can help me with.
>> 1. Can typed memory views accept multiple dimensions?
>> I've noticed that memory views do have an ndim attribute, however defining a
> function as:
>>     def f(double[:] x):
>>         pass
>> only works if x is one-dimensional.  Can I somehow allow x to have 1, 2, or 3
> dimensions?  I'm fine adding an `assert 1 <= x.ndim <= 3` statement.
>>
>> 2. If I have a multidimensional array, why do I have to call `is_f_contig` to
> see if it is f-contiguous?  It seems like that should be a property, much like
> `ndim`.
>>
>>     def f(double[:, :] x):
>>
>>         print x.is_f_contig()
>>
>> 3. Supposing that I know in advance that my memory is contiguous, how can I
> get access to the underlying data pointer of the memoryview?
>>
>> Certainly I could do:
>>     def f(double[::1, :] x):
>>         cfunction(&x[0,0])
>> ... but what if I don't know the dimensionality of x?  (See Q 1).
>>
>>
>> Perhaps there should be a x.data attribute?
>>
>> 4. Can I not have inline memoryview functions in pxd files?
>>
>> Consider:
>>
>> ### lib.pxd ###
>> cdef inline void f(double[:,:] x):
>>     pass
>> cdef inline f1(x):
>>     f(x)
>>
>> ### tst.pyx ###
>> cimport lib
>>
>> Then compiling tst.pyx fails:
>>
>>
>> $ python setup.py build_ext --inplace
>> running build_ext
>> building 'tst' extension
>> creating build
>> creating build/temp.linux-x86_64-2.7
>> gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-
> prototypes -fPIC -I/usr/include/python2.7 -c tst.c -o build/temp.linux-x86_64-
> 2.7/tst.o
>> tst.c: In function ‘__pyx_f_3lib_f1’:
>> tst.c:1232:3: warning: implicit declaration of function
> ‘__Pyx_PyObject_to_MemoryviewSlice_dsds_double’ [-Wimplicit-function-
> declaration]
>> tst.c:1232:13: error: incompatible types when assigning to type
> ‘__Pyx_memviewslice’ from type ‘int’
>> tst.c: At top level:
>> tst.c:13446:12: warning: ‘__Pyx_ValidateAndInit_memviewslice’ defined but not
> used [-Wunused-function]
>> error: command 'gcc' failed with exit status 1
>>
>>
>> Thanks!
>> -Brad
>>
>
> Not sure about the answers to your questions in general, but I thought you
> might be able to cheat by using fused types. Unfortunately this seems not
> to work:
>
> In [32]: %%cython
>     ...: cimport cython
>     ...:
>     ...: from cpython cimport bool
>     ...:
>     ...: import numpy as np
>     ...: cimport numpy as np
>     ...:
>     ...: ctypedef np.float64_t float64_t
>     ...:
>     ...: ctypedef fused myarray:
>     ...:     float64_t[:,:]
>     ...:     float64_t[:,:,:]
>     ...: #
>     ...:
>     ...: cpdef myarray nop(myarray array):
>     ...:     return array
>     ...:
>
> In [33]: nop(rand(2))
> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call last)
> <ipython-input-33-bbba0b03d22e> in <module>()
> ----> 1 nop(rand(2))
>
> f.pyd in f.__pyx_fused_cpdef (f.c:2503)()
>
> TypeError: No matching signature found
>
> In [34]: nop(rand(2,2))
> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call last)
> <ipython-input-34-fa44702cf241> in <module>()
> ----> 1 nop(rand(2,2))
>
> f.pyd in f.__pyx_fused_cpdef (Cf.c:2503)()
>
> TypeError: No matching signature found
>
> In [35]: nop(rand(2,2,2))
> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call last)
> <ipython-input-35-c6b24e4d9bf8> in <module>()
> ----> 1 nop(rand(2,2,2))
>
> f.pyd in f.__pyx_fused_cpdef f.c:2503)()
>
> TypeError: No matching signature found
>
> In [36]:
>
>
> Is there any reason why this shouldn't work or is this a bug?
>
> -Dave
>
>

Thanks, that's a bug. It seems the delimiter ', ' was wrong, since it
generates signature strings like 'double[:, :]'. It also didn't
dispatch on ndim, so that's fixed as well. There's a fix here
https://github.com/markflorisson88/cython/commit/f96a5622c68776d4a206f36d1f701c763bad7caf
which will be pushed for 0.17 if it doesn't break anything.


Gmane