15 posit_derepr
= re
.compile(r
'Posit[0-9]+\((.*)\)')
17 def posit_get_classes(nbits
):
19 return sfpy
.Posit8
, softposit
.posit8
21 return sfpy
.Posit16
, softposit
.posit16
23 return sfpy
.Posit32
, softposit
.posit32
25 raise ValueError('no representation of {}-bit posits'.format(repr(nbits
)))
27 def posit_get_fn(mod
, nbits
, fn
):
28 return getattr(mod
, 'p' + str(nbits
) + '_' + fn
)
30 def posit_get_rounding_arguments(nbits
, extra
=False):
31 sfpy_cls
, sp_cls
= posit_get_classes(nbits
)
32 mask
= (1 << nbits
) - 1
37 for i
in range(1 - (1<<(nbits
-1)), (1<<(nbits
-1)) - 1):
38 f1
= float(sfpy_cls(i
& mask
))
39 f2
= float(sfpy_cls((i
+1) & mask
))
41 geomean
= math
.sqrt(f1
* f2
)
44 cases
.add(float(numpy
.nextafter(f1
, ninf
)))
45 cases
.add(float(numpy
.nextafter(f1
, inf
)))
47 cases
.add(float(numpy
.nextafter(mean
, ninf
)))
48 cases
.add(float(numpy
.nextafter(mean
, inf
)))
50 cases
.add(float(numpy
.nextafter(geomean
, ninf
)))
51 cases
.add(float(numpy
.nextafter(geomean
, inf
)))
54 cases
.add(float(numpy
.nextafter(f2
, ninf
)))
55 cases
.add(float(numpy
.nextafter(f2
, inf
)))
61 morecases
.add(1 / case
)
64 cases
.update(morecases
)
69 def posit_test_representation_bits(nbits
, it
):
70 sfpy_cls
, sp_cls
= posit_get_classes(nbits
)
73 sfpy_2
= sfpy_cls
.from_bits(i
)
78 sfpy_1
.bits
== sfpy_2
.bits
== sp_1
.v
.v
79 and float(sfpy_1
) == float(sfpy_2
) == float(sp_1
)
81 # and int(sfpy_1) == int(sfpy_2) == int(sp_1)
83 print('representation mismatch on bits: {}'.format(repr(i
)))
86 sfpy_3
= sfpy_cls(float(str(sfpy_1
)))
87 sfpy_4
= sfpy_cls(float(str(sfpy_2
)))
88 sfpy_5
= sfpy_cls(float(posit_derepr
.match(repr(sfpy_1
)).group(1)))
89 sfpy_6
= sfpy_cls(float(posit_derepr
.match(repr(sfpy_2
)).group(1)))
90 # problem: 'NaR' strings
91 # sp_2 = sp_cls(float(str(sp_1)))
92 # sp_3 = sp_cls(float(repr(sp_1)))
95 sfpy_1
.bits
== sfpy_3
.bits
== sfpy_4
.bits
== sfpy_5
.bits
== sfpy_6
.bits
# == sp_2.v.v == sp_3.v.v
97 print('string representation mismatch on bits: {}'.format(repr(i
)))
102 def posit_test_representation_floats(nbits
, it
):
103 sfpy_cls
, sp_cls
= posit_get_classes(nbits
)
106 sfpy_2
= sfpy_cls
.from_double(f
)
110 sfpy_1
.bits
== sfpy_2
.bits
== sp_1
.v
.v
112 print('bit representation mismatch on float: {}'.format(repr(i
)))
118 def posit_test_neg(nbits
, it
):
120 sfpy_cls
, sp_cls
= posit_get_classes(nbits
)
121 fn
= posit_get_fn(sfpy
.posit
, nbits
, fname
)
125 sfpy_2
= sfpy_0
.neg()
135 sp_1
.v
.v
== sfpy_1
.bits
== sfpy_2
.bits
== sfpy_3
.bits
== sfpy_4
.bits
137 print('{} mismatch on bits: {}'.format(fname
, repr(i
)))
143 def dispatch_test(pool
, workers
, n
, test
, nbits
, *it
):
144 print('running {}'.format(repr(test
)))
151 for i
in range(workers
):
153 it0
= it
[0][idx
:new_idx
]
155 print(' dispatch {:d}:{:d}'.format(idx
, new_idx
))
156 work_slots
.append(pool
.apply_async(test
, (nbits
, it0
, *(it
[1:]))))
159 # crude sleep-wait loop to redispatch
162 for i
, result
in enumerate(work_slots
):
164 failed
= result
.get()
169 it0
= it
[0][idx
:new_idx
]
171 print(' dispatch {:d}:{:d}'.format(idx
, new_idx
))
172 work_slots
[i
] = pool
.apply_async(test
, (nbits
, it0
, *(it
[1:])))
179 for result
in work_slots
:
181 failed
= result
.get()
188 if __name__
== '__main__':
190 workers
= os
.cpu_count()
192 pool
= multiprocessing
.Pool(processes
=workers
, maxtasksperchild
=1)
195 dispatch_test(pool
, workers
, 256, posit_test_representation_bits
, 8, range(1 << 8))
196 or dispatch_test(pool
, workers
, 10000, posit_test_representation_bits
, 16, range(1 << 16))
199 args
= posit_get_rounding_arguments(8, True)
200 dispatch_test(pool
, workers
, 10000, posit_test_representation_floats
, 8, args
)
201 args
= posit_get_rounding_arguments(16, True)
202 dispatch_test(pool
, workers
, 100000, posit_test_representation_floats
, 16, args
)
205 dispatch_test(pool
, workers
, 256, posit_test_neg
, 8, range(1 << 8))
206 or dispatch_test(pool
, workers
, 10000, posit_test_neg
, 16, range(1 << 16))
211 print('Failed?', failed
)
213 # print('testing Poist8 neg / abs...')
214 # for i in range(1 << 8):
217 # minus_x = x * sfpy.Posit8(-1.0)
219 # if not neg_x.bits == minus_x.bits:
220 # print('-', x, neg_x, minus_x)
222 # neg_x2 = sfpy.posit.p8_neg(x)
224 # if not neg_x2.bits == minus_x.bits:
225 # print('p8_neg', x, neg_x2, minus_x)
229 # if not x.bits == minus_x.bits:
230 # print('ineg', x, minus_x)
235 # if y < sfpy.Posit8(0):
236 # ifneg_y = y * sfpy.Posit8(-1.0)
238 # ifneg_y = y * sfpy.Posit8(1.0)
240 # if not abs_y.bits == ifneg_y.bits:
241 # print('abs', y, abs_y, ifneg_y)
243 # abs_y2 = sfpy.posit.p8_abs(y)
245 # if not abs_y2.bits == ifneg_y.bits:
246 # print('p8_abs', y, abs_y2, ifneg_y)
250 # if not y.bits == ifneg_y.bits:
251 # print('iabs', y, ifneg_y)
254 # print('testing Poist16 neg / abs...')
255 # for i in range(1 << 16):
256 # x = sfpy.Posit16(i)
258 # minus_x = x * sfpy.Posit16(-1.0)
260 # if not neg_x.bits == minus_x.bits:
261 # print('-', x, neg_x, minus_x)
263 # neg_x2 = sfpy.posit.p16_neg(x)
265 # if not neg_x2.bits == minus_x.bits:
266 # print('p16_neg', x, neg_x2, minus_x)
270 # if not x.bits == minus_x.bits:
271 # print('ineg', x, minus_x)
274 # y = sfpy.Posit16(i)
276 # if y < sfpy.Posit16(0):
277 # ifneg_y = y * sfpy.Posit16(-1.0)
279 # ifneg_y = y * sfpy.Posit16(1.0)
281 # if not abs_y.bits == ifneg_y.bits:
282 # print('abs', y, abs_y, ifneg_y)
284 # abs_y2 = sfpy.posit.p16_abs(y)
286 # if not abs_y2.bits == ifneg_y.bits:
287 # print('p16_abs', y, abs_y2, ifneg_y)
291 # if not y.bits == ifneg_y.bits:
292 # print('iabs', y, ifneg_y)
295 # print('testing Poist32 neg / abs...')
296 # for i in range(1 << 32):
297 # x = sfpy.Posit32(i)
299 # minus_x = x * sfpy.Posit32(-1.0)
301 # if not neg_x.bits == minus_x.bits:
302 # print('-', x, neg_x, minus_x)
304 # neg_x2 = sfpy.posit.p32_neg(x)
306 # if not neg_x2.bits == minus_x.bits:
307 # print('p32_neg', x, neg_x2, minus_x)
311 # if not x.bits == minus_x.bits:
312 # print('ineg', x, minus_x)
315 # y = sfpy.Posit32(i)
317 # if y < sfpy.Posit32(0):
318 # ifneg_y = y * sfpy.Posit32(-1.0)
320 # ifneg_y = y * sfpy.Posit32(1.0)
322 # if not abs_y.bits == ifneg_y.bits:
323 # print('abs', y, abs_y, ifneg_y)
325 # abs_y2 = sfpy.posit.p32_abs(y)
327 # if not abs_y2.bits == ifneg_y.bits:
328 # print('p32_abs', y, abs_y2, ifneg_y)
332 # if not y.bits == ifneg_y.bits:
333 # print('iabs', y, ifneg_y)