From 95a4e0e2b6d7a6c179f914df17108e4b17e85282 Mon Sep 17 00:00:00 2001 From: "Michael F. Herbst" Date: Thu, 28 Nov 2019 15:21:31 +0100 Subject: [PATCH 1/6] Add support for Float32 and Float16 --- src/CRlibm.jl | 21 +++++++++++---------- test/runtests.jl | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/CRlibm.jl b/src/CRlibm.jl index d0d31f2..003857e 100644 --- a/src/CRlibm.jl +++ b/src/CRlibm.jl @@ -25,13 +25,13 @@ function setup(use_MPFR=false) the same functionality, but with slower execution. This is currently the only option on Windows.") - use_MPFR = true + use_MPFR = true end wrap_MPFR() if use_MPFR - println("CRlibm is shadowing MPFR.") + @info "CRlibm is shadowing MPFR." shadow_MPFR() else wrap_CRlibm() @@ -95,10 +95,11 @@ function wrap_CRlibm() end - @eval $f(x::Float64) = $f(x, RoundNearest) - + # CRlibm only implements Float64 ... this is to get the other IEEE FP types + # working transparently as well (albeit not as efficient as possible) + @eval $f(x::Float16, r::RoundingMode) = Float16((Base.$f)(Float32(x)), r) + @eval $f(x::Float32, r::RoundingMode) = Float32((Base.$f)(Float64(x)), r) end - end @@ -116,16 +117,16 @@ function shadow_MPFR() mode2 = Symbol("Round", string(mode)) - @eval function $f(x::Float64, $mode1) - setprecision(BigFloat, 53) do - Float64(($f)(BigFloat(x), $mode2), $mode2) + for T in (Float16, Float32, Float64) + @eval function $f(x::$T, $mode1) + setprecision(BigFloat, precision($T)) do + $T(($f)(BigFloat(x), $mode2), $mode2) + end end end # use the functions that were previously defined for BigFloat end - @eval $f(x::BigFloat) = $f(x, RoundNearest) - end end diff --git a/test/runtests.jl b/test/runtests.jl index a28304b..eb87aa6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,7 @@ using CRlibm using Test +# Float64 @test CRlibm.cos(0.5, RoundDown) == 0.8775825618903726 @test CRlibm.cos(0.5, RoundUp) == 0.8775825618903728 @test CRlibm.cos(0.5, RoundNearest) == cos(0.5) == 0.8775825618903728 @@ -8,6 +9,22 @@ using Test @test CRlibm.cos(1.6, RoundDown) == -0.029199522301288815 @test CRlibm.cos(0.5) == CRlibm.cos(0.5, RoundNearest) +# Float32 +@test CRlibm.cos(0.5f0, RoundDown) == 0.87758255f0 +@test CRlibm.cos(0.5f0, RoundUp) == 0.8775826f0 +@test CRlibm.cos(0.5f0, RoundNearest) == cos(0.5f0) == 0.87758255f0 +@test CRlibm.cos(1.6f0, RoundToZero) == -0.029199544f0 +@test CRlibm.cos(1.6f0, RoundDown) == -0.029199546f0 +@test CRlibm.cos(0.5f0) == CRlibm.cos(0.5f0, RoundNearest) + +# Float16 +@test CRlibm.cos(Float16(0.5), RoundDown) == Float16(0.8774) +@test CRlibm.cos(Float16(0.5), RoundUp) == Float16(0.878) +@test CRlibm.cos(Float16(0.5), RoundNearest) == cos(Float16(0.5)) == Float16(0.8774) +@test CRlibm.cos(Float16(1.6), RoundToZero) == Float16(-0.02881) +@test CRlibm.cos(Float16(1.6), RoundDown) == Float16(-0.02882) +@test CRlibm.cos(Float16(0.5)) == CRlibm.cos(Float16(0.5), RoundNearest) + function my_eps(prec::Int) ldexp(eps(Float64), 53-prec) end From 72964c228d66ebb12141516cbb780ca636a3fc9e Mon Sep 17 00:00:00 2001 From: "Michael F. Herbst" Date: Thu, 28 Nov 2019 17:24:12 +0100 Subject: [PATCH 2/6] Suggested changes --- src/CRlibm.jl | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/CRlibm.jl b/src/CRlibm.jl index 003857e..c003358 100644 --- a/src/CRlibm.jl +++ b/src/CRlibm.jl @@ -94,11 +94,6 @@ function wrap_CRlibm() @eval $f(x::Float64, $mode) = ccall(($fname, libcrlibm), Float64, (Float64,), x) end - - # CRlibm only implements Float64 ... this is to get the other IEEE FP types - # working transparently as well (albeit not as efficient as possible) - @eval $f(x::Float16, r::RoundingMode) = Float16((Base.$f)(Float32(x)), r) - @eval $f(x::Float32, r::RoundingMode) = Float32((Base.$f)(Float64(x)), r) end end @@ -117,11 +112,9 @@ function shadow_MPFR() mode2 = Symbol("Round", string(mode)) - for T in (Float16, Float32, Float64) - @eval function $f(x::$T, $mode1) - setprecision(BigFloat, precision($T)) do - $T(($f)(BigFloat(x), $mode2), $mode2) - end + @eval function $f(x::Float64, $mode1) + setprecision(BigFloat, 53) do + Float64(($f)(BigFloat(x), $mode2), $mode2) end end # use the functions that were previously defined for BigFloat @@ -137,9 +130,12 @@ function wrap_generic_fallbacks() for f in functions @eval $f(x::Real, r::RoundingMode) = ($f)(float(x), r) @eval $f(x::Real) = $f(x, RoundNearest) - end - + # Specialise for Float32 and Float16 to get the other IEEE FP types + # working transparently as well + @eval $f(x::Float16, r::RoundingMode) = Float16((Base.$f)(Float32(x)), r) + @eval $f(x::Float32, r::RoundingMode) = Float32((Base.$f)(Float64(x)), r) + end end From 35e44e3ed53a9db5e72d9890777d57dc4795851b Mon Sep 17 00:00:00 2001 From: "Michael F. Herbst" Date: Thu, 28 Nov 2019 18:28:24 +0100 Subject: [PATCH 3/6] Allow failures on nightly --- .travis.yml | 4 ++++ appveyor.yml | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index df585f5..d50c41d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,10 @@ julia: - 1.0 - nightly +matrix: + allow_failures: + - julia: nightly + notifications: email: false # uncomment the following lines to override the default test script diff --git a/appveyor.yml b/appveyor.yml index c2588f1..9dcf199 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,11 +8,11 @@ platform: - x86 # 32-bit - x64 # 64-bit -# # Uncomment the following lines to allow failures on nightly julia -# # (tests will run but not make your overall status red) -# matrix: -# allow_failures: -# - julia_version: nightly +# Uncomment the following lines to allow failures on nightly julia +# (tests will run but not make your overall status red) +matrix: + allow_failures: + - julia_version: nightly branches: only: From 9ce32d6c94f4039aa5d4c8f0bcae461d0524ae58 Mon Sep 17 00:00:00 2001 From: "Michael F. Herbst" Date: Thu, 28 Nov 2019 18:29:07 +0100 Subject: [PATCH 4/6] Test on 1.0 and 1.3 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d50c41d..50cc0ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ os: - osx julia: - - 0.7 - 1.0 + - 1.3 - nightly matrix: diff --git a/appveyor.yml b/appveyor.yml index 9dcf199..d225044 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ environment: matrix: - - julia_version: 0.7 - julia_version: 1 + - julia_version: 1.3 - julia_version: nightly platform: From 5922be9a08f1c64e942a85e1d6cd26ec72906059 Mon Sep 17 00:00:00 2001 From: "Michael F. Herbst" Date: Thu, 28 Nov 2019 18:29:47 +0100 Subject: [PATCH 5/6] Convert to Float64 instead of Float32 --- src/CRlibm.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CRlibm.jl b/src/CRlibm.jl index c003358..794ec6f 100644 --- a/src/CRlibm.jl +++ b/src/CRlibm.jl @@ -133,7 +133,7 @@ function wrap_generic_fallbacks() # Specialise for Float32 and Float16 to get the other IEEE FP types # working transparently as well - @eval $f(x::Float16, r::RoundingMode) = Float16((Base.$f)(Float32(x)), r) + @eval $f(x::Float16, r::RoundingMode) = Float16((Base.$f)(Float64(x)), r) @eval $f(x::Float32, r::RoundingMode) = Float32((Base.$f)(Float64(x)), r) end end From 458f71b3cb114e482bbd9d461acce8e7b41afd2d Mon Sep 17 00:00:00 2001 From: "Michael F. Herbst" Date: Sat, 30 Nov 2019 16:43:26 +0100 Subject: [PATCH 6/6] Avoid Base functions completely --- src/CRlibm.jl | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/CRlibm.jl b/src/CRlibm.jl index 794ec6f..f6e969f 100644 --- a/src/CRlibm.jl +++ b/src/CRlibm.jl @@ -92,8 +92,12 @@ function wrap_CRlibm() mode = :(::RoundingMode{$mode}) @eval $f(x::Float64, $mode) = ccall(($fname, libcrlibm), Float64, (Float64,), x) - end + + # Specialise for Float32 and Float16 to get the other IEEE FP types + # working transparently as well + @eval $f(x::Float16, r::RoundingMode) = Float16(($f)(Float64(x), r), r) + @eval $f(x::Float32, r::RoundingMode) = Float32(($f)(Float64(x), r), r) end end @@ -112,9 +116,11 @@ function shadow_MPFR() mode2 = Symbol("Round", string(mode)) - @eval function $f(x::Float64, $mode1) - setprecision(BigFloat, 53) do - Float64(($f)(BigFloat(x), $mode2), $mode2) + for T in (Float16, Float32, Float64) + @eval function $f(x::$T, $mode1) + setprecision(BigFloat, precision($T)) do + $T(($f)(BigFloat(x), $mode2), $mode2) + end end end # use the functions that were previously defined for BigFloat @@ -130,11 +136,6 @@ function wrap_generic_fallbacks() for f in functions @eval $f(x::Real, r::RoundingMode) = ($f)(float(x), r) @eval $f(x::Real) = $f(x, RoundNearest) - - # Specialise for Float32 and Float16 to get the other IEEE FP types - # working transparently as well - @eval $f(x::Float16, r::RoundingMode) = Float16((Base.$f)(Float64(x)), r) - @eval $f(x::Float32, r::RoundingMode) = Float32((Base.$f)(Float64(x)), r) end end