Next topic

This Page

Quick search

Numba provides several utilities for code generation, but its central
feature is the numba.jit() decorator. Using this decorator, you can mark
a function for optimization by Numba’s JIT compiler. Various invocation
modes trigger differing compilation options and behaviours.

The recommended way to use the @jit decorator is to let Numba decide
when and how to optimize:

fromnumbaimportjit@jitdeff(x,y):# A somewhat trivial examplereturnx+y

In this mode, compilation will be deferred until the first function
execution. Numba will infer the argument types at call time, and generate
optimized code based on this information. Numba will also be able to
compile separate specializations depending on the input types. For example,
calling the f() function above with integer or complex numbers will
generate different code paths:

int32(int32,int32) is the function’s signature. In this case, the
corresponding specialization will be compiled by the @jit decorator,
and no other specialization will be allowed. This is useful if you want
fine-grained control over types chosen by the compiler (for example,
to use single-precision floats).

If you omit the return type, e.g. by writing (int32,int32) instead of
int32(int32,int32), Numba will try to infer it for you. Function
signatures can also be strings, and you can pass several of them as a list;
see the numba.jit() documentation for more details.

Of course, the compiled function gives the expected results:

>>> f(1,2)3

and if we specified int32 as return type, the higher-order bits get
discarded:

Numba has two compilation modes: nopython mode and
object mode. The former produces much faster code, but has
limitations that can force Numba to fall back to the latter. To prevent
Numba from falling back, and instead raise an error, pass nopython=True.

Whenever Numba optimizes Python code to native code that only works on
native types and variables (rather than Python objects), it is not necessary
anymore to hold Python’s global interpreter lock (GIL).
Numba will release the GIL when entering such a compiled function if you
passed nogil=True.

@jit(nogil=True)deff(x,y):returnx+y

Code running with the GIL released runs concurrently with other
threads executing Python or Numba code (either the same compiled function,
or another one), allowing you to take advantage of multi-core systems.
This will not be possible if the function is compiled in object mode.

When using nogil=True, you’ll have to be wary of the usual pitfalls
of multi-threaded programming (consistency, synchronization, race conditions,
etc.).