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