On 04/10/2012 02:11 AM, Travis Oliphant wrote:
> Hi all,
>
> Some of you are aware of Numba. Numba allows you to create the equivalent
> of C-function's dynamically from Python. One purpose of this system is to
> allow NumPy to take these functions and use them in operations like ufuncs,
> generalized ufuncs, file-reading, fancy-indexing, and so forth. There are
> actually many use-cases that one can imagine for such things.
>
> One question is how do you pass this function pointer to the C-side. On
> the Python side, Numba allows you to get the raw integer address of the
> equivalent C-function pointer that it just created out of the Python code.
> One can think of this as a 32- or 64-bit integer that you can cast to a
> C-function pointer.
>
> Now, how should this C-function pointer be passed from Python to NumPy? One
> approach is just to pass it as an integer --- in other words have an API in C
> that accepts an integer as the first argument that the internal function
> interprets as a C-function pointer.
>
> This is essentially what ctypes does when creating a ctypes function pointer
> out of:
>
> func = ctypes.CFUNCTYPE(restype, *argtypes)(integer)
>
> Of course the problem with this is that you can easily hand it integers which
> don't make sense and which will cause a segfault when control is passed to
> this "function"
>
> We could also piggy-back on-top of Ctypes and assume that a ctypes
> function-pointer object is passed in. This allows some error-checking at
> least and also has the benefit that one could use ctypes to access a
> c-function library where these functions were defined. I'm leaning towards
> this approach.
>
> Now, the issue is how to get the C-function pointer (that npy_intp integer)
> back and hand it off internally. Unfortunately, ctypes does not make it
> very easy to get this address (that I can see). There is no ctypes C-API,
> for example. There are two potential options:
>
> 1) Create an API for such Ctypes function pointers in NumPy and use the
> ctypes object structure. If ctypes were to ever change it's object structure
> we would have to adapt this API.
>
> Something like this is what is envisioned here:
>
> typedef struct {
> PyObject_HEAD
> char *b_ptr;
> } _cfuncptr_object;
>
> then the function pointer is:
>
> (*((void **)(((_sp_cfuncptr_object *)(obj))->b_ptr)))
>
> which could be wrapped-up into a nice little NumPy C-API call like
>
> void * Npy_ctypes_funcptr(obj)
>
>
> 2) Use the Python API of ctypes to do the same thing. This has the
> advantage of not needing to mirror the simple _cfuncptr_object structure in
> NumPy but it is *much* slower to get the address. It basically does the
> equivalent of
>
> ctypes.cast(obj, ctypes.c_void_p).value
>
>
> There is working code for this in the ctypes_callback branch of my
> scipy fork on github.
>
>
> I would like to propose two things:
>
> * creating a Npy_ctypes_funcptr(obj) function in the C-API of NumPy and
> * implement it with the simple pointer dereference above (option #1)
>
>
> Thoughts?
I really hope we can find some project-neutral common ground, so that
lots of tools (Cython, f2py, numba, C extensions in NumPy and SciPy) can
agree on how to "unbox callables".
A new extension type in NumPy would not fit this bill I feel. I've
created a specification for this; if a number of projects (the ones
mentioned above) agree on this or something similar and implement
support, we could propose a PEP and do it properly once it has proven
itself.
http://wiki.cython.org/enhancements/cep1000
In Cython, this may take the form
def call_callback(object func):
cdef double (*typed_func)(int)
typed_func = func
return typed_func(4)
...it would be awesome if passing a Numba-compiled function just worked
in this example.
Dag
_______________________________________________
NumPy-Discussion mailing list
[email protected]
http://mail.scipy.org/mailman/listinfo/numpy-discussion