[pythran] JIT typing

  • From: serge Guelton <serge.guelton@xxxxxxxxxxxxxxxx>
  • To: Mehdi AMINI <mehdi.amini@xxxxxxxxxxxxxxx>
  • Date: Wed, 27 Mar 2013 22:37:01 +0100

Hi Mehdi (and other pythraners),

some toughts of how we could use decorators to make pythran easier to
use.

First it is not a novel approach. Copperhead, nuitka, numba are all
already implementing this or planning to. The difference is that pythran
is not a jit compiler, and C++ compilation time would make it useless at
such, at least in production. It would be still useful for testing.

Let's consider the following function

def add(self, other): return self + other

it is polymorphic, and works for various parameter types. Pythran
supports this perfectly thanks to template. What numba does is

@numba.autojit
def add(self, other): return self + other

and when the function is called, we have the effective parameter types
so we can instantiate the template. Still it is useful for debugging.

Otherwise they accept

@numba.jit("typedesciption1", "typedescription2")

which would be, for pythran
@pythran.jit("(int list, int list)")

quite ugly. First i'd rather get rid of jit and use native instead,
because we are not jitting much there.

@pythran.native("int list, int list", "int, float")

the type description is still not very pythonic, but at least it is the
consistent with the pythran export spec, which is a start.


Given such generator, we could

1/ take it into account in addition to export commands when running
pythran. in that case the whole file is pythran compatible (I don't
quite like this option, it is a subcase of 2/)

2/ take it into account in addition to export commands when running 
pythran, but generate a file.pyc holding non-pythran code, and a
_file.so loaded by the pyc to implement the native functions (I like
this option)

3/ use it as a real generator and dynamically run the compiler,
hopefully using a cahce to avoid calling the compiler twice, and
apologizing for the slowness of c++ compilation (I like this option
inside ipython, but not otherwise) It is compatible with 2/

I'll detail 2/


<<<input.py>>>
import pythran

def foo(a): return getattr(a,'pop') # not pythranic at all
@pythran.native('int, int')
def bar(a,b): return a%b

After running pythran, we would get two files

<<<input.pyc>>> which is the bytecode for
from _input import bar
def foo(a): return getattr(a,'pop')

and
<<<_input.so>>> which is the pythran compilation of
#pythran export bar(int, int)
def bar(a,b): return a%b



IMPORTANT NOTE

callgraph consideration: if a native function calls other functions, we
have two options
1/ all called functions are marked native
2/ we try to statically infer the called function, because it should be
possible based on ImportedIds, and it makes life easier to the
programmer --- he does not need to annotate all functions, but only the
entry points (I tend to like this one)


Wooo, that was a long one :-)

Other related posts: