Home > OS >  Cython: How to convert numpy 2D array of type "object" to memoryview?
Cython: How to convert numpy 2D array of type "object" to memoryview?

Time:01-28

I am wondering how one can convert a 2D numpy array input of type "object" into a Cython memoryview?

For example, if I have the following Cython extension type:

cdef class A:
   cdef:
       const double[:, ::1] X  # here I define that X is a memoryview

   cdef int init(self, object X):
        # how do I convert X into the correct memoryview object?
        self.X = X

In Python, the class A is initialized:

def do_something():
    # say we have a 2D numpy array; this is an example, and not necessarily how it is constructed
    X = np.zeros((5, 2), dtype=np.float32)
    A()
    
    # When we initialize, I would like Cython to now store it as a Cython memoryview
    A.init(X)

There are two issues I face with the Cython code currently:

  1. I don't know whether or not X is initialized as contiguous, or fortran.
  2. I want to force it into a contiguous array.

How do I make it so that way I can just work with Cython code that is always working with a contiguous array?

A tangential question I would have is are there any tradeoffs to forcing the Cython memoryview to be contiguous vs fortran?

CodePudding user response:

How do I make it so that way I can just work with Cython code that is always working with a contiguous array?

numpy.ascontiguousarray - it'll do nothing if it's already right and make a copy if it isn't.

A tangential question I would have is are there any tradeoffs to forcing the Cython memoryview to be contiguous vs fortran?

For best use of the CPU cache you usually want the innermost loop to be over the contiguous dimension. Which you prefer therefore depends on what you're doing. For example, for a matrix vector matrix multiplication you likely want the second dimension to be contiguous. For a vector matrix multiplication you likely want the first dimension to be contiguous.

If you're passing them to third party libraries you may well want to match what they expect.


Maybe if you're accepting arrays from a variety of sources the correct memoryview is double[:,:] (i.e. not requiring it to be contiguous)?

  • Related