Beyond Python

This is a small collection of thoughts related to the inclusion of code written in languages other than Python. Currently, the only option for languages other than Python that we have extra documentation for is Cython.

Can I use a programming language other than Python to speed up my code?

Yes. The languages used in SciPy are Python, Cython, Pythran, C, C++, and Fortran. All of these have their pros and cons. If Python really doesn’t offer enough performance, one of those languages can be used. Important concerns when using compiled languages are maintainability and portability. For maintainability, Pythran and Cython are preferred over C/C++/Fortran. Cython, C and C++ are more portable than Fortran. A lot of the existing Fortran code in SciPy is older, battle-tested code that was only wrapped in (but not specifically written for) Python/SciPy.

Our basic advice is: use Pythran or Cython for accelerating smaller pieces of code. In cases where Pythran or Cython are no longer enough, prefer C or C++. If there are specific reasons why Fortran is preferred, please discuss those reasons first.

Can I use Numba?

Not yet, but we’re considering it for the future. It is possible to write code that takes user-defined functions which are generated by Numba, see Extending scipy.ndimage in C.

How do I debug code written in C/C++/Fortran inside SciPy?

The easiest way to do this is to first write a Python script that invokes the C code whose execution you want to debug. For instance mytest.py:

from scipy.special import hyp2f1
print(hyp2f1(5.0, 1.0, -1.8, 0.95))

Now, you can run:

gdb --args python runtests.py -g --python mytest.py

If you didn’t compile with debug symbols enabled before, remove the build directory first. While in the debugger:

(gdb) break cephes_hyp2f1
(gdb) run

The execution will now stop at the corresponding C function and you can step through it as usual. Instead of plain gdb you can, of course, use your favorite alternative debugger; run it on the python binary with arguments runtests.py -g --python mytest.py.