Cython

From Bauman National Library
This page was last modified on 8 June 2016, at 21:02.
Cython
fraimed
Developer Robert Bradshaw, Stefan Behnel, et al.
First appeared 28 July 2007; 15 years ago (2007-07-28)[1]
Implementation language Python, C
OS Cross-platform
License Apache License
Website cython.org

Cython - a programming language that simplifies the writing module C / C++ code to Python. In addition to the standard syntax, Python, are supported:

  • a direct challenge to the functions and methods of the C / C++ code from Cython;
  • strong typing of variables, classes, class attributes.

Cython code is converted into the C / C++ code for a subsequent compilation and may subsequently be used as an extension to the standard Python or as an independent application with built-in library performance Cython.

History

Cython is derived from the language Pyrex, but imeeet more opportunities and better optimization than Pyrex. Cython separated from Pyrex in 2007, the developers of computer algebra package Sage, because they were dissatisfied with the limitations of Pyrex. Initially, the project was named SageX. When developers have found that people Sage downloads only, to get SageX, SageX was in a separate project by Sage and unite with Cython-LXML, then called Cython.

Description

The essence of nature Cython'a can be expressed in the following words: Cython - this is Python data types of language C. Cython - this is Python, in the sense that almost any Python code will be valid from the point of view Cython (and although there are some limit, but in a first approximation this case). Cython compiler converts it to code in C, that will do the equivalent calls to the Python / C API. However Cython greater than Python, because the parameters and variables can specify the types of C. In the code, you can use the data in parallel Python-type and C-type, and the conversion is done automatically, wherever possible. In addition, links are counted and validation errors in Python-operation, that is available to you all the power of Python error handling, including design try-except and try-finally, - even in the C-data types.

Basics

Definitions and types of variables

Note cdef variables to C-types (both locally and at the module level):

cdef int i, j, k
cdef float f, g [42], *h

and C-type struct , union or enum :

cdef struct Grail:
    int age
    float volume

cdef union Food:
    char *spam
    float *eggs

cdef enum CheeseType:
    cheddar, edam,
    camembert

cdef enum CheeseState:
    hard = 1
    soft = 2
    runny = 3

Functions

Cython allows you to define a function in one of two ways:

  • Python-functions are defined by using the def , as in Python. They take as parameters Python-object and returns too Python-objects.
  • C-functions are defined using the new instruction cdef . They can receive and return a Python-like objects and values ​​of C-types.

Within one Cython-module functions of different types may be freely call each other, but from the outside for the import and use of Python-only available functions. That is, if you want to "export" function from Cython-module, it should be declared as a Python-function by using the def . There is also a hybrid version called cpdef , these functions are accessible from anywhere, but use a quick launch of the agreement when called from Cython-code. With any method of determining the function, you can declare the type of its parameters using a standard syntax C. For example:

def spam (int i, char *s):
    ...

cdef int eggs (unsigned long l, float f):

When you declare a type parameter Python-function, it is passed as a Python-object and is automatically converted to the value of C, if possible. At the moment, the automatic conversion is available only for numeric and string types; attempt to use other types of parameters in Python-functions will cause a compilation error. C-receive functions may also be any type of parameters as they are transmitted directly using the standard call C.

Classes

For compatibility with the object-oriented approach, Cython supports regular classes as well as Python:

class MathFunction (object):
    def __init __ (self, name, operator):
        self.name = name
        self.operator = operator

    def __call __ (self, *operands):
        return self.operator (*operands)

In addition to the built-in Python types, Cython allows you to use another type of classes: extension types, sometimes called "cdef-classes" on behalf of the keyword used for their ads. With some limitations as compared with the conventional Python-classes, they generally use less memory and CPU time. The main difference is that they keep their attributes and methods in a C-object struct , and not in Python-dictionary. This allows you to store values ​​of arbitrary C-types, without turning them into Python-objects and have direct access to the attributes and methods at C without having to search for them in Python-dictionary. Conventional Python-classes can inherit from cdef-class, but not vice versa. Cython should know the entire inheritance hierarchy to prepare the desired C-struct'y, and allows a single parent class. Python-classes also can inherit from any number of classes of any type (built-in, additional or normal) in the code to Cython, and in pure Python .. We write as an example of function integration. To do this, create a cdef-class to represent the function on the floating-point numbers:

cdef class Function:
    cpdef double evaluate (self, double x) except *:
        return 0

cdef class SinOfSquareFunction (Function):
    cpdef double evaluate (self, double x) except *:
        return sin (x ** 2)

def integrate (Function f, double a, double b, int N):
  cdef int i
  cdef double s, dx
  if f is None:
      raise ValueError ("f can not be None")
  s = 0
  dx = (b-a) / N
  for i in range (N):
      s + = f.evaluate (a + i * dx)
  return s *dx

