Cython“不允许在常量表达式中使用”,boundscheck False不起作用 [英] Cython "Not allowed in a constant expression", boundscheck False doesn't work

查看:157
本文介绍了Cython“不允许在常量表达式中使用”,boundscheck False不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