Fused Types w/ Runtime Dispatch

If you have a fused function that is exposed to Python, it also needs to be specialized from Python (in Cython space all this functionality already works). There are two ways to do this:

  • indexing
  • directly calling

For indexing from Python space, you can use (Cython) types or strings. So if you have a function in Cython like

    def f(cython.integral x, cython.floating y):
        print x, y

then it can be indexed as follows:

    module.f[cython.long, cython.double]
    module.f[int, float]
    module.f["int, long double"]

Please note that this example is for demonstration only, one could just use the largest types that are needed here.
All these index operations return a new specialized version of the function.

You can also call the function immediately, like

    module.f(10, 2.0)

and the specialized version with the largest types will be called, if it can be inferred from the types of the arguments, otherwise a TypeError is raised.

In an attempt to support all this, “binding Cython functions” were also made to be a bit more like actual Python functions. Vitja has added quite a bit more than just a __dict__, and functions should then also be pickle-able.

Because these binding functions can currently only be used for Python (def and cpdef) functions and methods of normal classes (non-extensions classes), the fused version (which will be a subclass) will bind differently based on whether it’s in a normal class, or in an extension class. In a normal class the methods expect self to be in the args tuple, or depending on the signature, as the second argument to the C function. In an extension class however, it expects code>self to be passed in as part of the PyCFunctionObject, through the m_self attribute (i.e., PyMethod_New vs PyDescr_NewMethod). Unfortunately, we cannot just at binding time decide to use which, because we need to be subscriptable after binding. So we have to implement tp_call and for extension methods bind self as m_self (so for unbound calls we need to get the tail of the args tuple) and for normal methods we need to type check args[0] (‘self’) for unbound calls.


About markflorisson

Blog for the Cython gsoc 2011
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s