print (integrate (SinOfSquareFunction (), 0, 1, 10000))

This function will work in almost 200 times faster than its counterpart in pure python.

Automatic casting

If Python-object is used in a context that requires a C-value (or vice versa), for the basic numeric and string types, the conversion is done automatically.

C-types From the Python-type For Python-type
[unsigned] char, [unsigned] short, int, long int, long int
unsigned int, unsigned long, [unsigned] long long int, long long
float, double, long double int, long, float float
char * str/bytes str/bytes
struct dict

Differences between C expression and Cython

There are some differences in the syntax and semantics of the C-expression and Sython expressions, especially in designs C, no direct counterpart in Python.

  • An integer literal is treated as C-constant and may be truncated at the discretion of your compiler C. To get a Python integer (any precision), just convert it explicitly in Python-object (for example, <object> 100000000000000000000) . Suffixes L , LL and U have the same meaning as in C.
  • The operator -> is absent. Instead of p-> x email px .
  • The unary operator * is absent. Instead of *p using p[0] .
  • The operator & preserves the semantics of C.
  • Null pointer called NULL , and not 0 . NULL is a reserved word.
  • Typecasting is written as <type> value, for example:
cdef char *p, float *q
p = <char *> q

Sample Code

A simple application

Since Cython able to handle almost any valid Python code, the most difficult thing that you have to do first - just to understand how to compile your extension. So, take the traditional program in Python:

print "Hello World"

The first step is to rename the file helloworld.pyx . Then you need to create the file setup.py , which will serve as something of a Makefile. Your setup.py to start would be:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup (
    cmdclass = {'build_ext': build_ext},
    ext_modules = [Extension ("helloworld", ["helloworld.pyx"])]
)

Now, to compile Cython-file run the following command:

$ [[Python]] setup.py build_ext --inplace

As a result, the local folder is a file named helloworld.so (in Unix-system) or helloworld.dll (in Windows). Using this file is simple: run the Python interpreter and import as a regular module:

>>> Import helloworld
Hello World

Congratulations! Now you know how to compile modules written in Cython. However, while this example is not particularly inspiring to use it, so let's try something more close to reality.

Primes

Now, the example of a small program primes.pyx for finding prime numbers show some possibilities Cython'a. The program takes an integer and returns the specified number of primes in a Python-list.

def primes (int kmax):
    cdef int n, k, i
    cdef int p [1000]
    result = []
    if kmax> 1000:
        kmax = 1000
    k = 0
    n = 2
    while k <kmax:
        i = 0
        while i <k and n% p [i]! = 0:
            i = i + 1
        if i == k:
            p [k] = n
            k = k + 1
            result.append (n)
        n = n + 1
    return result

As we can see, the beginning is no different from the conventional definition of the function in Python, except that the type of the parameter kmax is declared as int . This means that the passed parameter is converted in the C-type integer (in case of impossibility of such a transformation exception will be raised TypeError ).

Lines 2 and 3 are determined by several local variables with the help of instructions cdef . Line 4 creates a Python-list in which the result is returned. It should be noted that the variable type is not specified (as in pure Python), so it will contain Python-object.

Rows 7-9 organize cycle for primality checking, as long as they will not be found for the specified amount. Particular attention should be 11-12 rows, where the division of the audited results of all hitherto primes. As this cycle does not use any Python-objects, it is entirely translated into pure C code, and therefore is very fast.

If the number was simple, lines 14-15 it is added to an array of p for quick access verification inside the cycle line 16 and adds it to the result list. Line 16 looks like a normal expression of Python, and so it is, in fact, is the only parameter n is automatically converted into Python-object for the transmission method append. Finally, in line 18 typically Python-expression returns the result.

After compiling the primes.pyx Cython'om we get the extension, which can immediately check into the interpreter session:

>>> Import primes
>>> Primes.primes (10)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Look, works! Well, if you're curious how much work you save Cython, you can look at the C-code generated for this module.

The use of language

Cython especially popular among users of scientific Python, that for him the "ideal audience", according to the developer Python Guido van Rossum. Separately, it is worth noting:

  • A significant part of scientific computing libraries SciPy, pandas and scikit-learn written in Cython.
  • Some sites with high traffic, such as Quora used Cython.
  • Cython not limited to the numerical calculations. For example, LXML XML-tool written mostly in Cython.
  • Like its predecessor Pyrex, Cython used to provide some reference to the Python C and C++ libraries such as the library messaging ZeroMQ.
  • Cython can also be used for the development of parallel programs for multi-core processors machines (using the library OpenMP).

Links

  • Dr. Behnel, Stefan (2008). "The Cython Compiler for C-Extensions in Python". EuroPython (28 July 2007: official Cython launch). Vilnius/Lietuva.