Indeed, if both argument types have 10 specializations, you'll get 10
* 10 specializations. There's usually several options, one is to
separate out the main algorithm, but it's still a lot of
specializations. If the specializations for the types aren't dependent
on each other, you could separate out the code dealing with either
argument in two separate functions. Here you don't want to hold the
GIL, so automatic dispatching or python callables aren't going to
work. So I think in this particular case, you're stuck with function
pointers. You could retrieve them in a slightly different way, but it
doesn't win any prize either, but you can create a wrapper def
function that dispatches on the argument and returns a pointer to a
specialized wrapped function:
cimport numpy as np
import numpy as np
cimport cython
cdef extern from *:
ctypedef int Py_intptr_t
ctypedef fused data_t:
np.int8_t
np.uint8_t
np.int16_t
np.uint16_t
np.int32_t
np.uint32_t
np.int64_t
np.uint64_t
np.float32_t
np.float64_t
ctypedef void (*func_t)(np.int32_t)
cdef void func(data_t arg):
print cython.typeof(arg), arg
def get_func(np.ndarray[data_t] a):
return <Py_intptr_t> func[data_t]
cdef func_t f = <func_t> <void *> <Py_intptr_t> get_func(np.arange(10,
dtype=np.int32))
f(20)