Skip to content
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

Fix rem2pi for NaN #36420

Merged
merged 1 commit into from
Jul 24, 2022
Merged

Fix rem2pi for NaN #36420

merged 1 commit into from
Jul 24, 2022

Conversation

mgautam98
Copy link
Contributor

Fix for #32888

This will also fix the mod2pi.

There was a discussion that Domain Error should be thrown or NaN should be returned. To be consistent with rem I returned NaN

@mgautam98
Copy link
Contributor Author

@simeonschaub can you please review it?

Comment on lines +978 to 1244
isnan(x) && return NaN

abs(x) < pi && return x
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this can be optimized:

Suggested change
isnan(x) && return NaN
abs(x) < pi && return x
abs(x) >= pi || return x

Copy link
Contributor Author

@mgautam98 mgautam98 Jun 25, 2020

Choose a reason for hiding this comment

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

@kimikage Yes. but won't it make it hard to understand and debug later?

Copy link
Contributor

Choose a reason for hiding this comment

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

That's right. However, for such low-level functions, I prefer the speed. Is it not enough to just add comments into the source?

Copy link
Member

Choose a reason for hiding this comment

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

Worth checking if LLVM figures that out and eliminates the isnan check.

Copy link
Member

Choose a reason for hiding this comment

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

It seems like LLVM with optimize=true can't eliminate the fcmp ord double %0, 0.000000e+00 instruction and extra branch from isnan here. So I think it makes sense to use >= here to replace the isnan check and just add an explanatory comment about the NaN case.

@ViralBShah ViralBShah added the maths Mathematical functions label Feb 25, 2022
@fredrikekre fredrikekre added backport 1.6 Change should be backported to release-1.6 backport 1.7 backport 1.8 Change should be backported to release-1.8 labels Jul 24, 2022
@fredrikekre fredrikekre merged commit 665b03e into JuliaLang:master Jul 24, 2022
@oscardssmith
Copy link
Member

what's the performance impact of this pr?

@giordano
Copy link
Contributor

About 5% according to

julia> using BenchmarkTools

julia> @benchmark x .= mod2pi.(x) setup=(x=randn(10_000))
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  64.060 μs … 177.371 μs  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     66.712 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   68.426 μs ±   6.567 μs  ┊ GC (mean ± σ):  0.00% ± 0.00%

   ▅█▇▅▇▇▄▄▄▂        ▁▁▁▁▂▁                 ▁                  ▂
  ▇██████████▆▅▅▁▅▆▇█████████▇▄▅▄▄▄▅▃▅▅██▇███▇▄▄▃▃▁▄▃▄▄▄▅▅▇▇██ █
  64.1 μs       Histogram: log(frequency) by time        99 μs <

 Memory estimate: 0 bytes, allocs estimate: 0.

julia> @eval Base.Math function rem2pi(x::Float64, ::RoundingMode{:Down})
           isnan(x) && return NaN

           if x < pi4o2_h
               if x >= 0
                   return x
               elseif x > -pi4o2_h
                   return add22condh(x,0.0,pi4o2_h,pi4o2_l)
               end
           end

           n,y = rem_pio2_kernel(x)

           if iseven(n)
               if n & 2 == 2 # n % 4 == 2: add pi
                   return add22condh(y.hi,y.lo,pi2o2_h,pi2o2_l)
               else          # n % 4 == 0: add 0 or 2pi
                   if y.hi > 0
                       return y.hi+y.lo
                   else      # negative: add 2pi
                       return add22condh(y.hi,y.lo,pi4o2_h,pi4o2_l)
                   end
               end
           else
               if n & 2 == 2 # n % 4 == 3: add 3pi/2
                   return add22condh(y.hi,y.lo,pi3o2_h,pi3o2_l)
               else          # n % 4 == 1: add pi/2
                   return add22condh(y.hi,y.lo,pi1o2_h,pi1o2_l)
               end
           end
       end
rem2pi (generic function with 9 methods)

julia> @benchmark x .= mod2pi.(x) setup=(x=randn(10_000))
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  67.314 μs … 171.758 μs  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     69.521 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   72.705 μs ±   8.752 μs  ┊ GC (mean ± σ):  0.00% ± 0.00%

  ▂██▅▇▅▄▅▂    ▁ ▂▁▁▁▁                                         ▂
  ██████████▇▇████████▇▇▇▇█▇▇▇████▇▆▆▅▇▅▆▆▆▆▇▇▇▆▅▆▅▆▆▆▆▄▅▄▅▄▅▇ █
  67.3 μs       Histogram: log(frequency) by time       113 μs <

 Memory estimate: 0 bytes, allocs estimate: 0.

Unless you have smarter ways to deal with non-finite values, this seems a decent trade-off.

@JeffreySarnoff just reported on Slack that also Inf is wrong

julia> mod2pi.((-Inf, Inf, NaN))
(1.1963318081441687, 5.086853499035418, 1.3470949413735402)

@oscardssmith oscardssmith removed backport 1.6 Change should be backported to release-1.6 backport 1.7 backport 1.8 Change should be backported to release-1.8 labels Jul 25, 2022
@oscardssmith
Copy link
Member

removing back-port labels since #46163 is a more complete fix.

@fredrikekre
Copy link
Member

Pretty sure you need both to make the other patch apply cleanly (and avoid manual work).

@oscardssmith oscardssmith added backport 1.6 Change should be backported to release-1.6 backport 1.7 backport 1.8 Change should be backported to release-1.8 labels Jul 25, 2022
KristofferC pushed a commit that referenced this pull request Aug 7, 2022
@KristofferC KristofferC removed the backport 1.8 Change should be backported to release-1.8 label Aug 7, 2022
ffucci pushed a commit to ffucci/julia that referenced this pull request Aug 11, 2022
pcjentsch pushed a commit to pcjentsch/julia that referenced this pull request Aug 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 1.6 Change should be backported to release-1.6 maths Mathematical functions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants