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 startedThroughout 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)pyxextensions, denoting that the files will be compiled using Cython, instead of the default
Compiling the Python libraryFirst, you’ll need to compile your Python library. To do this, create a file called
setup.pycontaining 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 --inplaceNote 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_extstep to recompile it.
Compiling the Sage scriptNow 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.spyxReferences: http://docs.cython.org/src/quickstart/build.html http://www.sagemath.org/doc/developer/coding_in_cython.html