8

我创建了一个 Cython 代码来在密集矩阵和稀疏向量之间进行矩阵运算,如下所示(因为我正在学习 Cython,我不确定这是一个好的代码,但这是我能想到的最好的远的):

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    

它工作正常。但是当我改变第三行时:

ctypedef np.float64_t dtype_t

至:

ctypedef np.float32_t dtype_t

并编译 .pyx 文件并再次运行矩阵运算我得到错误:

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

例如,使用 np.float32_t 编译并运行代码时:

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'

在 Cython 中使用 float32 有不同的方法吗?使用 float64 和 float32 不应该以同样的方式工作?

对于我迄今为止研究的内容,它应该工作相同,但它没有在那个代码中。

提前致谢!

4

1 回答 1

6

np.zeros 的默认行为是创建一个 float64 数据,如果你想强制数据类型为 float32,你应该指定它。您还应该将所有 cdef 放在函数的开头。

于 2013-09-24T18:20:14.863 回答