Some background for the question:
I'm trying to optimise a custom neural network code. It relies heavily on loops and I decided to use cython to speed up the calculation.
I followed the usual online tips: Declare all local variables with appropriate cdefs and switch off boundscheck and nonecheck. This barely gave me 10% performance.
Well, my code relies on lots of class members. Therefore I decided to convert the entire class into a cdef class. Turns out that cython doesn't allow numpy ndarrays as types for class members. Instead one has to use memoryviews. Unfortunately the two types seem to be vastly incompatible.
I already ran into this problem: Cython memoryview transpose: Typeerror
To sum it up: You can store an np.ndarray in a memoryview. You can transpose it and store the returned array in a memview. But not if that memview is a class member. Then you have to create an intermediate memview, store the result in that and assign the intermediate memview to the class member.
Here's the code ( many thanks to DavidW)
def 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).
Now I've got a new problem. The code above is from the so-called "forward-pass". There is also a corresponding backward-pass, which does all the calculations backward (for analytical gradients).
This means that for the backward pass, I have to transpose the memoryview and store it in a numpy array:
cdef np.ndarray[DTYPE_t, ndim=4] d_out_image = self.d_y.transpose(1, 0, 2,3)
d_y has to be a class member, therefore it has to be a memoryview. Memoryviews don't allow transposing. They have a .T method, but that doesn't help me.
Actual Question:
- How do I correctly store a numpy array as a class member of a cdef class?
- If the answer is :"as a memoryview", how do I transpose a memoryview ?