memory view from fortran-contigous pointer

78 views
Skip to first unread message

Soren Christensen

unread,
Dec 30, 2015, 5:28:41 PM12/30/15
to cython-users
Hi,
 I am having problems casting a short* array to a memory view (with the ultimate goal of exposing this memoryview to a numpy array).
I get an error when running cython on my .pyx file:
...
        cdef getData(self)
                 .....
        cdef short[ ::1,:,:] mya= <short[:128 , :128, :14]> self._thisptr.getBufferPtr()    #this is the short pointer
        z=np.asarray(mya)
        return z
...

Error:
 cdef short[ ::1,:,:] mya= <short[:128 , :128, :14]> self._thisptr.getBufferPtr()
                                 ^
DataImporter.pyx:72:34: Memoryview 'short[:, :, ::1]' not conformable to memoryview 'short[::contiguous, :, :]'.


If I declare the mya array to be c-contigous, there are no technical issues, but the numpy array is then nominally c-contiguous with an f-contiguous raw buffer and my 3D matrix is messed up (as expected).

1) Why am I getting this error?   Is there a different casting syntax to specify that the buffer is fortran contiguous?
2) If not, are there any good work arounds?  Casting to 1D buffer and reshaping perhaps? 

Thanks!
Soren

Soren Christensen

unread,
Dec 30, 2015, 5:39:24 PM12/30/15
to cython-users
Sorry, did eventually find a previous post with this.
Should be:
cdef short[ ::1,:,:] mya= <short[:128:1 , :128, :14]> self._thisptr.getBufferPtr()
This works well.

Is this level of detail documented anywhere right now?

Thanks!
Soren

Nathaniel Smith

unread,
Dec 30, 2015, 7:13:10 PM12/30/15
to cython...@googlegroups.com

Probably there is some better solution, but a silly/simple hack would be to exploit the fact that if some memory buffer is an f-contiguous representation of an array A, then it is also a c-contiguous representation of the array A-transpose. So you could take a C contiguous view with your shape reversed, and then return resulting_array.T

(The .T attribute on numpy arrays never makes a copy, because it can exploit the above trick internally.)

-n

--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Soren Christensen

unread,
Jan 2, 2016, 9:03:21 PM1/2/16
to cython...@googlegroups.com
Thanks for the suggestion!
I think my follow up post may have crossed yours. Eventually the bold faced addition did the trick of making the pointer cast Fortran contigous.
cdef short[ ::1,:,:] mya= <short[:128:1 , :128, :14]> 
self._thisptr.getBufferPtr()

I think transposing would also have worked - but it seems to be limited to 2 dimensions?

Thanks in any case!
Soren





--

---
You received this message because you are subscribed to a topic in the Google Groups "cython-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cython-users/A7tUKycLZfM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cython-users...@googlegroups.com.

Nathaniel Smith

unread,
Jan 2, 2016, 9:12:18 PM1/2/16
to cython...@googlegroups.com
On Sat, Jan 2, 2016 at 6:02 PM, Soren Christensen <sor...@gmail.com> wrote:
> Thanks for the suggestion!
> I think my follow up post may have crossed yours. Eventually the bold faced
> addition did the trick of making the pointer cast Fortran contigous.
> cdef short[ ::1,:,:] mya= <short[:128:1 , :128, :14]>
> self._thisptr.getBufferPtr()
>
> I think transposing would also have worked - but it seems to be limited to 2
> dimensions?

Sounds like you solved your problem, but for the record, no, the numpy
transpose operator (np.transpose or array.T) applies to
higher-dimensional arrays by reversing the dimension order, which is
also what you want for flipping between C and F ordering.

-n

--
Nathaniel J. Smith -- http://vorpus.org

Soren Christensen

unread,
Jan 2, 2016, 11:39:54 PM1/2/16
to cython...@googlegroups.com
Thanks again!
I assumed it was for 2D matrices only, but I see now it is nd and would also work.

Soren

Reply all
Reply to author
Forward
0 new messages