22
33# fast math
44
5- # check expansions
6-
7- @test macroexpand (Main, :(@fastmath 1 + 2 )) == :(Base. FastMath. add_fast (1 ,2 ))
8- @test macroexpand (Main, :(@fastmath + )) == :(Base. FastMath. add_fast)
9- @test macroexpand (Main, :(@fastmath min (1 ))) == :(Base. FastMath. min_fast (1 ))
10- @test macroexpand (Main, :(@fastmath min)) == :(Base. FastMath. min_fast)
11- @test macroexpand (Main, :(@fastmath x. min)) == :(x. min)
12- @test macroexpand (Main, :(@fastmath sincos (x))) == :(Base. FastMath. sincos_fast (x))
13-
14- # basic arithmetic
15-
5+ @testset " check expansions" begin
6+ @test macroexpand (Main, :(@fastmath 1 + 2 )) == :(Base. FastMath. add_fast (1 ,2 ))
7+ @test macroexpand (Main, :(@fastmath + )) == :(Base. FastMath. add_fast)
8+ @test macroexpand (Main, :(@fastmath min (1 ))) == :(Base. FastMath. min_fast (1 ))
9+ @test macroexpand (Main, :(@fastmath min)) == :(Base. FastMath. min_fast)
10+ @test macroexpand (Main, :(@fastmath x. min)) == :(x. min)
11+ @test macroexpand (Main, :(@fastmath sincos (x))) == :(Base. FastMath. sincos_fast (x))
12+ end
1613const one32 = one (Float32)
1714const eps32 = eps (Float32)
1815const eps32_2 = eps32/ 2
1916# Note: Cannot use local functions since these are not yet optimized
2017fm_ieee_32 (x) = x + eps32_2 + eps32_2
2118fm_fast_32 (x) = @fastmath x + eps32_2 + eps32_2
22- @test fm_ieee_32 (one32) == one32
23- @test (fm_fast_32 (one32) == one32 ||
24- fm_fast_32 (one32) == one32 + eps32 > one32)
25-
2619const one64 = one (Float64)
2720const eps64 = eps (Float64)
2821const eps64_2 = eps64/ 2
2922# Note: Cannot use local functions since these are not yet optimized
3023fm_ieee_64 (x) = x + eps64_2 + eps64_2
3124fm_fast_64 (x) = @fastmath x + eps64_2 + eps64_2
32- @test fm_ieee_64 (one64) == one64
33- @test (fm_fast_64 (one64) == one64 ||
34- fm_fast_64 (one64) == one64 + eps64 > one64)
35- # check updating operators
3625fm_ieee_64_upd (x) = (r= x; r+= eps64_2; r+= eps64_2)
3726fm_fast_64_upd (x) = @fastmath (r= x; r+= eps64_2; r+= eps64_2)
38- @test fm_ieee_64_upd (one64) == one64
39- @test (fm_fast_64_upd (one64) == one64 ||
40- fm_fast_64_upd (one64) == one64 + eps64 > one64)
41-
42- let epsf = 1.0f0 / 2 ^ 15 , one_epsf = 1 + epsf
43- @test @fastmath (one_epsf * one_epsf - 1 ) ≈ Float32 (65537 / 1073741824 )
44- end
45- let eps = 1.0 / 2 ^ 30 , one_eps = 1 + eps
46- @test @fastmath (one_eps * one_eps - 1 ) ≈ 2147483649 / 1152921504606846976
47- end
27+ @testset " basic arithmetic" begin
28+ @test fm_ieee_32 (one32) == one32
29+ @test (fm_fast_32 (one32) == one32 ||
30+ fm_fast_32 (one32) == one32 + eps32 > one32)
31+ @test fm_ieee_64 (one64) == one64
32+ @test (fm_fast_64 (one64) == one64 ||
33+ fm_fast_64 (one64) == one64 + eps64 > one64)
34+ # check updating operators
35+ @test fm_ieee_64_upd (one64) == one64
36+ @test (fm_fast_64_upd (one64) == one64 ||
37+ fm_fast_64_upd (one64) == one64 + eps64 > one64)
38+
39+ let epsf = 1.0f0 / 2 ^ 15 , one_epsf = 1 + epsf
40+ @test @fastmath (one_epsf * one_epsf - 1 ) ≈ Float32 (65537 / 1073741824 )
41+ end
42+ let eps = 1.0 / 2 ^ 30 , one_eps = 1 + eps
43+ @test @fastmath (one_eps * one_eps - 1 ) ≈ 2147483649 / 1152921504606846976
44+ end
4845
49- for T in (Float32, Float64, BigFloat)
50- zero = convert (T, 0 )
51- one = convert (T, 1 ) + eps (T)
52- two = convert (T, 2 ) + 1 // 10
53- three = convert (T, 3 ) + 1 // 100
54-
55- @test @fastmath (+ two) ≈ + two
56- @test @fastmath (- two) ≈ - two
57- @test @fastmath (zero+ one+ two) ≈ zero+ one+ two
58- @test @fastmath (zero- one- two) ≈ zero- one- two
59- @test @fastmath (one* two* three) ≈ one* two* three
60- @test @fastmath (one/ two/ three) ≈ one/ two/ three
61- @test @fastmath (rem (two,three)) ≈ rem (two,three)
62- @test @fastmath (mod (two,three)) ≈ mod (two,three)
63- @test @fastmath (cmp (two,two)) == cmp (two,two)
64- @test @fastmath (cmp (two,three)) == cmp (two,three)
65- @test @fastmath (cmp (three,two)) == cmp (three,two)
66- @test @fastmath (one/ zero) == convert (T,Inf )
67- @test @fastmath (- one/ zero) == - convert (T,Inf )
68- @test isnan (@fastmath (zero/ zero)) # must not throw
69-
70- for x in (zero, two, convert (T, Inf ), convert (T, NaN ))
71- @test @fastmath (isfinite (x))
72- @test ! @fastmath (isinf (x))
73- @test ! @fastmath (isnan (x))
74- @test ! @fastmath (issubnormal (x))
46+ for T in (Float32, Float64, BigFloat)
47+ zero = convert (T, 0 )
48+ one = convert (T, 1 ) + eps (T)
49+ two = convert (T, 2 ) + 1 // 10
50+ three = convert (T, 3 ) + 1 // 100
51+
52+ @test @fastmath (+ two) ≈ + two
53+ @test @fastmath (- two) ≈ - two
54+ @test @fastmath (zero+ one+ two) ≈ zero+ one+ two
55+ @test @fastmath (zero- one- two) ≈ zero- one- two
56+ @test @fastmath (one* two* three) ≈ one* two* three
57+ @test @fastmath (one/ two/ three) ≈ one/ two/ three
58+ @test @fastmath (rem (two,three)) ≈ rem (two,three)
59+ @test @fastmath (mod (two,three)) ≈ mod (two,three)
60+ @test @fastmath (cmp (two,two)) == cmp (two,two)
61+ @test @fastmath (cmp (two,three)) == cmp (two,three)
62+ @test @fastmath (cmp (three,two)) == cmp (three,two)
63+ @test @fastmath (one/ zero) == convert (T,Inf )
64+ @test @fastmath (- one/ zero) == - convert (T,Inf )
65+ @test isnan (@fastmath (zero/ zero)) # must not throw
66+
67+ for x in (zero, two, convert (T, Inf ), convert (T, NaN ))
68+ @test @fastmath (isfinite (x))
69+ @test ! @fastmath (isinf (x))
70+ @test ! @fastmath (isnan (x))
71+ @test ! @fastmath (issubnormal (x))
72+ end
7573 end
76- end
7774
78- for T in (Complex64, Complex128, Complex{BigFloat})
79- zero = convert (T,0 )
80- one = convert (T,1 ) + im* eps (real (convert (T,1 )))
81- two = convert (T,2 ) + im// 10
82- three = convert (T,3 ) + im// 100
83-
84- @test @fastmath (+ two) ≈ + two
85- @test @fastmath (- two) ≈ - two
86- @test @fastmath (zero+ one+ two) ≈ zero+ one+ two
87- @test @fastmath (zero- one- two) ≈ zero- one- two
88- @test @fastmath (one* two* three) ≈ one* two* three
89- @test @fastmath (one/ two/ three) ≈ one/ two/ three
90- @test @fastmath (three == two) == (three == two)
91- @test @fastmath (three != two) == (three != two)
92- @test isnan (@fastmath (one/ zero)) # must not throw
93- @test isnan (@fastmath (- one/ zero)) # must not throw
94- @test isnan (@fastmath (zero/ zero)) # must not throw
95-
96- for x in (zero, two, convert (T, Inf ), convert (T, NaN ))
97- @test @fastmath (isfinite (x))
98- @test ! @fastmath (isinf (x))
99- @test ! @fastmath (isnan (x))
100- @test ! @fastmath (issubnormal (x))
75+ for T in (Complex64, Complex128, Complex{BigFloat})
76+ zero = convert (T,0 )
77+ one = convert (T,1 ) + im* eps (real (convert (T,1 )))
78+ two = convert (T,2 ) + im// 10
79+ three = convert (T,3 ) + im// 100
80+
81+ @test @fastmath (+ two) ≈ + two
82+ @test @fastmath (- two) ≈ - two
83+ @test @fastmath (zero+ one+ two) ≈ zero+ one+ two
84+ @test @fastmath (zero- one- two) ≈ zero- one- two
85+ @test @fastmath (one* two* three) ≈ one* two* three
86+ @test @fastmath (one/ two/ three) ≈ one/ two/ three
87+ @test @fastmath (three == two) == (three == two)
88+ @test @fastmath (three != two) == (three != two)
89+ @test isnan (@fastmath (one/ zero)) # must not throw
90+ @test isnan (@fastmath (- one/ zero)) # must not throw
91+ @test isnan (@fastmath (zero/ zero)) # must not throw
92+
93+ for x in (zero, two, convert (T, Inf ), convert (T, NaN ))
94+ @test @fastmath (isfinite (x))
95+ @test ! @fastmath (isinf (x))
96+ @test ! @fastmath (isnan (x))
97+ @test ! @fastmath (issubnormal (x))
98+ end
10199 end
102100end
103101
104-
105102# math functions
106103
107- # real arithmetic
108- for T in (Float32, Float64, BigFloat)
109- half = 1 / convert (T,2 )
110- third = 1 / convert (T,3 )
111-
112- for f in (:+ , :- , :abs , :abs2 , :conj , :inv , :sign ,
113- :acos , :asin , :asinh , :atan , :atanh , :cbrt , :cos , :cosh ,
114- :exp10 , :exp2 , :exp , :expm1 , :lgamma , :log10 , :log1p ,
115- :log2 , :log , :sin , :sinh , :sqrt , :tan , :tanh )
116- @eval begin
117- @test @fastmath ($ f ($ half)) ≈ $ f ($ half)
118- @test @fastmath ($ f ($ third)) ≈ $ f ($ third)
104+ @testset " real arithmetic" begin
105+ for T in (Float32, Float64, BigFloat)
106+ half = 1 / convert (T,2 )
107+ third = 1 / convert (T,3 )
108+
109+ for f in (:+ , :- , :abs , :abs2 , :conj , :inv , :sign ,
110+ :acos , :asin , :asinh , :atan , :atanh , :cbrt , :cos , :cosh ,
111+ :exp10 , :exp2 , :exp , :expm1 , :lgamma , :log10 , :log1p ,
112+ :log2 , :log , :sin , :sinh , :sqrt , :tan , :tanh )
113+ @eval begin
114+ @test @fastmath ($ f ($ half)) ≈ $ f ($ half)
115+ @test @fastmath ($ f ($ third)) ≈ $ f ($ third)
116+ end
119117 end
120- end
121- for f in ( :acosh ,)
122- @eval begin
123- @test @fastmath ($ f (1 + $ half )) ≈ $ f (1 + $ half )
124- @test @fastmath ( $ f ( 1 + $ third)) ≈ $ f ( 1 + $ third)
118+ for f in ( :acosh ,)
119+ @eval begin
120+ @test @fastmath ( $ f ( 1 + $ half)) ≈ $ f ( 1 + $ half)
121+ @test @fastmath ($ f (1 + $ third )) ≈ $ f (1 + $ third )
122+ end
125123 end
126- end
127- for f in (: + , : - , : * , : / , : % , :( == ), : != , : < , : <= , :> , :>= , :^ ,
128- :atan2 , :hypot , :max , :min )
129- @eval begin
130- @test @fastmath ($ f ($ half , $ third )) ≈ $ f ($ half , $ third )
131- @test @fastmath ( $ f ( $ third, $ half)) ≈ $ f ( $ third, $ half)
124+ for f in (: + , : - , : * , : / , : % , :( == ), : != , : < , : <= , : > , : >= , : ^ ,
125+ :atan2 , :hypot , :max , :min )
126+ @eval begin
127+ @test @fastmath ( $ f ( $ half, $ third)) ≈ $ f ( $ half, $ third)
128+ @test @fastmath ($ f ($ third , $ half )) ≈ $ f ($ third , $ half )
129+ end
132130 end
133- end
134- for f in ( :minmax ,)
135- @eval begin
136- @test @fastmath ($ f ($ half, $ third)[1 ]) ≈ $ f ($ half, $ third)[1 ]
137- @test @fastmath ($ f ($ half , $ third)[ 2 ]) ≈ $ f ($ half , $ third)[ 2 ]
138- @test @fastmath ($ f ($ third, $ half)[1 ]) ≈ $ f ($ third, $ half)[1 ]
139- @test @fastmath ( $ f ( $ third, $ half)[ 2 ]) ≈ $ f ( $ third, $ half)[ 2 ]
131+ for f in ( :minmax ,)
132+ @eval begin
133+ @test @fastmath ( $ f ( $ half, $ third)[ 1 ]) ≈ $ f ( $ half, $ third)[ 1 ]
134+ @test @fastmath ($ f ($ half, $ third)[2 ]) ≈ $ f ($ half, $ third)[2 ]
135+ @test @fastmath ($ f ($ third , $ half)[ 1 ]) ≈ $ f ($ third , $ half)[ 1 ]
136+ @test @fastmath ($ f ($ third, $ half)[2 ]) ≈ $ f ($ third, $ half)[2 ]
137+ end
140138 end
141139 end
142140end
143-
144- # complex arithmetic
145- for T in (Complex64, Complex128, Complex{BigFloat} )
146- half = (1 + 1im )/ T (2 )
147- third = ( 1 - 1im ) / T ( 3 )
148-
149- # some of these functions promote their result to double
150- # precision, but we want to check equality at precision T
151- rtol = Base . rtoldefault ( real (T))
152-
153- for f in (: + , :- , :abs , :abs2 , :conj , :inv , :sign ,
154- :acos , :acosh , :asin , :asinh , :atan , :atanh , :cis , :cos ,
155- :cosh , :exp10 , :exp2 , :exp , :expm1 , :log10 , :log1p ,
156- :log2 , :log , :sin , :sinh , :sqrt , :tan , :tanh )
157- @eval begin
158- @test @fastmath ($ f ($ half )) ≈ $ f ($ half ) rtol= $ rtol
159- @test @fastmath ( $ f ( $ third)) ≈ $ f ( $ third) rtol = $ rtol
141+ @testset " complex arithmetic " begin
142+ for T in (Complex64, Complex128, Complex{BigFloat})
143+ half = ( 1 + 1im ) / T ( 2 )
144+ third = (1 - 1im )/ T (3 )
145+
146+ # some of these functions promote their result to double
147+ # precision, but we want to check equality at precision T
148+ rtol = Base . rtoldefault ( real (T))
149+
150+ for f in (: + , : - , :abs , :abs2 , :conj , :inv , :sign ,
151+ :acos , :acosh , :asin , :asinh , :atan , :atanh , :cis , :cos ,
152+ :cosh , :exp10 , :exp2 , :exp , :expm1 , :log10 , :log1p ,
153+ :log2 , :log , :sin , :sinh , :sqrt , :tan , :tanh )
154+ @eval begin
155+ @test @fastmath ( $ f ( $ half)) ≈ $ f ( $ half) rtol = $ rtol
156+ @test @fastmath ($ f ($ third )) ≈ $ f ($ third ) rtol= $ rtol
157+ end
160158 end
161- end
162- for f in (: + , : - , : * , : / , :( == ), : != , : ^ )
163- @eval begin
164- @test @fastmath ($ f ($ half , $ third )) ≈ $ f ($ half , $ third ) rtol= $ rtol
165- @test @fastmath ( $ f ( $ third, $ half)) ≈ $ f ( $ third, $ half) rtol = $ rtol
159+ for f in (: + , : - , : * , : / , :( == ), : != , : ^ )
160+ @eval begin
161+ @test @fastmath ( $ f ( $ half, $ third)) ≈ $ f ( $ half, $ third) rtol = $ rtol
162+ @test @fastmath ($ f ($ third , $ half )) ≈ $ f ($ third , $ half ) rtol= $ rtol
163+ end
166164 end
167165 end
168166end
169-
170- # mixed real/complex arithmetic
171- for T in (Float32, Float64, BigFloat)
172- CT = Complex{T}
173- half = 1 / T (2 )
174- third = 1 / T ( 3 )
175- chalf = (1 + 1im )/ CT (2 )
176- cthird = ( 1 - 1im ) / CT ( 3 )
177-
178- for f in (: + , : - , : * , : / , :( == ), : != , : ^ )
179- @eval begin
180- @test @fastmath ($ f ($ chalf , $ third )) ≈ $ f ($ chalf , $ third )
181- @test @fastmath ($ f ($ half , $ cthird )) ≈ $ f ($ half , $ cthird )
182- @test @fastmath ($ f ($ cthird , $ half )) ≈ $ f ($ cthird , $ half )
183- @test @fastmath ( $ f ( $ third, $ chalf)) ≈ $ f ( $ third, $ chalf)
167+ @testset " mixed real/complex arithmetic " begin
168+ for T in (Float32, Float64, BigFloat)
169+ CT = Complex{T}
170+ half = 1 / T ( 2 )
171+ third = 1 / T (3 )
172+ chalf = ( 1 + 1im ) / CT ( 2 )
173+ cthird = (1 - 1im )/ CT (3 )
174+
175+ for f in (: + , : - , : * , : / , :( == ), : != , : ^ )
176+ @eval begin
177+ @test @fastmath ( $ f ( $ chalf, $ third)) ≈ $ f ( $ chalf, $ third)
178+ @test @fastmath ($ f ($ half , $ cthird )) ≈ $ f ($ half , $ cthird )
179+ @test @fastmath ($ f ($ cthird , $ half )) ≈ $ f ($ cthird , $ half )
180+ @test @fastmath ($ f ($ third , $ chalf )) ≈ $ f ($ third , $ chalf )
181+ end
184182 end
185- end
186183
187- @test @fastmath (third^ 3 ) ≈ third^ 3
188- @test @fastmath (chalf/ third) ≈ chalf/ third
189- @test @fastmath (chalf^ 3 ) ≈ chalf^ 3
190- @test @fastmath (cis (third)) ≈ cis (third)
184+ @test @fastmath (third^ 3 ) ≈ third^ 3
185+ @test @fastmath (chalf/ third) ≈ chalf/ third
186+ @test @fastmath (chalf^ 3 ) ≈ chalf^ 3
187+ @test @fastmath (cis (third)) ≈ cis (third)
188+ end
191189end
192-
193- # issue #10544
194- let a = ones ( 2 , 2 ), b = ones (2 ,2 )
190+ @testset " issue #10544 " begin
191+ a = ones ( 2 , 2 )
192+ b = ones (2 ,2 )
195193 @test @fastmath (a[1 ] += 2.0 ) ≈ (b[1 ] += 2.0 )
196194 @test @fastmath (a[2 ] -= 2.0 ) ≈ (b[2 ] -= 2.0 )
197195 @test @fastmath (a[1 ,1 ] *= 2.0 ) ≈ (b[1 ,1 ] *= 2.0 )
@@ -203,8 +201,10 @@ let a = ones(2,2), b = ones(2,2)
203201 @test @fastmath (c |= 1 ) == 1
204202end
205203
206- # issue #23218
207- let a = zeros (1 ), b = ones (1 ), idx = (1 ,)
204+ @testset " issue #23218" begin
205+ a = zeros (1 )
206+ b = ones (1 )
207+ idx = (1 ,)
208208 @fastmath a[idx... ] += b[idx... ]
209209 @test a == b
210210end
0 commit comments