xref: /freebsd/contrib/arm-optimized-routines/math/tools/plot.py (revision 31914882fca502069810b9e9ddea4bcd8136a4f4)
1*31914882SAlex Richardson#!/usr/bin/python
2*31914882SAlex Richardson
3*31914882SAlex Richardson# ULP error plot tool.
4*31914882SAlex Richardson#
5*31914882SAlex Richardson# Copyright (c) 2019, Arm Limited.
6*31914882SAlex Richardson# SPDX-License-Identifier: MIT
7*31914882SAlex Richardson
8*31914882SAlex Richardsonimport numpy as np
9*31914882SAlex Richardsonimport matplotlib.pyplot as plt
10*31914882SAlex Richardsonimport sys
11*31914882SAlex Richardsonimport re
12*31914882SAlex Richardson
13*31914882SAlex Richardson# example usage:
14*31914882SAlex Richardson# build/bin/ulp -e .0001 log 0.5 2.0 2345678 | math/tools/plot.py
15*31914882SAlex Richardson
16*31914882SAlex Richardsondef fhex(s):
17*31914882SAlex Richardson	return float.fromhex(s)
18*31914882SAlex Richardson
19*31914882SAlex Richardsondef parse(f):
20*31914882SAlex Richardson	xs = []
21*31914882SAlex Richardson	gs = []
22*31914882SAlex Richardson	ys = []
23*31914882SAlex Richardson	es = []
24*31914882SAlex Richardson	# Has to match the format used in ulp.c
25*31914882SAlex Richardson	r = re.compile(r'[^ (]+\(([^ )]*)\) got ([^ ]+) want ([^ ]+) [^ ]+ ulp err ([^ ]+)')
26*31914882SAlex Richardson	for line in f:
27*31914882SAlex Richardson		m = r.match(line)
28*31914882SAlex Richardson		if m:
29*31914882SAlex Richardson			x = fhex(m.group(1))
30*31914882SAlex Richardson			g = fhex(m.group(2))
31*31914882SAlex Richardson			y = fhex(m.group(3))
32*31914882SAlex Richardson			e = float(m.group(4))
33*31914882SAlex Richardson			xs.append(x)
34*31914882SAlex Richardson			gs.append(g)
35*31914882SAlex Richardson			ys.append(y)
36*31914882SAlex Richardson			es.append(e)
37*31914882SAlex Richardson		elif line.startswith('PASS') or line.startswith('FAIL'):
38*31914882SAlex Richardson			# Print the summary line
39*31914882SAlex Richardson			print(line)
40*31914882SAlex Richardson	return xs, gs, ys, es
41*31914882SAlex Richardson
42*31914882SAlex Richardsondef plot(xs, gs, ys, es):
43*31914882SAlex Richardson	if len(xs) < 2:
44*31914882SAlex Richardson		print('not enough samples')
45*31914882SAlex Richardson		return
46*31914882SAlex Richardson	a = min(xs)
47*31914882SAlex Richardson	b = max(xs)
48*31914882SAlex Richardson	fig, (ax0,ax1) = plt.subplots(nrows=2)
49*31914882SAlex Richardson	es = np.abs(es) # ignore the sign
50*31914882SAlex Richardson	emax = max(es)
51*31914882SAlex Richardson	ax0.text(a+(b-a)*0.7, emax*0.8, '%s\n%g'%(emax.hex(),emax))
52*31914882SAlex Richardson	ax0.plot(xs,es,'r.')
53*31914882SAlex Richardson	ax0.grid()
54*31914882SAlex Richardson	ax1.plot(xs,ys,'r.',label='want')
55*31914882SAlex Richardson	ax1.plot(xs,gs,'b.',label='got')
56*31914882SAlex Richardson	ax1.grid()
57*31914882SAlex Richardson	ax1.legend()
58*31914882SAlex Richardson	plt.show()
59*31914882SAlex Richardson
60*31914882SAlex Richardsonxs, gs, ys, es = parse(sys.stdin)
61*31914882SAlex Richardsonplot(xs, gs, ys, es)
62