@@ -18,56 +18,63 @@ def assert_raises_fpe(strmatch, callable, *args, **kwargs):
18
18
f"Did not raise floating point { strmatch } error" )
19
19
20
20
class TestHalf :
21
- def setup_method (self ):
21
+ def _create_arrays_all (self ):
22
22
# An array of all possible float16 values
23
- self . all_f16 = np .arange (0x10000 , dtype = uint16 )
24
- self . all_f16 = self . all_f16 .view (float16 )
23
+ all_f16 = np .arange (0x10000 , dtype = uint16 )
24
+ all_f16 = all_f16 .view (float16 )
25
25
26
26
# NaN value can cause an invalid FP exception if HW is being used
27
27
with np .errstate (invalid = 'ignore' ):
28
- self .all_f32 = np .array (self .all_f16 , dtype = float32 )
29
- self .all_f64 = np .array (self .all_f16 , dtype = float64 )
28
+ all_f32 = np .array (all_f16 , dtype = float32 )
29
+ all_f64 = np .array (all_f16 , dtype = float64 )
30
+ return all_f16 , all_f32 , all_f64
30
31
32
+ def _create_arrays_nonan (self ):
31
33
# An array of all non-NaN float16 values, in sorted order
32
- self . nonan_f16 = np .concatenate (
34
+ nonan_f16 = np .concatenate (
33
35
(np .arange (0xfc00 , 0x7fff , - 1 , dtype = uint16 ),
34
36
np .arange (0x0000 , 0x7c01 , 1 , dtype = uint16 )))
35
- self .nonan_f16 = self .nonan_f16 .view (float16 )
36
- self .nonan_f32 = np .array (self .nonan_f16 , dtype = float32 )
37
- self .nonan_f64 = np .array (self .nonan_f16 , dtype = float64 )
38
-
39
- # An array of all finite float16 values, in sorted order
40
- self .finite_f16 = self .nonan_f16 [1 :- 1 ]
41
- self .finite_f32 = self .nonan_f32 [1 :- 1 ]
42
- self .finite_f64 = self .nonan_f64 [1 :- 1 ]
37
+ nonan_f16 = nonan_f16 .view (float16 )
38
+ nonan_f32 = np .array (nonan_f16 , dtype = float32 )
39
+ nonan_f64 = np .array (nonan_f16 , dtype = float64 )
40
+ return nonan_f16 , nonan_f32 , nonan_f64
41
+
42
+ def _create_arrays_finite (self ):
43
+ nonan_f16 , nonan_f32 , nonan_f64 = self ._create_arrays_nonan ()
44
+ finite_f16 = nonan_f16 [1 :- 1 ]
45
+ finite_f32 = nonan_f32 [1 :- 1 ]
46
+ finite_f64 = nonan_f64 [1 :- 1 ]
47
+ return finite_f16 , finite_f32 , finite_f64
43
48
44
49
def test_half_conversions (self ):
45
50
"""Checks that all 16-bit values survive conversion
46
51
to/from 32-bit and 64-bit float"""
47
52
# Because the underlying routines preserve the NaN bits, every
48
53
# value is preserved when converting to/from other floats.
54
+ all_f16 , all_f32 , all_f64 = self ._create_arrays_all ()
55
+ nonan_f16 , _ , _ = self ._create_arrays_nonan ()
49
56
50
57
# Convert from float32 back to float16
51
58
with np .errstate (invalid = 'ignore' ):
52
- b = np .array (self . all_f32 , dtype = float16 )
59
+ b = np .array (all_f32 , dtype = float16 )
53
60
# avoid testing NaNs due to differing bit patterns in Q/S NaNs
54
61
b_nn = b == b
55
- assert_equal (self . all_f16 [b_nn ].view (dtype = uint16 ),
62
+ assert_equal (all_f16 [b_nn ].view (dtype = uint16 ),
56
63
b [b_nn ].view (dtype = uint16 ))
57
64
58
65
# Convert from float64 back to float16
59
66
with np .errstate (invalid = 'ignore' ):
60
- b = np .array (self . all_f64 , dtype = float16 )
67
+ b = np .array (all_f64 , dtype = float16 )
61
68
b_nn = b == b
62
- assert_equal (self . all_f16 [b_nn ].view (dtype = uint16 ),
69
+ assert_equal (all_f16 [b_nn ].view (dtype = uint16 ),
63
70
b [b_nn ].view (dtype = uint16 ))
64
71
65
72
# Convert float16 to longdouble and back
66
73
# This doesn't necessarily preserve the extra NaN bits,
67
74
# so exclude NaNs.
68
- a_ld = np .array (self . nonan_f16 , dtype = np .longdouble )
75
+ a_ld = np .array (nonan_f16 , dtype = np .longdouble )
69
76
b = np .array (a_ld , dtype = float16 )
70
- assert_equal (self . nonan_f16 .view (dtype = uint16 ),
77
+ assert_equal (nonan_f16 .view (dtype = uint16 ),
71
78
b .view (dtype = uint16 ))
72
79
73
80
# Check the range for which all integers can be represented
@@ -171,34 +178,35 @@ def test_half_conversion_denormal_round_even(self, float_t, uint_t, bits):
171
178
assert larger_value .astype (np .float16 ) == smallest_value
172
179
173
180
def test_nans_infs (self ):
181
+ all_f16 , all_f32 , _ = self ._create_arrays_all ()
174
182
with np .errstate (all = 'ignore' ):
175
183
# Check some of the ufuncs
176
- assert_equal (np .isnan (self . all_f16 ), np .isnan (self . all_f32 ))
177
- assert_equal (np .isinf (self . all_f16 ), np .isinf (self . all_f32 ))
178
- assert_equal (np .isfinite (self . all_f16 ), np .isfinite (self . all_f32 ))
179
- assert_equal (np .signbit (self . all_f16 ), np .signbit (self . all_f32 ))
184
+ assert_equal (np .isnan (all_f16 ), np .isnan (all_f32 ))
185
+ assert_equal (np .isinf (all_f16 ), np .isinf (all_f32 ))
186
+ assert_equal (np .isfinite (all_f16 ), np .isfinite (all_f32 ))
187
+ assert_equal (np .signbit (all_f16 ), np .signbit (all_f32 ))
180
188
assert_equal (np .spacing (float16 (65504 )), np .inf )
181
189
182
190
# Check comparisons of all values with NaN
183
191
nan = float16 (np .nan )
184
192
185
- assert_ (not (self . all_f16 == nan ).any ())
186
- assert_ (not (nan == self . all_f16 ).any ())
193
+ assert_ (not (all_f16 == nan ).any ())
194
+ assert_ (not (nan == all_f16 ).any ())
187
195
188
- assert_ ((self . all_f16 != nan ).all ())
189
- assert_ ((nan != self . all_f16 ).all ())
196
+ assert_ ((all_f16 != nan ).all ())
197
+ assert_ ((nan != all_f16 ).all ())
190
198
191
- assert_ (not (self . all_f16 < nan ).any ())
192
- assert_ (not (nan < self . all_f16 ).any ())
199
+ assert_ (not (all_f16 < nan ).any ())
200
+ assert_ (not (nan < all_f16 ).any ())
193
201
194
- assert_ (not (self . all_f16 <= nan ).any ())
195
- assert_ (not (nan <= self . all_f16 ).any ())
202
+ assert_ (not (all_f16 <= nan ).any ())
203
+ assert_ (not (nan <= all_f16 ).any ())
196
204
197
- assert_ (not (self . all_f16 > nan ).any ())
198
- assert_ (not (nan > self . all_f16 ).any ())
205
+ assert_ (not (all_f16 > nan ).any ())
206
+ assert_ (not (nan > all_f16 ).any ())
199
207
200
- assert_ (not (self . all_f16 >= nan ).any ())
201
- assert_ (not (nan >= self . all_f16 ).any ())
208
+ assert_ (not (all_f16 >= nan ).any ())
209
+ assert_ (not (nan >= all_f16 ).any ())
202
210
203
211
def test_half_values (self ):
204
212
"""Confirms a small number of known half values"""
@@ -255,9 +263,10 @@ def test_half_rounding(self):
255
263
def test_half_correctness (self ):
256
264
"""Take every finite float16, and check the casting functions with
257
265
a manual conversion."""
266
+ finite_f16 , finite_f32 , finite_f64 = self ._create_arrays_finite ()
258
267
259
268
# Create an array of all finite float16s
260
- a_bits = self . finite_f16 .view (dtype = uint16 )
269
+ a_bits = finite_f16 .view (dtype = uint16 )
261
270
262
271
# Convert to 64-bit float manually
263
272
a_sgn = (- 1.0 )** ((a_bits & 0x8000 ) >> 15 )
@@ -270,29 +279,30 @@ def test_half_correctness(self):
270
279
271
280
a_manual = a_sgn * a_man * 2.0 ** a_exp
272
281
273
- a32_fail = np .nonzero (self . finite_f32 != a_manual )[0 ]
282
+ a32_fail = np .nonzero (finite_f32 != a_manual )[0 ]
274
283
if len (a32_fail ) != 0 :
275
284
bad_index = a32_fail [0 ]
276
- assert_equal (self . finite_f32 , a_manual ,
285
+ assert_equal (finite_f32 , a_manual ,
277
286
"First non-equal is half value 0x%x -> %g != %g" %
278
287
(a_bits [bad_index ],
279
- self . finite_f32 [bad_index ],
288
+ finite_f32 [bad_index ],
280
289
a_manual [bad_index ]))
281
290
282
- a64_fail = np .nonzero (self . finite_f64 != a_manual )[0 ]
291
+ a64_fail = np .nonzero (finite_f64 != a_manual )[0 ]
283
292
if len (a64_fail ) != 0 :
284
293
bad_index = a64_fail [0 ]
285
- assert_equal (self . finite_f64 , a_manual ,
294
+ assert_equal (finite_f64 , a_manual ,
286
295
"First non-equal is half value 0x%x -> %g != %g" %
287
296
(a_bits [bad_index ],
288
- self . finite_f64 [bad_index ],
297
+ finite_f64 [bad_index ],
289
298
a_manual [bad_index ]))
290
299
291
300
def test_half_ordering (self ):
292
301
"""Make sure comparisons are working right"""
302
+ nonan_f16 , _ , _ = self ._create_arrays_nonan ()
293
303
294
304
# All non-NaN float16 values in reverse order
295
- a = self . nonan_f16 [::- 1 ].copy ()
305
+ a = nonan_f16 [::- 1 ].copy ()
296
306
297
307
# 32-bit float copy
298
308
b = np .array (a , dtype = float32 )
0 commit comments