Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

float64 to float32 Cython Error

I've created a Cython code to make matrix operations between a dense matrix and a sparse vector,as follows (as I'm learning Cython I'm not sure this is a good code, but it's the best I could come up with so far):

import numpy as np
cimport numpy as np
ctypedef np.float64_t dtype_t
ctypedef np.int32_t dtypei_t
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def cdenseXsparse(np.ndarray[dtype_t, ndim = 2] Y,
                  np.ndarray[dtype_t, ndim = 1] V,
                  np.ndarray[dtypei_t, ndim = 1] I,
                  np.ndarray[dtype_t, ndim = 1] A = None):
    """
    Computes A = Y * (V_I)
    """
    if Y is None:
        raise ValueError("Input cannot be Null")
    A = np.zeros(Y.shape[1])
    cdef Py_ssize_t i, indice
    cdef dtype_t s  
    for i in range(A.shape[0]):             
        s = 0
        for indice in range(len(I)):
            s += Y[I[indice], i] * V[indice]
        A[i] = s
    return A    

It works fine. But when I change the third line from:

ctypedef np.float64_t dtype_t

to:

ctypedef np.float32_t dtype_t

and compile the .pyx file and run again the matrix operations I get the error:

"Buffer dtype mismatch, expected 'dtype_t' but got 'long'"

As an example, when compiling using np.float32_t and running the code:

In [3]: from numpy import random as rd, array, int32, float32

In [4]: y = array(rd.rand(10, 200), dtype = float32)

In [5]: v = array([1, 2, 3], dtype = float32)

In [6]: i = array([0, 1, 2], dtype = int32) 

In [7]: from cdenseXsparse import cdenseXsparse

In [8]: r = cdenseXsparse(y, v, i)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-319f9c8c8d49> in <module>()
----> 1 r = cdenseXsparse(y, v, i)

/home/will/workspace/s3_RecSys/SVD/cdenseXsparse.so in cdenseXsparse.cdenseXsparse     (cdenseXsparse.c:1484)()

ValueError: Buffer dtype mismatch, expected 'dtype_t' but got 'double'

Is there a different way to use float32 in Cython? Using float64 and float32 shouldn't work the same way?

For what I've researched so far it should work the same, but it didn't in that code.

Thanks in advance!

like image 520
Willian Fuks Avatar asked Sep 24 '13 15:09

Willian Fuks


1 Answers

The default behaviour of np.zeros is to create a float64 data, if you want to force the datatype to be float32 you should specify it. You should also put all cdefs in the beginning of the function.

like image 186
flaviotruzzi Avatar answered Nov 19 '22 07:11

flaviotruzzi