Newbie to Cython (perhaps this is a basic question). Consider two examples both taken from this blog here:
# code 1
import numpy as np
def num_update(u):
u[1:-1,1:-1] = ((u[2:,1:-1]+u[:-2,1:-1])*dy2 +
(u[1:-1,2:] + u[1:-1,:-2])*dx2) / (2*(dx2+dy2))
and
# code 2
cimport numpy as np
def cy_update(np.ndarray[double, ndim=2] u, double dx2, double dy2):
cdef unsigned int i, j
for i in xrange(1,u.shape[0]-1):
for j in xrange(1, u.shape[1]-1):
u[i,j] = ((u[i+1, j] + u[i-1, j]) * dy2 +
(u[i, j+1] + u[i, j-1]) * dx2) / (2*(dx2+dy2))
Suppose I compile the first file with the following setup.py
script:
# setup file for code 1
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext = Extension("laplace", ["laplace.pyx"],)
setup(ext_modules=[ext], cmdclass = {'build_ext': build_ext})
and the second file with the following setup.py
script:
# setup file for code 2
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
ext = Extension("laplace", ["laplace.pyx"],
include_dirs = [numpy.get_include()])
setup(ext_modules=[ext], cmdclass = {'build_ext': build_ext})
In the 1st case, I used regular numpy
and didn't import numpy
in the setup file, while in the 2nd case I imported numpy
using cimport
, declared variables using cdef
but then also included numpy
in the setup file.
Cython
compiles the first code anyway (and the first code seems to work).
What would be advantages of using cimport
and cdef
before compiling with Cython (via the setup file) versus not using cimport
and cdef
before compiling with Cython (via the setup file)?
import numpy
in Cython is the same as Python, but cimport numpy
tells Cython to load the declare file:
https://github.com/cython/cython/blob/master/Cython/Includes/numpy/init.pxd
where declares all the C-API functions, constants, and types, and also include the header files, such as numpy/arrayobject.h
.
If you declare variable with np.ndarray[...]
, Cython will know how to convert array element access into c code which is much faster then Python's []
operator.
You need to tell the c compiler where are the numpy header files in setup.py
, so you call numpy.get_include()
to get the path.
Cython can compile normal python code, so your first one compiles.
Generally speaking, the more types you mark up for cython, the more chance you will get better performance. So it is your decision if you want to trade flexibility for speed.
Run cython -a your_test.pyx
to see an annotated version of how cython would compile your code. The yellow means your code converts to a lot of C code (which roughly implies performance penalty), while white means it converts to only a few lines of C.
If you hadn't spent the time asking here, but instead read through the guide in the official website, you could have got a better understanding already.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With