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?
-Travis
_______________________________________________
NumPy-Discussion mailing list
[email protected]
http://mail.scipy.org/mailman/listinfo/numpy-discussion