This script:
import numpy as np, numba as nb
@nb.njit(fastmath=True)
def f():
return np.nan
#@nb.njit(fastmath=True)
def g():
print(f(), np.isnan(f()))
g()
produces different results:
nan False
when uncommented, and:
nan True
when commented. Is there a simple explanation of this?
milton
April 19, 2025, 1:38pm
2
Interesting, for
fm = True
@nb.njit(fastmath=fm)
def g(x):
return np.isnan(x)
I got LLVM instructions containing unordered comparison (detecting NaN)
%.12 = fcmp uno double %arg.x, 0.000000e+00
%.26 = zext i1 %.12 to i8
store i8 %.26, i8* %retptr, align 1
while for fm=True I got ‘optimized’ one:
store i8 0, i8* %retptr, align 1
1 Like
Oyibo
April 19, 2025, 10:38pm
3
@pauljurczak Have you tried without “fastmath”?
“fastmath” allows optimizations to assume the arguments and result are not NaN.
import numpy as np, numba as nb
@nb.njit(fastmath=False)
def f():
return np.nan
@nb.njit(fastmath=False)
def g():
print(f(), np.isnan(f()))
g()
# nan True
https://llvm.org/docs/LangRef.html#fast-math-flags
1 Like
Good catch, thank you. It indeed works with @nb.njit(fastmath=False) for function g(), which uses fcmp instruction. It is irrelevant for function f(), i.e.:
@nb.njit(fastmath=True)
def f():
return np.nan
@nb.njit(fastmath=False)
def g():
print(f(), np.isnan(f()))
works fine.
1 Like