Author Topic: Cython  (Read 2080 times)

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Cython
« on: June 15, 2011, 04:50:12 pm »
Cython is a python extension that takes a slightly modified Python script file and converts it to C code. That way, it will run about 5-70× as fast on average as the regular python script. Also, python extensions can be written in python.

Pros:
★ Huge speed improvement (can be faster than 70× faster than plain python)
★ Ability to write python extensions with python
★ Added ability to import Cython scripts invisibly with the regular import command
★ Ability to create frozen binaries
★ Ability to combine both C and Python in one binary
★ Very little modification to original python script makes a big difference in speed
★ No editing to source file required
★ By using cython -a and then viewing the outputted html file in a web viewer, you can see which lines of code use python apis (slow), and which ones can be converted to plain c (fast)

Cons:
☆ Must have a working gcc (GNU C Compiler), which is a pain in the @$$ to get working properly on iphoneos
☆ Must have minimal knowledge of C for advanced code optimization


I have built and compiled this already, i just dont have a repo to upload to. Boo? Would you like to host it? Ill build the deb.


Here is the help and usage for the cython shell script:
Quote
Cython (http://cython.org) is a compiler for code written in the
Cython language.  Cython is based on Pyrex by Greg Ewing.

Usage: cython [options] sourcefile.{pyx,py} ...

Options:
  -V, --version                  Display version number of cython compiler
  -l, --create-listing           Write error messages to a listing file
  -I, --include-dir <directory>  Search for include files in named directory
                                 (multiple include directories are allowed).
  -o, --output-file <filename>   Specify name of generated C file
  -t, --timestamps               Only compile newer source files
  -f, --force                    Compile all source files (overrides implied -t)
  -q, --quiet                    Don't print module names in recursive mode
  -v, --verbose                  Be verbose, print file names on multiple compilation
  -p, --embed-positions          If specified, the positions in Cython files of each
                                 function definition is embedded in its docstring.
  --cleanup <level>              Release interned objects on python exit, for memory debugging.
                                 Level indicates aggressiveness, default 0 releases nothing.
  -w, --working <directory>      Sets the working directory for Cython (the directory modules
                                 are searched from)
  --gdb                          Output debug information for cygdb

  -D, --no-docstrings            Strip docstrings from the compiled module.
  -a, --annotate                 Produce a colorized HTML version of the source.
  --line-directives              Produce #line directives pointing to the .pyx source
  --cplus                        Output a C++ rather than C file.
  --embed                        Generate a main() function that embeds the Python interpreter.
  -2                             Compile based on Python-2 syntax and code semantics.
  -3                             Compile based on Python-3 syntax and code semantics.
  --fast-fail                    Abort the compilation on the first error
  -X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive

Edit: Pros and Cons changed. There are actually no required modifications to the original python script.

Edit: Ways to compile:

1) cython shell script

2)
Code: (Python) [Select]
import pyximport
pyximport.install()

import myCythonScript
PyxInstall allows you to automatically build and compile cython scripts with normal import command.

3) site-packages/sitecustomize.py
↑this file is always run on python start. If you add the following code to it, then the standard import command will always import cython files:
Code: (Python) [Select]
import pyximport
pyximport.install()
pyximport.install() takes an optional argument, which specifies whether or not normal python files should be attempted to be compiled with cython during import or not.

4) distutils setup.py
This is probably the most cumbersome method of compiling, because you must write a new python script for each cython file. There is plenty of documentation about this online, so ill let you google it if you want to use this method of compiling.


I usually use either option 1) or 3).


The Cython script files are .pyx files. Here is a comparison of a Python script and a Cython script. Both files find prime numbers.

Normal python code:
Code: (Python) [Select]
def primes(kmax):
    p = []
    k = 0
    n = 2
    while k < kmax:
        i = 0
        while i < k and n % p[i] != 0:
            i = i + 1
        if i == k:
            p.append(n)
            k = k + 1
        n = n + 1
    return p


Faster cython code:
Code: (Cython) [Select]
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

Notice the similarity?


Look at this:

Filename: cmath.pyx
Code: (Python) [Select]
cdef extern from "math.h":
    double c_lgamma "lgamma" (double)
    double c_exp "exp" (double)

def exp(n):
    """Return e**n."""
    return c_exp(n)

def lfactorial(n):
    """Return an estimate of the log factorial of n."""
    return c_lgamma(n+1)

def factorial(n):
    """Return an estimate of the factorial of n."""
    return c_exp( c_lgamma(n+1) )


if __name__ == "__main__":
    import sys
    if len(sys.argv) != 2:
        sys.stderr.write("USAGE: %s n\nPrints n!.\n" % sys.argv[0])
        sys.exit(2)
    n, = map(float, sys.argv[1:])
    print factorial(n)

And:

Filename: combinatorics.pyx
Code: (Python) [Select]
import cmath

def nCr(n, r):
    """Return the number of ways to choose r elements of a set of n."""
    return cmath.exp( cmath.lfactorial(n) - cmath.lfactorial(r)
                      - cmath.lfactorial(n-r) )

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 3:
        sys.stderr.write("USAGE: %s n r\nPrints n-choose-r.\n" % sys.argv[0])
        sys.exit(2)
    n, r = map(float, sys.argv[1:])
    print nCr(n, r)

The cdef extern from "math.h" part loads a c function from a header. Cython can run c code.


In cython, code files end with the .pyx extension. It is python with c data types. Here i have a cython script, very simple.

