【问题标题】:cython C code compilation fails with typed memoryviewscython C 代码编译因类型化的 memoryviews 而失败
【发布时间】:2016-06-16 21:52:19
【问题描述】:

以下代码在 cython 中编译没有问题:

cdef class Double:
    cdef double v
    def __init__(self, double v):
        self.v = v
    cdef double incr(self) nogil:
        self.v += 1
        return self.v

cdef int f(Double[:] xs):
    cdef int i, N
    N = xs.shape[0]
    for i in range(N):
        xs[i].incr()
    return 0

但是,当我尝试编译生成的 C 代码时,gcc 编译器停止并出现错误:

test.c: In function '__pyx_f_4test_f':
test.c:1491:55: error: 'PyObject {aka struct _object}' has no member named '__pyx_vtab'
     ((struct __pyx_vtabstruct_4test_Double *)__pyx_t_3->__pyx_vtab)->incr(__pyx_t_3);

我犯的错误在哪里?请注意,当我使用标准内存类型时,相同的代码没有任何问题(例如,在f 函数中使用double[:] xs 参数)。

另外,有没有办法用Double[:] 释放f 函数中的gil?如果我尝试这样做,我会收到一条错误消息

test.pyx:13:10: Cannot access buffer with object dtype without gil

查看生成的代码,我看到对 __Pyx_INCREF__Pyx_DECREF 的几个调用,但我似乎不需要。

编辑

经过一些讨论,我现在可以找到解决方法并能够编译 C 代码:例如在函数定义中使用 object[:] xs,然后在 for 循环中强制转换 (<Double>(xs[i])).incr()。然而,这些解决方法引入了更多的 python 交互,这正是我想要避免的。

用更一般的术语来说,问题是:在 cython 中有没有办法处理 cdef class 的同构列表(类型化缓冲区或类似的),这样就没有 python 开销并且 GIL 可以发布了吗?

【问题讨论】:

  • 这个问题有什么解决办法吗?

标签: c compiler-errors cython


【解决方案1】:

请查看此主题,您的情况可能与此类似: Cython: have sequence of Extension Types as attribute of another Extension Type with access to cdef methods

也请尝试谷歌搜索__pyx_vtab - 搜索结果显示来自有类似问题的人的问题,我简要检查了第一个问题,并且看起来也有一些解决方案: https://groups.google.com/forum/#!topic/cython-users/3tUDIc11Xak

【讨论】:

  • 谢谢。您链接的问题确实非常相似,我忽略了它:但是,没有提供任何答案,并且只有一种解决方法建议。然而,解决方法引入了 python 开销。另外,我仍然不明白为什么 cython 将 __Pyx_INCREF 放入代码中,因此不能以快速、并行的方式使用这些构造。因此,这个问题仍然没有答案。
  • 忘了说:谷歌的建议不起作用,只有几页讨论类似的问题,但没有适用于我的情况的解决方案:特别是你提到的页面讨论的问题完全不同,来自不同文件中定义的父子类列表。
猜你喜欢
  • 2011-01-22
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 2020-08-21
  • 2019-07-08
  • 2021-03-06
  • 1970-01-01
  • 2021-10-30
相关资源
最近更新 更多