I am trying to use Numba cfunc
as scipy.LowLevelCallable
inside ndi.generic_filter
however I am facing signature matching issue. If I set return type to int16
it recognize as short
if I set to int32
or intc
it says long
. Both signatures cannot be matched. The matching problem is in return type
import numpy as np
import scipy
from numba import cfunc, carray, types
import scipy.ndimage as ndi
@cfunc("intc (CPointer(float64),intp, CPointer(float64), voidptr)") #problematic
def myfunc(values_ptr, len_values, result, data):
#some work here
return 1
footprint = np.array([[0, 1, 0],[1, 1, 1],[0, 1, 0]], dtype=bool)
from scipy import ndimage as ndi
a=np.random.random((100,100))
ndi.generic_filter(a, scipy.LowLevelCallable(myfunc.ctypes), footprint=footprint)
This is the Error:
ValueError: Invalid scipy.LowLevelCallable signature "long (double *, long, double *, void *)". Expected one of: ['int (double *, intptr_t, double *, void *)', 'int (double *, npy_intp, double *, void *)', 'int (double *, int, double *, void *)', 'int (double *, long, double *, void *)']
System specs (if related): Python 2.7.10 (32-bit), Numba 0.39.0
It seems that you ran into this known issue. Specifically, there appears to be no way to produce the signature expected by LowLevelCallable
with Numba on platforms where int
and long
are the same size (such as 64 bit flavors of Windows).
I suggest you support a fix on GitHub. In the meantime, your best bet is to pass the Numba functon directly into generic_filter
and accept some function call overhead, or to wrap the function in a supported way, e.g. via Cython.