14

I am new to Cython and encountered this code snippet:

import numpy as np
cimport numpy as np

testarray = np.arange(5)
cdef np.ndarray[np.int_t, ndim=1] testarray1 = testarray.copy()
cdef np.ndarray[np.float_t, ndim=1] testarray2 = testarray.astype(np.float)

During compilation, it said Buffer types only allowed as function local variables. However, I am using .copy() or .astype() which is returning not a memoryview, but a copy. Why is this still happening? How can I get around this?

Thanks!

2
  • 1
    testarray itself is a buffer. So why not put everything into a function and call it from Python? Commented May 23, 2014 at 21:06
  • @Midnighter Thanks! I was trying to define some global constants to save several lines of code... And I never thought that testarray is a buffer itself before. Thanks for the input - I'd go with more verbose code then I guess! :) Commented May 23, 2014 at 21:08

1 Answer 1

17

When you define an array in cython using np.ndarray[Type, dim], that is accessing the python buffer interface, and those can't be set as module level variables. This is a separate issue from views vs copies of numpy array data.

Typically if I want to have an array as a module level variable (i.e not local to a method), I define a typed memoryview and then set it within a method using something like (untested):

import numpy as np
cimport numpy as np

cdef np.int_t[:] testarray1

def init_arrays(np.int_t[:] testarray):
    global testarray1
    testarray1 = testarray.copy()
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much Josh! It is very helpful. However, the memoryviewslice would not have ndarray methods such as ndarray.mean() or ndarray.max()... Any chance you know a workaround?
As long as it doesn't incur too much overhead for what you're doing, you can use np.asarray to coerce the typed memoryview to a numpy array docs.cython.org/src/userguide/… within the method that you are using the memoryview in.
Excellent! That is awesome functionality that I didn't notice. Thank you so much Josh!
Why do you use testarray.copy() instead of just testarray1 = testarray?
From stackoverflow.com/a/24166170, "I am using .copy() to guarantee that you have contiguous data in memory. This would be unnecessary if positions was Fortran-contiguous.". So I'm guessing the copy() here is also to ensure contiguous memory

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.