【问题标题】:Cython buffer declarations for object members对象成员的 Cython 缓冲区声明
【发布时间】:2012-02-07 03:45:09
【问题描述】:

我想要一个带有 NumPy 成员的 Cython“cdef”对象,并且能够使用快速缓冲区访问。理想情况下,我会这样做:

import numpy as np
cimport numpy as np

cdef class Model:
  cdef np.ndarray[np.int_t, ndim=1] A

  def sum(self):
    cdef int i, s=0, N=len(self.A)
    for 0 <= i < N:
      s += self.A[i]
    return s

  def __init__(self):
    self.A = np.arange(1000)

不幸的是,Cython 无法编译它,错误为Buffer types only allowed as function local variables

我使用的解决方法是在分配给对象成员的新局部变量上声明缓冲区属性:

cdef class Model:
  cdef np.ndarray A

  def sum(self):
    cdef int i, s=0, N=len(self.A)
    cdef np.ndarray[np.int_t, ndim=1] A = self.A
    for 0 <= i < N:
      s += A[i]
    return s

如果您想让多个方法访问相同的数据结构,这会变得非常烦人——这似乎是一个很常见的用例,不是吗?

有没有更好的解决方案,不需要在每个方法中重新声明类型?

【问题讨论】:

    标签: python numpy cython


    【解决方案1】:

    您当前使用的解决方案是我倾向于使用的解决方案,即在函数中制作本地副本。它并不优雅,但我认为您不会对性能产生巨大影响(或者至少在我的情况下,我在该方法上做了很多工作,所以它不会产生明显的差异)。我还在 __cinit__ 方法中创建了一个 C 数组,然后用 __init__ 中的数据填充它(确保使用 __dealloc__ 正确清理)。你失去了 numpy 数组的一些特性,但你仍然可以像使用 c 数组一样使用它。

    您还可以查看 cython 列表中这封较旧电子邮件中的讨论:

    http://codespeak.net/pipermail/cython-dev/2009-April/005214.html

    【讨论】:

      【解决方案2】:

      可以选择使用内存片或 cython 数组 http://docs.cython.org/src/userguide/memoryviews.html

      import numpy as np
      cimport numpy as np
      
        cdef class Model:
      
          cdef int [:] A
      
          def sum(self):
      
              for 0 <= i < N:
                  s += self.A[i]
              return s
      
          def __init__(self):
              self.A = np.arange(1000)
      

      【讨论】:

      • 当你使用这种 memoryviews 方法时,你可能会失去性能??我对此进行了分析:stringsource:368(dealloc) 和 stringsource:341(cinit)。顺便说一句,这在stackoverflow.com/questions/21056696/…中也有讨论
      • 关于这个需求问题的优雅解决方案是什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2012-03-03
      相关资源
      最近更新 更多