These flags unlock SIMD vectorization and remove checks, but each changes semantics in specific ways.
The JIT decorators accept options that change what the compiler may assume.
fastmath=Truelets LLVM ignore strict IEEE 754 rules: it may reorder additions (enabling SIMD vectorization of reductions), assume no NaNs or infinities, and use approximate reciprocals. Loops summing floats often get several times faster. The price: results can differ in the last bits, and code that relies on NaN checks (x != x,np.isnan) may be optimised away. You can pass a set of flags such as{"nsz", "arcp", "contract", "afn", "reassoc"}to enable only some relaxations, leaving NaN and infinity handling intact.boundscheck=Trueturns on index bounds checking. By default Numba does not check bounds, soa[10]on a 5-element array reads or writes arbitrary memory. Enable checks while debugging, or globally withNUMBA_BOUNDSCHECK=1.error_model="numpy"makes division by zero returninfornanlike NumPy instead of raisingZeroDivisionErroras Python does. Removing the check makes division-heavy loops faster.inline="always"inlines a small@njitfunction into callers at the Numba IR level; LLVM usually inlines small functions anyway.nogil=Trueandcache=Trueare covered elsewhere.
Treat these as measured optimisations: benchmark with and without, and test numerical results against the strict version.
Example
import numpy as np
from numba import njit
@njit(fastmath=True)
def fast_sum(a):
s = 0.0
for x in a:
s += x # may be reordered and vectorized
return s
@njit(error_model="numpy")
def safe_ratio(a, b):
return a / b
@njit(boundscheck=True)
def get(a, i):
return a[i]
a = np.random.default_rng(0).random(10_000_000)
print(np.isclose(fast_sum(a), a.sum())) # True (last bits may differ)
print(safe_ratio(1.0, 0.0)) # inf (Python error model would raise)
try:
get(np.zeros(5), 10)
except IndexError as e:
print("IndexError:", e) # IndexError: index is out of boundsRemember
- fastmath allows reordering and SIMD; results may change slightly and NaN checks may vanish
- Bounds are not checked by default; enable boundscheck while debugging
- error_model='numpy' returns inf/nan for division by zero
Watch out for
- Using fastmath=True in code that tests for NaN, which may then never detect it.