简体   繁体   English

Cython 用零初始化矩阵

[英]Cython initialize matrix with zeros

Description描述

I simply want to create a matrix of rows x cols that is filled with 0 s.我只是想创建一个由0填充的rows x cols的矩阵。 Always working with numpy I thought using np.zeros as describedin the docs is the easiest:总是使用 numpy 我认为使用文档中描述np.zeros是最简单的:

DTYPE = np.int
ctypedef np.int_t DTYPE_t

def f1():
    cdef:
        int dim = 40000
        int i, j
        np.ndarray[DTYPE_t, ndim=2] mat = np.zeros([40000, 40000], dtype=DTYPE)
        
    for i in range(dim):
        for j in range(dim):
            mat[i, j] = 1

Then I compared this using the arrays in c:然后我使用 c 中的数组进行了比较:

def f2():
    cdef:
        int dim = 40000
        int[40000][40000] mat
        int i, j
    
    for i in range(dim):
        for j in range(dim):
            mat[i][j] = 1

The numpy version took 3 secs on my pc whereas the c version only took 2.4e-5 secs . numpy 版本在我的电脑上用了3 secs ,而 c 版本只用了2.4e-5 secs However when I return the array from f2() I noticed it is not zero filled (of course here it can't be, i==j however when not filling it it won't return a 0 array either).但是,当我从f2()返回数组时,我注意到它不是零填充的(当然这里不能, i==j但是当不填充它时,它也不会返回 0 数组)。 How can this be done in cython.如何在 cython 中做到这一点。 I know in regular C it would be like: int arr[n][m] = {};我知道在常规 C 中它会像: int arr[n][m] = {}; . .

Question问题

How can the c array be filled with 0s ?如何用0s填充 c 数组? (I would go for numpy instead if there is something obvious wrong in my code) (如果我的代码中有明显错误,我会选择 numpy)

You do not want to be writing code like this:你不想写这样的代码:

  1. int[40000][40000] mat generates a 6 gigabyte array on the stack (assuming 4 byte ints). int[40000][40000] mat在堆栈上生成一个 6 GB 的数组(假设为 4 字节整数)。 Typically maximum stack sizes are of the order of a few Mb.通常,最大堆栈大小约为几 Mb。 I have no idea how this isn't crashing your PC.我不知道这不会使您的 PC 崩溃。

  2. However when I return the array from f2() [...]但是,当我从 f2() 返回数组时 [...]

    The array you have allocated is completely local to the function.您分配的数组完全是函数本地的。 From a C point of view you cannot return it since it ceases to exist after the function has finished.从 C 的角度来看,您无法返回它,因为它在函数完成后不再存在。 I think Cython may convert it to a (nested) Python list for you.我认为 Cython 可能会为您将其转换为(嵌套的)Python 列表。 This requires a slow copy element-by-element and is not what you want.这需要逐个元素的慢速复制,这不是您想要的。

For what you're doing here you're much better just using Numpy.对于您在这里所做的事情,仅使用 Numpy 会更好


Cython doesn't support a good equivalent of the C arr = {} so if you do want initialize sensible, small C arrays you need to use of one: Cython 不支持 C arr = {}的良好等效项,因此如果您确实想要初始化合理的小型 C 数组,则需要使用一个:

  1. loops,循环,
  2. memset (which you can cimport from libc.string ), memset (您可以从cimport libc.string ),
  3. Create a typed memoryview of it and do memview[:,:] = 0创建它的类型化内存视图并执行memview[:,:] = 0

The numpy version took 3 secs on my pc whereas the c version only took2.4e-5 secs. numpy 版本在我的电脑上用了 3 秒,而 c 版本只用了 2.4e-5 秒。

This kind of difference usually suggests that the C compiler has optimized some code out (by detecting that the result is unused).这种差异通常表明 C 编译器已经优化了一些代码(通过检测结果未使用)。 It is unlikely to be a genuine speed-up.这不太可能是真正的加速。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM