Differ from earlier post, I work with all cdef function here. If I work with function pointer of fused_type input, it will raise "Invalid use of fused types, type cannot be specialized". On the contrary, the function pointer with built-in type works well. Why?
cimport cython
# raise error
ctypedef fused fused_type:
float
int
ctypedef fused_type (* _func_pointer) (fused_type[:])
cdef fused_type base_func(fused_type[:] arg1):
return arg1[0]
cdef fused_type c_entry(fused_type[:] arg1, _func_pointer func):
return func(arg1)
cdef fused_type base_wrapper(fused_type[:] arg1):
return c_entry(arg1, base_func)
""" ------- """
# works
cdef int base_func(int[:] arg1):
return arg1[0]
cdef int c_entry(int[:] arg1, _func_pointer func):
return func(arg1)
cdef int base_wrapper(int[:] arg1):
return c_entry(arg1, base_func)
You need to change it to
When
base_wrapper
is specialized, that selects the specialization ofbase_func
for whateverfused_type
currently is inbase_wrapper
.The rough explanation of why:
This doesn't define a function pointer type that takes and returns
fused_type
. Instead it defines a fused type with containing two types:When you do
base_func
on its own it isn't a "real" function - you get one of the specializations either by calling it, or my manually selecting it (e.g.base_func[int]
).Therefore in
base_wrapper
the linereturn c_entry(arg1, base_func)
doesn't know which specialization ofbase_func
it should be using, and therefore can't pick which of the two types of_func_pointer
it should match.The Cython fused type system is fairly dump and doesn't make too much of an effort to resolve confusion - it's either an unambiguous exact match or no match at all.