At the moment I’m working on some maths code written in a combination of standard Python and its mathematical superset, Sage. The code is fairly computationally expensive (it’s essentially a brute force search for chemical reaction networks that are monotone). Consequently, after getting the code working as a proof-of-concept, I wanted to compile it to C using Cython to get a bit more speed out of it. I found the documentation on converting Sage and Python scripts to Cython a bit vague, particularly when it comes to combining the two, so this article gives step by step instructions based on my findings.
Getting started
Throughout this article I will assume that you already have Sage installed and working under the path /usr/local/share/sage
. For the sake of this example, I'll assume you want to combine two files: a main Sage script called main.spyx
, and a supporting Python library called library.pyx
. Note the .(s)pyx
extensions, denoting that the files will be compiled using Cython, instead of the default .sage
and .py
extensions.
Compiling the Python library
First, you’ll need to compile your Python library. To do this, create a file called setup.py
containing the following:
#!/usr/local/share/sage/local/bin/python from distutils.core import setup from Cython.Build import cythonize setup( name = 'Cython test library', ext_modules = cythonize( 'library.pyx' ), )
This tells Python how to compile the library. You can then compile it using the command
/usr/local/share/sage/local/bin/python setup.py build_ext --inplace
Note the fully-qualified path to Sage’s version of Python. Do not use your default system Python version! Once this has completed, you should have a file library.so
, which is the Cython compiled version of your library, ready to be imported into Sage, using the line import library
, in exactly the same way as a regular Sage or Python file. Note that each time you change the library, you will need to rerun the build_ext
step to recompile it.
Compiling the Sage script
Now you’re ready to run your Sage script. Unlike the Python library, this will not need rebuilding each time it is changed: Sage is able to detect when the script has changed, and will recompile accordingly. All you need is to run it as you would an ordinary Sage script, although you must make sure to include the file extension:
sage main.spyx
References:
http://docs.cython.org/src/quickstart/build.html
http://www.sagemath.org/doc/developer/coding_in_cython.html