Skip to content

Implement isfinite, isinf, isnan ufuncs #121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

juntyr
Copy link
Contributor

@juntyr juntyr commented Jul 21, 2025

Fixes #111

@juntyr
Copy link
Contributor Author

juntyr commented Jul 21, 2025

I get some weird runtime warnings in the isfinite and isinf ufuncs:

tests/test_quaddtype.py: 10 warnings
  /workspaces/numpy-user-dtypes/quaddtype/tests/test_quaddtype.py:113: RuntimeWarning: invalid value encountered in isfinite
    quad_result = op_func(quad_val)

tests/test_quaddtype.py: 10 warnings
  /workspaces/numpy-user-dtypes/quaddtype/tests/test_quaddtype.py:113: RuntimeWarning: invalid value encountered in isinf
    quad_result = op_func(quad_val)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

Any idea what I'm doing wrong?

@juntyr juntyr mentioned this pull request Jul 21, 2025
11 tasks
@seberg
Copy link
Member

seberg commented Jul 21, 2025

IEEE says comparisons with NaNs trigger FPEs (floating point error; FPEs are a flag set on the CPU when one occurs basically). That means normally also nan == inf.
C99 has special comparison functions for this purpose (not that all compilers used to get it right). Maybe sleef gets these warnings right, maybe not. But the best solution would be to avoid the function triggering it. Maybe sleef has a quiet comparison or just a way to test for this without a comparison.

@juntyr
Copy link
Contributor Author

juntyr commented Jul 22, 2025

IEEE says comparisons with NaNs trigger FPEs (floating point error; FPEs are a flag set on the CPU when one occurs basically). That means normally also nan == inf. C99 has special comparison functions for this purpose (not that all compilers used to get it right). Maybe sleef gets these warnings right, maybe not. But the best solution would be to avoid the function triggering it. Maybe sleef has a quiet comparison or just a way to test for this without a comparison.

This definitely got me on the right track but wasn't the issue in the end. In fact, Sleef_cast_from_doubleq1(std::numeric_limits<double>::infinity()) raised the flag (no idea why), so I switched to using constants defined with sleef_q (the recommended way).

@seberg
Copy link
Member

seberg commented Jul 22, 2025

Seems plausible that the sleef casts uses the wrong type of comparisons internally and nobody noticed/cares (or the compilers mess it up later).

@juntyr one thing I forgot is, that we should definitely add -ftrapping-math (compare NumPy meson.build for Clang builds. The default is just terrible for NumPy here since it honors FPEs (NumPy does, clang doesn't). If you were using Clang, it may well be that just setting this flag fixes the issue. (We should set it either way.)

@juntyr juntyr marked this pull request as draft July 23, 2025 15:09
@juntyr juntyr force-pushed the is-nan-inf-finite branch from d5a15f1 to 6e6a88b Compare July 26, 2025 09:12
@juntyr juntyr marked this pull request as ready for review July 26, 2025 09:13
@juntyr
Copy link
Contributor Author

juntyr commented Jul 26, 2025

@SwayamInSync I've rebased this PR and it should now also be good to go

Copy link
Collaborator

@SwayamInSync SwayamInSync left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @juntyr this looks good, just a small suggestion here.

@@ -1,6 +1,12 @@
#include <sleef.h>
#include <sleefquad.h>
#include <cmath>
#include <limits>

// Quad Constants, generated with qutil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems QUAD_ZERO and QUAD_ONE aren't used so you can remove them, also
sleef_q internally handles the biased exponent addition which managed to convert this to IEEE validated infinity representation but I am kind of biased here to keep this hardcoded as it can be easily defined as Sleef_cast_from_doubleq1(1.0 / 0.0) (Dividing a non-zero finite number by zero)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, my rebase was messed up then as I originally used the constants

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally tried the above but converting from infinity double caused numpy warning to appear, which I was only able to remove with the constants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SleefQuadPrecision arrays are missing isnan, isinf, isfinite, sign, copysign ufuncs
3 participants