Skip to content Skip to sidebar Skip to footer

Cython Memoryview Transpose: Typeerror

I'm trying to develop a small Convolutional Neural Network framework with python. The code for the convolutional node already works (slowly) and I would like to speed it up. The ho

Solution 1:

self.y[...] = some_array
# or equivalently self.y[:,:,:,:] = some_array

does a copy of some_array into self.y, which must already be initialised to the right size. It also only seems to work if some_array is already a memoryview (which doesn't hugely make sense to me, but this seems to be the case).

(self.y[:] = some_array only works for 1D arrays)

If you just want make self.y "look at" a numpy array you just want to do

self.y = some_array
# in your case:
# self.y = out_image.transpose(1, 0, 2, 3) 

The chances are that the this is fine for your purposes!


If you're particularly keen on making a copy (possibly if you've taken a C pointer to self.y or something like that) then you have to force some_array to be a memoryview. You'd do something like

cdef double[:,:,:,:] temporary_view_of_transpose

# temporary_view_of_transpose now "looks at" the memory allocated by transpose
# no square brackets!
temporary_view_of_transpose = out_image.transpose(1, 0, 2, 3)

# data is copied from temporary_view_of_transpose to self.y
self.y[...] = temporary_view_of_transpose # (remembering that self.y must be the correct shape before this assignment).

I agree the error message seen is unhelpful!


Edit: The following is minimum complete example that works for me (Cython 0.24, Python 3.5.1, Linux - I can't easily test on Anaconda) At this stage I'm not clear what's different in your code.

# memview.pyx
cimport numpy as np
import numpy as np

cdef class MemviewClass:
    cdef double[:,:,:,:] y

    def __init__(self):
        self.y = np.zeros((2,3,4,5))

    def do_something(self):
        cdef np.ndarray[np.float64_t,ndim=4] out_image = np.ones((3,2,4,5))
        cdef double[:,:,:,:] temp
        temp = out_image.transpose(1,0,2,3)
        self.y[...] = temp

    def print_y(self):
        # just to check it gets changed
        print(np.asarray(self.y))

and test_script.py to show it works:

# use pyximport for ease of testing
import numpy
import pyximport; pyximport.install(setup_args=dict(include_dirs=numpy.get_include()))

import memview

a = memview.MemviewClass()
a.print_y() # prints a big array of 0s
a.do_something()
a.print_y() # prints a big array of 1s

Post a Comment for "Cython Memoryview Transpose: Typeerror"