Reputation: 53
I am working on speeding up some Python/Numpy code with Cython, and am a bit unclear on the effects of "locally" setting (as defined here in the docs) compiler directives. In my case I'd like to use:
@cython.wraparound (False) #turn off negative indexing
@cython.boundscheck(False) #turn off bounds-checking
I understand that I can globally define this in my setup.py
file, but I'm developing for non-Cython users and would like the directives to be obvious from the .pyx
file.
If I am writing a .pyx
file with several functions defined in it, need I only set these once, or will they only apply to the next function defined? The reason I ask is that the documentation often says things like "turn off boundscheck
for this function," making me wonder whether it only applies to the next function defined.
In other words, do I need to do this:
import numpy as np
cimport numpy as np
cimport cython
ctypedef np.float64_t DTYPE_FLOAT_t
@cython.wraparound (False) #turn off negative indexing
@cython.boundscheck(False) # turn off bounds-checking
def myfunc1(np.ndarray[DTYPE_FLOAT_t] a):
do things here
def myfunc2(np.ndarray[DTYPE_FLOAT_t] b):
do things here
Or do I need to do this:
import numpy as np
cimport numpy as np
cimport cython
ctypedef np.float64_t DTYPE_FLOAT_t
@cython.wraparound (False) #turn off negative indexing
@cython.boundscheck(False) # turn off bounds-checking
def myfunc1(np.ndarray[DTYPE_FLOAT_t] a):
do things here
@cython.wraparound (False) #turn off negative indexing
@cython.boundscheck(False) # turn off bounds-checking
def myfunc2(np.ndarray[DTYPE_FLOAT_t] b):
do things here
Thanks!
Upvotes: 5
Views: 2235
Reputation: 40833
The documentation states that if you want to set a compiler directive globally, you need to do so with a comment at the top of the file. eg.
#!python
#cython: language_level=3, boundscheck=False
Upvotes: 7
Reputation: 140786
The manual does not say explicitly, but these directives are using decorator notation. In plain Python,
@decorator2
@decorator1
def fn(args):
body
is syntactic sugar for
def fn(args):
body
fn = decorator2(decorator1(fn))
So my expectation is that the directives work like that, which would mean that they apply only to the next function.
The Cython manual also says that the compiler directives can be used in with
statements. What it doesn't say, unfortunately, is whether those can appear at top level:
with cython.wraparound(False), cython.boundscheck(False):
def myfunc1(np.ndarray[DTYPE_FLOAT_t] a):
do things here
def myfunc2(np.ndarray[DTYPE_FLOAT_t] b):
do things here
might be what you're looking for, or then again it might be a syntax error or a no-op. You're going to have to try it and see.
Upvotes: 2