isfinite(inf) raises FloatingPointError in vectorized functions
The following works as expected:
@nb.njit
def finite(x):
return math.isfinite(x)
>>> finite(1.)
True
>>> finite(math.nan)
False
>>> finite(math.inf)
False
However, this vectorized version raises an exception when it receives inf:
@nb.vectorize
def finite(x):
return math.isfinite(x)
>>> finite(1.)
True
>>> finite(math.nan)
False
>>> finite(math.inf)
FloatingPointError: invalid value encountered in finite
It is interesting to notice that the behavior changes depending on np.seterr() settings:
>>> np.seterr(all='raise')
>>> finite(math.inf)
FloatingPointError: invalid value encountered in finite [...]
>>> np.seterr(all='warn')
>>> finite(math.inf)
RuntimeWarning: invalid value encountered in finite [...]
False
>>> np.seterr(all='ignore')
>>> finite(math.inf)
False
The same happens in guvectorized functions.
I understand isfinite(inf) should never raise an exception or warning, according to the behavior of math.isfinite() or np.isfinite(), or its own behavior in the non-vectorized version.
Using Numba 0.60.0 and Python 3.10.12.
For example, when converting floating point values to integers, an alternative to checking isfinite() would be to catch the exception raised by int(nan) or int(inf), but int(inf) does not raise OverflowError (#6044).
Thanks for the report. I can reproduce similar behaviour with:
from numba import njit, vectorize
import math
import numpy as np
np.seterr(all='raise')
@njit
def finite(x):
return math.isfinite(x)
finite(1.0)
finite(math.nan)
finite(math.inf)
@vectorize
def vectorize_finite(x):
return math.isfinite(x)
vectorize_finite(1.0)
vectorize_finite(math.nan)
vectorize_finite(math.inf)
The implementation if is_finite (in numba/cpython/mathimpl.py) might be setting an error flag:
56 def is_finite(builder, val):
57 """
58 Return a condition testing whether *val* is a finite.
59 """
60 # is_finite(x) <=> x - x != NaN
61 val_minus_val = builder.fsub(val, val)
62 return builder.fcmp_ordered('ord', val_minus_val, val_minus_val)
Newer llvm has https://llvm.org/docs/LangRef.html#llvm-is-fpclass-intrinsic
Also in LLVM 15: https://releases.llvm.org/15.0.0/docs/LangRef.html#llvm-is-fpclass-intrinsic