cython version of multi_dot based on np.dot
I have to optimize a python code with cython. The code has a lot of vectors and matrices dot products, which is the key of the optimization procedure.
The products are in chain like : A.B.C.D.e where e can be a vector and A,B,C,D are matrices. I'm using numpy to represent all the objects.
Originally, I used
numpy.linalg.multi_dot. I read here that multi_dot can be more efficient than np.dot because it tries to optimize operation order.
However, in my case, the matrices are small and using multi_dot is about 10x slower than doing a chain of np.dot.
However, the syntax of multi_dot is nice and there are thousands of lines in the code doing products of different numbers of matrices and vectors. Re-writing all these lines using np.dot would really loose readability for other developers.
Creating a pure python equivalent of multi_dot based on np.dot was easy, but I'd like to Cythonize it. The fact that I don't know the number of matrices given as arguments of multi_dot at compilation time forces me to call the python interpretor. Here is the code I wrote:
@cython.boundscheck(False) @cython.wraparound=False cpdef mymultidot(np_array_list): cdef int n=len(np_array_list) R=np_array_list for i in range(1,n): R=np.dot(R,np_array_list[i])
Is there a way to reduce python calls in this function? In particular, not deducing type of np_array_list at execution time?
Maybe deduce the type of np_array_list at compile time something like list_of ( np.ndarray[np.float_t, ndim=2] )? But not knowing the size of the list will make it difficult.
Is there a way in Cython to have methods with the same name but not the same arguments like in C/C++? So that I could create
mymultidot( np.ndarray[np.float_t, ndim=2], np.ndarray[np.float_t, ndim=2], np.ndarray[np.float_t, ndim=2]) mymultidot( np.ndarray[np.float_t, ndim=2], np.ndarray[np.float_t, ndim=2]) mymultidot( np.ndarray[np.float_t, ndim=2], np.ndarray[np.float_t, ndim=1])
... and so on?
It will be long to write all the versions existing in the code, but all multi_dot arguments would be known at compile time.
Thanks in advance.