Welcome to jitpy’s documentation!¶

What it jitpy?¶ jitpy is a hack to embed PyPy inside CPython: the goal is to let PyPy optimize selected functions and call them from CPython. The provided interface is limited: you can pass only simple builtin immutable types and numpy arrays. In other words, you cannot pass lists, dicts, and instances of custom classes. The usage pattern is similar to numba, though it does have very different characteristics. A simple example from jitpy import setup setup ( '<path-to-pypy-home>' ) from jitpy.wrapper import jittify @jittify ([ int , float ], float ) def func ( count , no ): s = 0 for i in range ( count ): s += no return s func ( 100000 , 1.2 ) This function will be executed by the underlying PyPy, thus yielding a significant speed benefit (around 50x in my own measurements).

Motivation¶ The idea behind jitpy is to lower the barrier of entry to PyPy. A lot of people have complicated dependencies that don’t work under PyPy, yet they want some way to speed up numeric computations. This is where jitpy comes to play.

Installing¶ You can install jitpy using pip install jitpy in your CPython installation.. You also need to download and unpack a very recent PyPy (newer than 2nd of Dec 2014), which can be e.g. downloaded from PyPy nightlies. An example of usage: Download 64bit binary or 32bit binary for linux: ~$ wget http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-74798-f1b314da580e-linux64.tar.bz2 ~$ tar xjf pypy-c-jit-74798-f1b314da580e-linux64.tar.bz2 ~$ export PYPY_HOME=`pwd`/pypy-c-jit-74798-f1b314da580e-linux64/bin/ ~$ pip install jitpy And you should be able to run examples (NOTE: since jitpy takes source code via inspect module, you can’t run jittify on functions typed from python interactive prompt)

Using jitpy¶ jitpy is not magic - what it does is to move code across the boundary between the two different Python implementations. It means that while PyPy and CPython don’t share any data, you can pass ints , floats , strings and numpy arrays without copying, since it’s done in-process. It’s also faster compared to out-of-process solutions, like multiprocessing . However, one needs to remember that the global state and the namespaces of the two interpreters are separate, which means that the functions and classes declared on CPython won’t be automatically available in PyPy, and viceversa. Moreover, if you import the same module in both interpreters, the module will be actually imported twice, which can make a difference in case of modules which have side-effects when imported. The API looks like this: jitpy.setup(pypy_home=None) - has to be called before anything in order to point to the correct PyPy build directory. pypy_home points to the directory of pypy checkout/installation. If None is passed, it’ll default to PYPY_HOME environment variable.

jitpy.wrapper.jittify(argtypes, restype=None) - a wrapper that’s passed argument types as a list and restype as on of the: int, float, string - immutable types. Additionally None can be used for return type 'array' - a numpy array, can only be used as an argument, not a return value. Also only simple types are supported for now (no compound dtypes, no string, unicode) or object dtypes

jitpy.extra_source(source) - executes source inside PyPy. The classes and functions defined there will be visible by the functions decorated with @jittify . For example: jitpy . extra_source ( """ class X: def __init__(self, x): self.x = x """ ) class Y ( object ): pass @jitpy.wrapper.jittify ([], int ) def func (): return X ( 42 ) . x func () this will work, however trying to reference Y from inside the func will result in a NameError exception. Differently than numba, you can use all Python constructs inside jitted functions, including the most dynamic ones like import , pdb , sys._getframe , ex ec , etc. However note that sys.path is not inherited: if you want to include extra directories in sys.path , you need to modify it explicitly using jitpy.extra_source .

Limitations¶ The API is limited to builtin types, because it’s easy to see how the boundary looks like. Numpy arrays can be shared, because the data is visible as a pointer in C on the low level. sys.path has to be initialized separately, but will respect all the libraries installed in the underlying pypy .