blob: 18b4e8c79e1279cae159ea6c0edb2fe476882644 [file] [log] [blame]
Christophe Favergeon3b2a0ee2019-06-12 13:29:14 +02001# Process the test results
2# Test status (like passed, or failed with error code)
3
4import argparse
5import re
6import TestScripts.NewParser as parse
7import TestScripts.CodeGen
8from collections import deque
9import os.path
10import numpy as np
11import pandas as pd
12import statsmodels.api as sm
13import statsmodels.formula.api as smf
14import csv
15
16def findItem(root,path):
17 """ Find a node in a tree
18
19 Args:
20 path (list) : A list of node ID
21 This list is describing a path in the tree.
22 By starting from the root and following this path,
23 we can find the node in the tree.
24 Raises:
25 Nothing
26 Returns:
27 TreeItem : A node
28 """
29 # The list is converted into a queue.
30 q = deque(path)
31 q.popleft()
32 c = root
33 while q:
34 n = q.popleft()
35 # We get the children based on its ID and continue
36 c = c[n-1]
37 return(c)
38
39
40
41NORMAL = 1
42INTEST = 2
43TESTPARAM = 3
44
45def joinit(iterable, delimiter):
46 it = iter(iterable)
47 yield next(it)
48 for x in it:
49 yield delimiter
50 yield x
51
52def formatProd(a,b):
53 if a == "Intercept":
54 return(str(b))
55 return("%s * %s" % (a,b))
56
57def summaryBenchmark(elem,path):
58 regressionPath=os.path.join(os.path.dirname(path),"regression.csv")
59 full=pd.read_csv(path)
60
61 csvheaders = []
62 with open('currentConfig.csv', 'r') as f:
63 reader = csv.reader(f)
64 csvheaders = next(reader, None)
65
66 groupList = list(set(elem.params.full) - set(elem.params.summary))
67 #grouped=full.groupby(list(elem.params.summary) + ['ID','CATEGORY']).max()
68 #grouped.reset_index(level=grouped.index.names, inplace=True)
69 #print(grouped)
70 #print(grouped.columns)
71
72
73 def reg(d):
74 m=d["CYCLES"].max()
75 results = smf.ols('CYCLES ~ ' + elem.params.formula, data=d).fit()
76 f=joinit([formatProd(a,b) for (a,b) in zip(results.params.index,results.params.values)]," + ")
77 f="".join(f)
78 f = re.sub(r':','*',f)
79 #print(results.summary())
80 return(pd.Series({'Regression':"%s" % f,'MAX' : m}))
81
82 regList = ['ID','CATEGORY','NAME'] + csvheaders + groupList
83
84 regression=full.groupby(regList).apply(reg)
85 regression.reset_index(level=regression.index.names, inplace=True)
86 renamingDict = { a : b for (a,b) in zip(elem.params.full,elem.params.paramNames)}
87 regression = regression.rename(columns=renamingDict)
88 regression.to_csv(regressionPath,index=False,quoting=csv.QUOTE_NONNUMERIC)
89
90
91
92def analyseResult(root,results,embedded,benchmark):
93 path = []
94 state = NORMAL
95 prefix=""
96 elem=None
97 theId=None
98 theError=None
99 theLine=None
100 passed=0
101 cycles=None
102 benchFile = None
103 if embedded:
104 prefix = ".*S:[ ]"
105
106 # Parse the result file.
107 # NORMAL mode is when we are parsing suite or group.
108 # Otherwise we are parsing a test and we need to analyse the
109 # test result.
110 # TESTPARAM is used to read parameters of the test.
111 # Format of output is:
112 #node ident : s id or g id or t or u
113 #test status : id error linenb status Y or N (Y when passing)
114 #param for this test b x,x,x,x or b alone if not param
115 #node end : p
116 # In FPGA mode:
117 #Prefix S:[ ] before driver dump
118 # D:[ ] before data dump (output patterns)
119
120 for l in results:
121 l = l.strip()
122 if not re.match(r'^.*D:[ ].*$',l):
123 if state == NORMAL:
124 if len(l) > 0:
125 # Line starting with g or s is a suite or group.
126 # In FPGA mode, those line are prefixed with 'S: '
127 # and data file with 'D: '
128 if re.match(r'^%s[gs][ ]+[0-9]+.*$' % prefix,l):
129 # Extract the test id
130 theId=re.sub(r'^%s[gs][ ]+([0-9]+).*$' % prefix,r'\1',l)
131 theId=int(theId)
132 path.append(theId)
133 # From a list of id, find the TreeElem in the Parsed tree
134 # to know what is the node.
135 elem = findItem(root,path)
136 # Display formatted output for this node
137 if elem.params:
138 #print(elem.params.full)
139 benchPath = os.path.join(benchmark,elem.fullPath(),"fullBenchmark.csv")
140 summaryBenchmark(elem,benchPath)
141
142
143 # If we have detected a test, we switch to test mode
144 if re.match(r'^%s[t][ ]*$' % prefix,l):
145 state = INTEST
146
147
148 # Pop
149 # End of suite or group
150 if re.match(r'^%sp.*$' % prefix,l):
151 path.pop()
152 elif state == INTEST:
153 if len(l) > 0:
154 # In test mode, we are looking for test status.
155 # A line starting with S
156 # (There may be empty lines or line for data files)
157 passRe = r'^%s([0-9]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([YN]).*$' % prefix
158 if re.match(passRe,l):
159 # If we have found a test status then we will start again
160 # in normal mode after this.
161
162 m = re.match(passRe,l)
163
164 # Extract test ID, test error code, line number and status
165 theId=m.group(1)
166 theId=int(theId)
167
168 status=m.group(5)
169 passed=0
170
171 # Convert status to number as used by formatter.
172 if status=="Y":
173 passed = 1
174 if status=="N":
175 passed = 0
176 # Compute path to this node
177 newPath=path.copy()
178 newPath.append(theId)
179 # Find the node in the Tree
180 elem = findItem(root,newPath)
181
182
183 state = TESTPARAM
184 else:
185 if re.match(r'^%sp.*$' % prefix,l):
186 path.pop()
187 if re.match(r'^%s[t][ ]*$' % prefix,l):
188 state = INTEST
189 else:
190 state = NORMAL
191 else:
192 if len(l) > 0:
193 state = INTEST
194 params=""
195
196
197parser = argparse.ArgumentParser(description='Generate summary benchmarks')
198
199parser.add_argument('-f', nargs='?',type = str, default=None, help="Test description file path")
200# Where the result file can be found
201parser.add_argument('-r', nargs='?',type = str, default=None, help="Result file path")
202
203parser.add_argument('-b', nargs='?',type = str, default="FullBenchmark", help="Full Benchmark dir path")
204parser.add_argument('-e', action='store_true', help="Embedded test")
205
206args = parser.parse_args()
207
208if args.f is not None:
209 p = parse.Parser()
210 # Parse the test description file
211 root = p.parse(args.f)
212 with open(args.r,"r") as results:
213 analyseResult(root,results,args.e,args.b)
214
215else:
216 parser.print_help()