How to register an existing builtin function

Let’s say I have a function with the following signature:

float fractal(vector position, float H , float lacunarity , int octaves, string type)

and I want to register this buitin function in order to use it from njit functions
How do I do that?

Hi @rpopovici

I’m not quite sure what you are asking. If you have a function fractal that is already jit compatible then just @numba.njit decorate it? If you are referring to fractal as a prototype from an external API and you wish to replicate the functionality with @jit, then I suggest using @numba.extending.overload docs are here and a user guide is here.

Hope this helps?

@stuartarchibald The function is already implemented in C and exported as a builtin for python. Basicaly, I am trying to call this builtin from an njit but I get:

Untyped global name 'hybrid_multi_fractal': Cannot determine Numba type of <class 'builtin_function_or_method'>

If it’s an exported C symbol then perhaps user Numba’s ctypes support. Example of binding to libm's cos function.

In [1]: import ctypes

In [2]: from numba import njit

In [3]: libm = ctypes.CDLL('')

In [4]: libm.cos.restype = ctypes.c_double # define return type

In [5]: libm.cos.argtypes = (ctypes.c_double,) # define arg type(s)

In [6]: cos_binding = libm.cos # bind directly to the function so that numba can resolve it

In [7]: @njit
   ...: def foo(x):
   ...:     return cos_binding(x)

In [8]: cos_binding(3.14159) # Call ctypes binding directly
Out[8]: -0.9999999999964793

In [9]: foo(3.14159) # Call ctypes binding from jit code
Out[9]: -0.9999999999964793

If cython is used for creating or exporting the function then this might help too:

@stuartarchibald that’s the thing. This function is statically linked to the main executable. There is no dll to load with ctypes. I don’t know if it’s possible to convert the imported python wrapper to a ctypes function call…

Without a library symbol to bind to there’s not a lot of options available for use by python (as a raw function call) or anything else? I suspect it will not be possible to convert the wrapper to a ctypes call, the wrapper will expect PyObject instances and return the same so it’s not suitable. Options available are to either try and find a way to get hold of that symbol, translate the compiled code into Python and JIT it, or use an objmode block and accept the performance penalty for doing so.