Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
617 views
in Technique[技术] by (71.8m points)

python - Cython compilation error "Not allowed in a constant expression"

The following

cimport cython

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

works fine. But when I try this:

cimport cython

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

I receive the following error:

[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
     

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.

If it weren't for the Cython documentation claiming to be up to date I would think boundscheck has been depreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The failure has nothing to do with cython.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).

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 enforces (I guess).

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]

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...