2

I'm trying to setup a buffer protocol in cython. I declare a new class in which I setup the two necessary methods __getbuffer__ and __releasebuffer__
FYI I'm using Cython0.19 and Python2.7 and here is the cython code:

cimport numpy as CNY
# Cython buffer protocol implementation for my array class
cdef class P_NpArray:
  cdef CNY.ndarray npy_ar
  def __cinit__(self, inpy_ar):
    self.npy_ar=inpy_ar      

  def __getbuffer__(self, Py_buffer *buffer, int flags):
    cdef Py_ssize_t ashape[2]
    ashape[0]=self.npy_ar.shape[0]
    ashape[1]=self.npy_ar.shape[1]
    cdef Py_ssize_t astrides[2]
    astrides[0]=self.npy_ar.strides[0]
    astrides[1]=self.npy_ar.strides[1]

    buffer.buf = <void *> self.npy_ar.data
    buffer.format = 'f'                     
    buffer.internal = NULL                  
    buffer.itemsize = self.npy_ar.itemsize
    buffer.len = self.npy_ar.size*self.npy_ar.itemsize      
    buffer.ndim = self.npy_ar.ndim
    buffer.obj = self
    buffer.readonly = 0
    buffer.shape = ashape
    buffer.strides = astrides
    buffer.suboffsets = NULL 

  def __releasebuffer__(self, Py_buffer *buffer):
    pass

This code compiles fine. But I can't retrieve the buffer data properly.
See the following test where:

  • I create a numpy array
  • load it with my buffer protocoled class
  • try to retrieve it as numpy array (Just to showcase my problem):
>>> import myarray
>>> import numpy as np
>>> ar=np.ones((2,4))         # create a numpy array
>>> ns=myarray.P_NpArray(ar)  # declare numpy array as a new numpy-style array
>>> print ns
<myarray.P_NpArray object at 0x7f30f2791c58>
>>> nsa = np.asarray(ns)      # Convert back to numpy array. Buffer protocol called here.
/home/tools/local/x86z/lib/python2.7/site-packages/numpy/core/numeric.py:235: RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.
  return array(a, dtype, copy=False, order=order)
>>> print type(nsa)           # Output array has the correct type
<type 'numpy.ndarray'>
>>> print "nsa=",nsa
nsa= <myarray.P_NpArray object at 0x7f30f2791c58>
>>> print "nsa.data=", nsa.data
nsa.data= Xy�0
>>> print "nsa.itemsize=",nsa.itemsize
nsa.itemsize= 8
>>> print "nsa.size=",nsa.size     # Output array has a WRONG size
nsa.size= 1
>>> print "nsa.shape=",nsa.shape   # Output array has a WRONG shape
nsa.shape= ()
>>> np.frombuffer(nsa.data, np.float64)  # I can't get a proper read of the data buffer
[  6.90941928e-310]

I looked around for the RuntimeWarning and found out that it probably was not relevant see PEP 3118 warning when using ctypes array as numpy array http://bugs.python.org/issue10746 and http://bugs.python.org/issue10744. What do you think ?

Obviously the buffer shape and size are not properly transmitted. So. What am I missing ? Is my buffer protocol correctly defined ?

Thanks

Community
  • 1
  • 1
  • 1
    have you found any solutions? [here](https://github.com/dashesy/pyavfcam/blob/master/src/avf.pyx#L76) I have similar issue. I can do `memoryview(nsa)` but `np.asarray(nsa)` does not work – dashesy Sep 17 '15 at 01:12
  • Actually I figured out now (same file updated now), both buffer as well as the object must have `shape` similar to [here](http://docs.cython.org/src/userguide/buffer.html) – dashesy Sep 17 '15 at 01:38

0 Answers0