shibatch / sleef

SIMD Library for Evaluating Elementary Functions, vectorized libm and DFT
https://sleef.org
Boost Software License 1.0
661 stars 133 forks source link

Using cinz functions that result in NaN has non-deterministic outputs #429

Closed sheredom closed 3 years ago

sheredom commented 3 years ago

I'm working on a feature in Burst where we have cross-platform consistent constant folding, using the deterministic functions provided by SLEEF.

I noticed that if we did Sleef_cinz_logf1_u10purec(13.0f) it'd produce different results on Windows vs macOS/Linux, because SLEEF_NAN and SLEEF_NANf are defined differently on each platform, and result in a different NaN bit pattern.

To fix this I've locally did:

#define SLEEF_NAN (((union { long long int i; double d; }) { .i = INT64_C(0x7ff8000000000000) }).d)
#define SLEEF_NANf (((union { long int i; float f; }) { .i = 0x7fc00000 }).f)

Is this something you would accept as an upstream fix? The only other issue is that SLEEF_NANl and SLEEF_NANq are still defined the old way, but we don't use either of them for our deterministic code so it doesn't matter for Burst.

sheredom commented 3 years ago

Also - follow-on find! If I use the cinz sin/cos/tan/sincos, they all produce different NaN results (all NaN though!). Is this to be expected? Wondering if the deterministic methods aren't deterministic in which NaN they produce maybe?

shibatch commented 3 years ago

Hello, The difference in the payload of NaN values is expected. Producing the exactly same NaN values takes overhead.

sheredom commented 3 years ago

Ok - thank you shibatch-san! I'll close this issue and we'll handle this ourselves 😄