Cython“不允许在常量表达式中使用”,boundscheck False不起作用 [英] Cython "Not allowed in a constant expression", boundscheck False doesn't work
问题描述
我对Cython比较陌生,遇到一个错误,我的研究使我失败了(我在spyder中使用Python3,而我的Sython版本是0.26)
I am relatively new to Cython and have encountered an error that my research has failed me on (I am using Python3 in spyder and my Sython version is 0.26)
我试过了:
import cython
@cython.boundscheck(False)
def boundtest():
cdef int r=4
cdef double l[3]
,效果很好。但是后来我尝试了这个:
and it works fine. But then I tried this:
import cython
@cython.boundscheck(False)
def boundtest():
cdef int r=4
cdef double l[r]
并且收到错误
[1/1] Cythonizing test.pyx
Error compiling Cython file:
------------------------------------------------------------
...
import cython
@cython.boundscheck(False)
def boundtest():
cdef int r=4
cdef double l[r]
^
------------------------------------------------------------
test.pyx:13:20: Not allowed in a constant expression
添加修饰符找到与此相关的stackexchange帖子并阅读Cython由Kurt W. Smith所著。据我所知,这应该告诉Cython不要担心动态索引变量可能导致的超出范围的错误,但出于某种原因却不会。我也尝试过在编译器选项和全局范围内更改boundscheck,但无济于事。
The decorator was added due to finding this related stackexchange post and reading the Cython book by Kurt W. Smith. As far as I can tell this should work to tell Cython not to worry about out of bounds errors that may result from having a dynamic indexing variable but for some reason it does not. I have also tried changing boundscheck in the compiler options and globally to no avail.
如果不是Cython文档声称是最新的,我认为boundscheck已被贬值。
If it weren't for the Cython documentation claiming to be up to date I would think boundscheck has been depreciated.
我意识到我已经使用 import Cython
代替了 cimport cython
。我再次尝试使用
I realized I have used import Cython
instead of cimport cython
. I tried again with
cimport cython
但是会得到相同的错误。
But get the same error.
类似注意代码
cdef int N = 3
cdef double[:] lout = array.array('d', N)
抛出错误
TypeError: 'int' object is not iterable
我认为与C无法处理(可能)动态数组分配的原因相同。相反,我们必须使用
I assume for the same reason that C cannot deal with (possibly) dynamic array allocation. Instead we must use
cdef double[:] lout = numpy.empty(N, 'd')
我假设有一行在将N放入C数组之前将N转换为静态类型
and I assume there is a line that converts N into a static type somewhere before putting it into the C-array
推荐答案
故障与 cython.boundscheck
无关。
边界检查只是检查您是否尝试访问数组中不存在的元素。例如,如果您有一个大小为4的数组,并尝试访问元素5-使用 boundscheck(True)
,它将给您一个异常,使用 boundscheck(错)
会导致未定义的行为(可能导致分段错误)。
Boundchecking is just checking if you try to access an element of an array that isn't there. For example if you have a size 4 array and try to access element 5 - with boundscheck(True)
it will give you an Exception, with boundscheck(False)
it will result in undefined behavior (probably causing a segmentation fault).
编译失败的原因是另一个:用动态长度创建一个静态数组!在编译时需要知道元素的数量,这只是 c 强制执行(我想)。
The reason for the compilation failure is another: You can't create a static array with a dynamic length! The number of elements need to be known at compile time, that's just something c enforces (I guess).
不过,您可以定义 r
以便在编译时间:
However you could define r
to be known at compile time:
DEF r=4
cimport cython
@cython.boundscheck(False)
def boundtest():
cdef double l[r]
不过,您可以简单地创建一个NumPy数组并将其存储在memoryview变量中:
You could however simply create a NumPy array and store it in a memoryview variable:
cimport cython
import numpy as np
@cython.boundscheck(False)
def boundtest():
cdef int r=4
cdef double[:] l = np.empty(r, dtype=np.double)
这篇关于Cython“不允许在常量表达式中使用”,boundscheck False不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!