常量表达式中不允许出现Cython编译错误"

2022-04-04 00:00:00 python python-3.x cython c cythonize

问题描述

以下

cimport cython

@cython.boundscheck(False)
def boundtest():
     cdef int r=4
     cdef double l[3]

工作正常。但当我尝试这个时:

cimport cython

@cython.boundscheck(False)
def boundtest():
     cdef int r=4
     cdef double l[r]

我收到以下错误:

[1/1] Cythonizing test.pyx

Error compiling Cython file:
------------------------------------------------------------
...
cimport cython

@cython.boundscheck(False)
def boundtest():
     cdef int r=4
     cdef double l[r]
                   ^
------------------------------------------------------------

test.pyx:13:20: Not allowed in a constant expression
     

添加修饰符是因为找到了this相关的StackExchange帖子,并阅读了Kurt W.Smith的Cython一书。就我所知,这应该可以告诉Cython不要担心拥有动态索引变量可能导致的越界错误,但出于某些原因,它并非如此。我还尝试在编译器选项和全局中更改边界检查,但都无济于事。

如果不是Cython文档声称是最新的,我会认为bundscheck已经贬值了。


解决方案

失败与cython.boundscheck无关。

边界检查只是检查您是否尝试访问不存在的数组元素。例如,如果您有一个大小为4的数组,并且尝试使用boundscheck(True)访问元素5-它将给您一个例外,boundscheck(False)它将导致未定义的行为(可能导致分段错误)。

编译失败的另一个原因是:不能创建具有动态长度的静态数组!在编译时需要知道元素的数量,这只是c强制执行的内容(我想)。

但是,您可以将r定义为compile time:

DEF r=4

cimport cython

@cython.boundscheck(False)
def boundtest():
    cdef double l[r]

不过,您只需创建一个NumPy数组并将其存储在Memory view变量中:

cimport cython
import numpy as np

@cython.boundscheck(False)
def boundtest():
    cdef int r=4
    cdef double[:] l = np.empty(r, dtype=np.double)

相关文章