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