Skip to content

Commit

Permalink
added more references and rules based on gcc's -ffast-math implementa…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
mikeizbicki committed Jun 2, 2014
1 parent c56f2c6 commit 9d8cbc6
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 26 deletions.
6 changes: 4 additions & 2 deletions Numeric/FastMath.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
-- | This module loads all rewrite rules. Unless you know that some rules
-- will be unsafe for your application, this is the module you should load.
-- Importing this module is roughly equivalent to gcc's @-ffast-math@
-- compilation flag.
--
-- The best way to figure out what optimizations these modules do is by
-- looking at the source code. RULES pragmas are surprisingly readable.

module Numeric.FastMath
( module Numeric.FastMath.Approximation
, module Numeric.FastMath.NaN
, module Numeric.FastMath.Infinitesimal
, module Numeric.FastMath.SignedZeros
)
where

import Numeric.FastMath.Approximation ()
import Numeric.FastMath.NaN ()
import Numeric.FastMath.Infinitesimal ()
import Numeric.FastMath.SignedZeros ()
3 changes: 3 additions & 0 deletions Numeric/FastMath/Approximation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
--
-- All of these RULES should be safe in the presence of `NaN` and `Infinity`
--
-- Importing this module is similar to compiling with gcc's
-- @-funsafe-math-operations@.
--
module Numeric.FastMath.Approximation
where

Expand Down
12 changes: 0 additions & 12 deletions Numeric/FastMath/Infinitesimal.hs

This file was deleted.

23 changes: 20 additions & 3 deletions Numeric/FastMath/NaN.hs
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
-- | This module contains rules that break the way NaN is handled for "Float"
-- and "Double" types. Still, these rules should be safe in the vast majority of
-- applications.
--
-- Importing this module is similar to compiling with gcc's @-fno-signaling-nans@
-- and @-ffinite-math-only@.
--
module Numeric.FastMath.NaN
where

import GHC.Exts

{-# RULES
"minusDouble x x" forall x. (-##) x x = 0.0##

"timesDouble 0 x" forall x. (*##) 0.0## x = 0.0##
"timesDouble x 0" forall x. (*##) x 0.0## = 0.0##

"divideDouble x 1" forall x. (/##) x 1.0## = x
"divideDouble x -1" forall x. (/##) x (-1.0##) = negateDouble# x
"divideDouble 0 x" forall x. (/##) 0.0## x = 0.0##
#-}

{-# RULES
"minusFloat x x" forall x. minusFloat# x x = 0.0#

"timesFloat x 0" forall x. timesFloat# x 0.0# = 0.0#
"timesFloat 0 x" forall x. timesFloat# 0.0# x = 0.0#

"minusDouble x x" forall x. (-##) x x = 0.0##
"timesDouble 0 x" forall x. (*##) 0.0## x = 0.0##
"timesDouble x 0" forall x. (*##) x 0.0## = 0.0##
"divideFloat x 1" forall x. divideFloat# x 1.0# = x
"divideFloat x -1" forall x. divideFloat# x (-1.0#) = negateFloat# x
"divideFloat 0 x" forall x. divideFloat# 0.0# x = 0.0#

#-}

24 changes: 24 additions & 0 deletions Numeric/FastMath/SignedZeros.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- | IEEE 754 math makes a distrinction between -0.0 and +0.0. This module
-- contains RULES that ignore this distinction.
--
-- Importing this module is similar to compiling with gcc's
-- @-fno-signed-zeros@.

module Numeric.FastMath.SignedZeros () where

import GHC.Exts

{-# RULES

"minusDouble 0 x" forall x. (-##) 0.0## x = negateDouble# x
"divideDouble 0 x" forall x. (/##) 0.0## x = 0.0##
#-}

{-# RULES

"minusFloat 0 x" forall x. minusFloat# 0.0# x = negateFloat# x
"divideFloat 0 x" forall x. divideFloat# 0.0# x = 0.0#

#-}


2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This package enables a number of "unsafe" floating point optimizations for GHC.
x*y + x*z == z*(y+z)
```

does not hold for `Float` or `Double` types. The lowest order bits may be different due to rounding errors.Therefore, GHC (and most compilers for any language) will not perform this optimization by default. Instead, most compilers support special flags that enable these unsafe optimizations. See for example the [-ffast-math flag in the gcc documentation](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html). GHC, however, has [no built in flags for these optimizations](http://www.haskell.org/ghc/docs/7.8.2/html/users_guide/flag-reference.html). But that's okay. GHC's `RULES` pragmas are sufficiently powerful to achieve most of the performance benefits of `-ffast-math`. This package provides those `RULES` pragmas.
does not hold for `Float` or `Double` types. The lowest order bits may be different due to rounding errors.Therefore, GHC (and most compilers for any language) will not perform this optimization by default. Instead, most compilers support special flags that enable these unsafe optimizations. See for example the [-ffast-math flag in the gcc documentation](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) and the [gcc wiki page FloatingPointMath](https://gcc.gnu.org/wiki/FloatingPointMath). GHC, however, has [no built in flags for these optimizations](http://www.haskell.org/ghc/docs/7.8.2/html/users_guide/flag-reference.html). But that's okay. GHC's `RULES` pragmas are sufficiently powerful to achieve most of the performance benefits of `-ffast-math`. This package provides those `RULES` pragmas.

### Enabling the optimizations

Expand Down
16 changes: 8 additions & 8 deletions fast-math.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ name: fast-math
version: 1.0
synopsis: Non IEEE-754 compliant compile-time floating-point optimisations
description:
The "Numeric.FastMath" module brings into scope RULES for 'Float's and
'Double's that rewrite @x-x@, @0*x@ and @x*0@ to @0@. This disagrees
with IEEE-754 when @x@ is @NaN@, but is acceptable for most
applications.
The "Numeric.FastMath" module brings into scope many unsafe @RULES@ for
'Float's and 'Double's that can greatly improve run time performance.
It is roughly equivalent to gcc\'s @-ffast-math@ compiler flag.
Optimisation (at least @-O1@) must be enabled for any @RULES@ to take effect.
.
Importing "Numeric.FastMath.Infinitesimal" also rewrites @0/x@ to @0@.
.
Optimisation (at least @-O1@) must be enabled for any RULES to take effect.
These rules are unsafe because they don't strictly adhere to the
IEEE-754 regulations and may subtly change the results of your numeric computations.
See the <http://github.com/liyang/fast-math/ README> on github for more details.

license: BSD3
license-file: LICENSE
Expand All @@ -31,8 +31,8 @@ library
exposed-modules:
Numeric.FastMath
Numeric.FastMath.Approximation
Numeric.FastMath.Infinitesimal
Numeric.FastMath.NaN
Numeric.FastMath.SignedZeros
default-extensions:
NoImplicitPrelude
MagicHash
Expand Down

0 comments on commit 9d8cbc6

Please sign in to comment.