Skip to content

Commit 9d8cbc6

Browse files
committed
added more references and rules based on gcc's -ffast-math implementation
1 parent c56f2c6 commit 9d8cbc6

File tree

7 files changed

+60
-26
lines changed

7 files changed

+60
-26
lines changed

Numeric/FastMath.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
-- | This module loads all rewrite rules. Unless you know that some rules
22
-- will be unsafe for your application, this is the module you should load.
3+
-- Importing this module is roughly equivalent to gcc's @-ffast-math@
4+
-- compilation flag.
35
--
46
-- The best way to figure out what optimizations these modules do is by
57
-- looking at the source code. RULES pragmas are surprisingly readable.
68

79
module Numeric.FastMath
810
( module Numeric.FastMath.Approximation
911
, module Numeric.FastMath.NaN
10-
, module Numeric.FastMath.Infinitesimal
12+
, module Numeric.FastMath.SignedZeros
1113
)
1214
where
1315

1416
import Numeric.FastMath.Approximation ()
1517
import Numeric.FastMath.NaN ()
16-
import Numeric.FastMath.Infinitesimal ()
18+
import Numeric.FastMath.SignedZeros ()

Numeric/FastMath/Approximation.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
--
1010
-- All of these RULES should be safe in the presence of `NaN` and `Infinity`
1111
--
12+
-- Importing this module is similar to compiling with gcc's
13+
-- @-funsafe-math-operations@.
14+
--
1215
module Numeric.FastMath.Approximation
1316
where
1417

Numeric/FastMath/Infinitesimal.hs

Lines changed: 0 additions & 12 deletions
This file was deleted.

Numeric/FastMath/NaN.hs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,35 @@
11
-- | This module contains rules that break the way NaN is handled for "Float"
22
-- and "Double" types. Still, these rules should be safe in the vast majority of
33
-- applications.
4+
--
5+
-- Importing this module is similar to compiling with gcc's @-fno-signaling-nans@
6+
-- and @-ffinite-math-only@.
7+
--
48
module Numeric.FastMath.NaN
59
where
610

711
import GHC.Exts
812

13+
{-# RULES
14+
"minusDouble x x" forall x. (-##) x x = 0.0##
15+
16+
"timesDouble 0 x" forall x. (*##) 0.0## x = 0.0##
17+
"timesDouble x 0" forall x. (*##) x 0.0## = 0.0##
18+
19+
"divideDouble x 1" forall x. (/##) x 1.0## = x
20+
"divideDouble x -1" forall x. (/##) x (-1.0##) = negateDouble# x
21+
"divideDouble 0 x" forall x. (/##) 0.0## x = 0.0##
22+
#-}
23+
924
{-# RULES
1025
"minusFloat x x" forall x. minusFloat# x x = 0.0#
26+
1127
"timesFloat x 0" forall x. timesFloat# x 0.0# = 0.0#
1228
"timesFloat 0 x" forall x. timesFloat# 0.0# x = 0.0#
1329

14-
"minusDouble x x" forall x. (-##) x x = 0.0##
15-
"timesDouble 0 x" forall x. (*##) 0.0## x = 0.0##
16-
"timesDouble x 0" forall x. (*##) x 0.0## = 0.0##
30+
"divideFloat x 1" forall x. divideFloat# x 1.0# = x
31+
"divideFloat x -1" forall x. divideFloat# x (-1.0#) = negateFloat# x
32+
"divideFloat 0 x" forall x. divideFloat# 0.0# x = 0.0#
33+
1734
#-}
1835

Numeric/FastMath/SignedZeros.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- | IEEE 754 math makes a distrinction between -0.0 and +0.0. This module
2+
-- contains RULES that ignore this distinction.
3+
--
4+
-- Importing this module is similar to compiling with gcc's
5+
-- @-fno-signed-zeros@.
6+
7+
module Numeric.FastMath.SignedZeros () where
8+
9+
import GHC.Exts
10+
11+
{-# RULES
12+
13+
"minusDouble 0 x" forall x. (-##) 0.0## x = negateDouble# x
14+
"divideDouble 0 x" forall x. (/##) 0.0## x = 0.0##
15+
#-}
16+
17+
{-# RULES
18+
19+
"minusFloat 0 x" forall x. minusFloat# 0.0# x = negateFloat# x
20+
"divideFloat 0 x" forall x. divideFloat# 0.0# x = 0.0#
21+
22+
#-}
23+
24+

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This package enables a number of "unsafe" floating point optimizations for GHC.
66
x*y + x*z == z*(y+z)
77
```
88

9-
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.
9+
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.
1010

1111
### Enabling the optimizations
1212

fast-math.cabal

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

1414
license: BSD3
1515
license-file: LICENSE
@@ -31,8 +31,8 @@ library
3131
exposed-modules:
3232
Numeric.FastMath
3333
Numeric.FastMath.Approximation
34-
Numeric.FastMath.Infinitesimal
3534
Numeric.FastMath.NaN
35+
Numeric.FastMath.SignedZeros
3636
default-extensions:
3737
NoImplicitPrelude
3838
MagicHash

0 commit comments

Comments
 (0)