cdef char* sayHi():
    return "Hello, world!"

print(sayHi())


This is the same as python except for the first line. cdef means that you are defining an object with a c data type. For example, cdef int count = 5. cdef does not necessarily mean to define a function, but could define functions, classes, and variables. char* sayHi(): means that a function called sayHi will be created and will return a char* value. A char* is like a c version of a string. Notice the return "Hello, world!". it returns a python string, which Cython automatically converts to a char*, or a c string. Then, now that sayHi() is defined, we do print(sayHi()). What this means is that we will print to stdout, or the terminal screen, whatever value that the function sayHi() returns. Since we made sayHi() always return the string "Hello, world!", then print will output the following: Hello, world!

Heres a screenshot of how this works:



I am able to run hello.pyx via the import command because i ran this beforehand: import pyximport; pyximport.install().
You didnt see me run it, because i put this line of code in /usr/lib/python2.5/site-packages/sitecustomize.py. This file, sitecustomize.py, is always executed when the python interpreter starts. pyximport.install() adds functionality to the import command to automatically compile cython files and run them as if they were normal python code. When i package Cython, i will make two packages: Cython, and pyximport. When you install pyximport, it will automatically add this line of code to sitecustomize.py. Release coming soon.

Ironman

  • Administrator
  • Hero Member
  • *****
  • Posts: 5108
  • Reputation: 252
  • Badges:
  • Computers: ASUS UL50VT
  • iDevices: iPhone 5, iPhone 4S, iPhone 4, iPhone 3GS
Re: Cython
« Reply #1 on: June 15, 2011, 04:53:25 pm »
Nice!!
Click for How to Add Our Repo
If you're going to ask questions....
At least make them good ones.

Knowledge is the one thing that can never be taken from you

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Re: Cython
« Reply #2 on: June 15, 2011, 04:57:18 pm »
Thanks. For all of that post, id say it took about an hour to type on ipod and come up with the tutorial, not to mention bbc code formatting and such. Since theres no image upload script yet, i had to upload the image manually via sftp. Compiling cython itself took a few hours, as did testing. Its done though. Im just workinh on metadata and installation / uninstall scripts.

PaulBird

  • Sr. Member
  • ****
  • Posts: 485
  • Reputation: 5
  • Every problem is an opportunity in disguise
    • Google
  • Badges:
Re: Cython
« Reply #3 on: June 15, 2011, 08:23:11 pm »
package tht *****! ;)
People Never Get The Flowers While They Can Still Smell Them

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Re: Cython
« Reply #4 on: June 15, 2011, 09:11:52 pm »
Already packaged. In testing phase (by a12).

Don't like seeing ads? Click here to register!

PaulBird

  • Sr. Member
  • ****
  • Posts: 485
  • Reputation: 5
  • Every problem is an opportunity in disguise
    • Google
  • Badges:
Re: Cython
« Reply #5 on: June 15, 2011, 10:00:07 pm »
can i please have a link to test?? thanks :)

u can just pm me???
cus im very interested in this. and know python and c/c++ :)
People Never Get The Flowers While They Can Still Smell Them

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Re: Cython
« Reply #6 on: June 16, 2011, 01:09:52 am »
Beta testing link: https://ininjas.com/beta/
Install in this order:
Cython
Pyxinstall
Hellocython

Dont worry about hello.pyx.

After you install these debs, do this:

cd /var/root
python
>>> import hellocython


If you see Hello, world!, then it works.

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Re: Cython
« Reply #7 on: June 19, 2011, 04:31:25 am »
Cython is now in the repo! Install it with cydia and enjoy!

Ironman

  • Administrator
  • Hero Member
  • *****
  • Posts: 5108
  • Reputation: 252
  • Badges:
  • Computers: ASUS UL50VT
  • iDevices: iPhone 5, iPhone 4S, iPhone 4, iPhone 3GS
Re: Cython
« Reply #8 on: June 19, 2011, 11:33:47 am »
Very cool!!
Click for How to Add Our Repo
If you're going to ask questions....
At least make them good ones.

Knowledge is the one thing that can never be taken from you

BooCocky

  • Leader
  • Hero Member
  • *****
  • Posts: 875
  • Reputation: 81
  • All your base are belong to ininjas
  • Badges:
  • Computers: Dell Inspirion
  • iDevices: ipod shuffle
Re: Cython
« Reply #9 on: July 15, 2011, 10:00:57 am »
cython works for me, but when I go to compile it says Im missing the python.h.

Don't like seeing ads? Click here to register!

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Re: Cython
« Reply #10 on: July 15, 2011, 03:22:23 pm »
It should be in /usr/include/python2.5

BooCocky

  • Leader
  • Hero Member
  • *****
  • Posts: 875
  • Reputation: 81
  • All your base are belong to ininjas
  • Badges:
  • Computers: Dell Inspirion
  • iDevices: ipod shuffle
Re: Cython
« Reply #11 on: July 18, 2011, 12:19:27 pm »
ahh, it is.  But it is named Python.h instead of python.h.  Thanks :)

C0deH4cker

  • Hero Member
  • *****
  • Posts: 2849
  • Reputation: 129
  • I am leaving iNinjas. Contact me via email.
  • Badges:
  • iDevices: iPhone 4S 16gb Black (5.1.1), iPad 2 32gb White (5.0.1), iPod Touch 2G 8gb (4.2.1)
Re: Cython
« Reply #12 on: July 18, 2011, 01:58:17 pm »
Gotcha. I thought u just typed it wrong here.