Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cython compilation - import vs cimport

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)?

like image 802
uday Avatar asked Mar 27 '15 22:03

uday


2 Answers

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.

like image 92
HYRY Avatar answered Nov 17 '22 18:11

HYRY


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.

like image 31
colinfang Avatar answered Nov 17 '22 20:11

colinfang