| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- import math
- from datetime import date
- NORMALFORMAT=0
- BYCFORMAT=1
- BYDFORMAT=2
- def joinit(iterable, delimiter):
- it = iter(iterable)
- yield next(it)
- for x in it:
- yield delimiter
- yield x
- # To format, in HTML, the cores in the right order.
- # First we order the categories
- # Then we order the cores in each category
- # The final ORDEREDCORES is what is used
- # to order tjhe values
- # Since some cores may be missing, each atble display
- # is computing a rstricted ordered core list with only the available cores.
- CORTEXCATEGORIES=["Cortex-M","Cortex-R","Cortex-A"]
- CORECATEGORIES={"Cortex-M":["m0","m4", "m7", "m33" , "m55 scalar", "m55 mve","m55 autovec"],
- "Cortex-R":["r8","r52"],
- "Cortex-A":["a32"]
- }
- ORDEREDCORES=[]
- for cat in CORTEXCATEGORIES:
- cores=[]
- if cat in CORECATEGORIES:
- for core in CORECATEGORIES[cat]:
- cores.append(core)
- else:
- print("Error core %s not found" % cat)
- quit()
- ORDEREDCORES += cores
- ORDEREDTYPES=["q7","q15","q31","u32","f16","f32","f64"]
- class Markdown:
- def __init__(self,output):
- self._id=0
- self._output = output
- def visitBarChart(self,data):
- pass
- def visitHistory(self,data):
- pass
- def visitText(self,text):
- self._output.write(text)
- # Write columns in markdown format
- def writeColumns(self,cols):
- colStr = "".join(joinit(cols,"|"))
- self._output.write("|")
- self._output.write(colStr)
- self._output.write("|\n")
- sepStr="".join(joinit([":-:" for x in cols],"|"))
- self._output.write("|")
- self._output.write(sepStr)
- self._output.write("|\n")
-
- # Write row in markdown format
- def writeRow(self,row):
- row=[str(x) for x in row]
- rowStr = "".join(joinit(row,"|"))
- self._output.write("|")
- self._output.write(rowStr)
- self._output.write("|\n")
- def visitTable(self,table):
- self.writeColumns(table.columns)
- for row in table.rows:
- self.writeRow(row)
- def visitSection(self,section):
- self._id = self._id + 1
- header = "".join(["#" for i in range(self._id)])
- self._output.write("%s %s\n" % (header,section.name))
- def leaveSection(self,section):
- self._id = self._id - 1
- def visitDocument(self,document):
- if document.runidHeader:
- self._output.write("Document generated for run ids : %s\n" % document.runidHeader)
- def leaveDocument(self,document):
- pass
- styleSheet="""
- <style type='text/css'>
- #TOC {
- position: fixed;
- left: 0;
- top: 0;
- width: 290px;
- height: 100%;
- overflow:auto;
- margin-top:5px;
- margin-bottom:10px;
- }
- html {
- font-size: 16px;
- }
- html, body {
- background-color: #E5ECEB;
- font-family: "Lato";
- font-style: normal; font-variant: normal;
- color: #002B49;
- line-height: 1.5em;
- }
- body {
- margin: auto;
- margin-top:0px;
- margin-left:290px;
- }
- .NA {
- color: #999999;
- }
- .testname {
- color: #0091BD;
- font-size: 1.125em;
- }
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- font-weight: bold;
- }
- h1 {
- font-size: 1.875em;
- margin-top:5px;
- }
- h2 {
- font-size: 1.3125em;
- }
- h3 {
- font-size: 1.3125em;
- margin-left:1em;
- }
- h4 {
- font-size: 1.125em;
- margin-left:1em;
- }
- h5,
- h6 {
- font-size: 1em;
- margin-left:1em;
- }
- #TOC h1 {
- margin-top:0em;
- margin-left:0.5em;
- }
- table {
- margin-bottom: 1.5em;
- font-size: 1em;
- width: 100%;
- border-collapse: collapse;
- border-spacing: 0;
- width: 100%;
- margin-left:1em;
- }
- thead th,
- tfoot th {
- padding: .25em .25em .25em .4em;
- text-transform: uppercase;
- }
- th {
- text-align: left;
- }
- td {
- vertical-align: top;
- padding: .25em .25em .25em .4em;
- }
- .ty-table-edit {
- background-color: transparent;
- }
- thead {
- background-color: #979ea3;
- }
- tr:nth-child(even) {
- background: #d7dadc;
- }
- ul, #myUL {
- list-style-type: none;
- padding-inline-start:10px;
- }
- /* Remove margins and padding from the parent ul */
- #myUL {
- margin: 0;
- padding: 0;
- }
- /* Style the caret/arrow */
- .caret {
- cursor: pointer;
- user-select: none; /* Prevent text selection */
- }
- /* Create the caret/arrow with a unicode, and style it */
- .caret::before {
- content: "\\25B6";
- color: black;
- display: inline-block;
- margin-right: 6px;
- }
- /* Rotate the caret/arrow icon when clicked on (using JavaScript) */
- .caret-down::before {
- transform: rotate(90deg);
- }
- /* Hide the nested list */
- .nested {
- display: none;
- }
- /* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */
- .active {
- display: block;
- }
- .firstcore {
- border-left-color: black;
- border-left-style: solid;
- border-left-width: 2px;
- }
- </style>
- """
- script="""<script type="text/javascript">
- var toggler = document.getElementsByClassName("caret");
- var i;
- for (i = 0; i < toggler.length; i++) {
- toggler[i].addEventListener("click", function() {
- this.parentElement.querySelector(".nested").classList.toggle("active");
- this.classList.toggle("caret-down");
- });
- }</script>"""
- barscript=""" <script src="https://d3js.org/d3.v5.js"></script>
- <script type="text/javascript">
- histwidth=400;
- histheight=200;
- histmargin={left:40,right:100,bottom:40,top:10};
- function legend(color,svg)
- {
- const g = svg
- .attr("transform", `translate(${histwidth},0)`)
- .attr("text-anchor", "end")
- .attr("font-family", "sans-serif")
- .attr("font-size", 9)
- .selectAll("g")
- .data(color.domain().slice().reverse())
- .join("g")
- .attr("transform", (d, i) => `translate(0,${i * 20})`);
- g.append("rect")
- .attr("x", -19)
- .attr("width", 19)
- .attr("height", 19)
- .attr("fill", color);
- g.append("text")
- .attr("x", -24)
- .attr("y", 9.5)
- .attr("dy", "0.35em")
- .text(d => d);
- }
-
- function myhist(data,theid)
- {
- var x,y,xAxis,yAxis,svg,color;
-
- color = d3.scaleOrdinal()
- .domain(data.series.map(d => d['name']))
- .range(["#FF6B00",
- "#FFC700",
- "#95D600",
- "#00C1DE",
- "#0091BD",
- "#002B49",
- "#333E48",
- "#7D868C",
- "#E5ECEB"]);
-
- svg = d3.select(theid).insert("svg")
- .attr("viewBox", [0, 0, histwidth, histheight]);
- sx = d3.scaleLinear()
- .domain(d3.extent(data.dates))
- .range([histmargin.left,histwidth - histmargin.right]);
- sy = d3.scaleLinear()
- .domain([0, d3.max(data.series, d => d3.max(d.values,q => q[1]))]).nice()
- .range([histheight - histmargin.bottom, histmargin.top]);
- xAxis = g => g
- .attr("transform", `translate(0,${histheight - histmargin.bottom})`)
- .call(d3.axisBottom(sx).tickValues(data.dates).ticks(histwidth / 80,"d").
- tickSizeOuter(0));
- svg.append("text")
- .attr("class", "x label")
- .attr("text-anchor", "end")
- .attr("x", histwidth/2.0)
- .attr("y", histheight - 6)
- .text("RUN ID");
- yAxis = g => g
- .attr("transform", `translate(${histmargin.left},0)`)
- .call(d3.axisLeft(sy))
- .call(g => g.select(".domain").remove());
- line = d3.line()
- .x(d => sx(data.dates[d[0]])
- )
- .y(d => sy(d[1]));
- svg.append("g")
- .call(xAxis);
- svg.append("g")
- .call(yAxis);
- const path = svg.append("g")
- .attr("fill", "none")
- .attr("stroke", "steelblue")
- .attr("stroke-width", 1.5)
- .attr("stroke-linejoin", "round")
- .attr("stroke-linecap", "round")
- .selectAll("path")
- .data(data.series)
- .join("path")
- .style("mix-blend-mode", "multiply")
- .attr("stroke", d => color(d.name))
- .attr("d", d => line(d.values));
- // Legend
-
- svg.append("g")
- .call(d => legend(color,d));
- //svg.call(hover, path);
- }
- function mybar(data,theid)
- {
- var width,height,margin,x,y,xAxis,yAxis,svg,color;
- width=400;
- height=100;
- margin={left:40,right:10,bottom:40,top:10};
-
- svg = d3.select(theid).insert("svg")
- .attr("viewBox", [0, 0, width, height]);;
- x = d3.scaleBand()
- .domain(d3.range(data.length))
- .range([margin.left, width - margin.right])
- .padding(0.1);
- y = d3.scaleLinear()
- .domain([0, d3.max(data, d => d.value)]).nice()
- .range([height - margin.bottom, margin.top]);
- xAxis = g => g
- .attr("transform", `translate(0,${height - margin.bottom})`)
- .call(d3.axisBottom(x).tickFormat(i => data[i].name).tickSizeOuter(0));
- yAxis = g => g
- .attr("transform", `translate(${margin.left},0)`)
- .call(d3.axisLeft(y).ticks(4, data.format))
- .call(g => g.select(".domain").remove())
- .call(g => g.append("text")
- .attr("x", -margin.left)
- .attr("y", 10)
- .attr("fill", "currentColor")
- .attr("text-anchor", "start")
- .text(data.y));
- color = "steelblue"
-
- svg.append("g")
- .attr("fill", color)
- .selectAll("rect")
- .data(data)
- .join("rect")
- .attr("x", (d, i) => x(i))
- .attr("y", d => y(d.value))
- .attr("height", d => y(0) - y(d.value))
- .attr("width", x.bandwidth());
- svg.append("g")
- .call(xAxis);
- svg.append("g")
- .call(yAxis);
- }
- </script>"""
- class HTMLToc:
- def __init__(self,output):
- self._id=0
- self._sectionID = 0
- self._output = output
-
- def visitTable(self,table):
- pass
- def visitBarChart(self,data):
- pass
- def visitHistory(self,data):
- pass
- def visitText(self,text):
- pass
- def visitSection(self,section):
- self._id = self._id + 1
- self._sectionID = self._sectionID + 1
- if section.hasChildren:
- self._output.write("<li><span class=\"caret\"><a href=\"#section%d\">%s</a></span>\n" % (self._sectionID,section.name))
- self._output.write("<ul class=\"nested\">\n")
- else:
- self._output.write("<li><span><a href=\"#section%d\">%s</a></span>\n" % (self._sectionID,section.name))
- def leaveSection(self,section):
- if section.hasChildren:
- self._output.write("</ul></li>\n")
- self._id = self._id - 1
- def visitDocument(self,document):
- self._output.write("<div id=\"TOC\"><h1>Table of content</h1><ul id=\"myUL\">\n")
- def leaveDocument(self,document):
- self._output.write("</ul></div>%s\n" % script)
- def permutation(ordered,unordered,mode):
- result=[]
- restricted=[]
- order = ORDEREDCORES
- if mode == BYDFORMAT:
- order = ORDEREDTYPES
- for c in order:
- if c in unordered:
- restricted.append(c)
- for c in unordered:
- result.append(restricted.index(c))
- return(result,restricted)
- def reorder(p,v):
- result=[0 for x in v]
- for val,i in zip(v,p):
- result[i]=val
- return(result)
- class HTML:
- def __init__(self,output,regMode,ratio,reorder):
- self._id=0
- self._sectionID = 0
- self._barID = 0
- self._histID = 0
- self._output = output
- self._regMode = regMode
- self._reorder = reorder
- self._ratioMode = ratio and regMode
- def visitBarChart(self,bar):
- data=bar.data
- datastr = "".join(joinit(["{name:'%s',value:%s}" % x for x in data],","))
- #print(datastr)
- self._output.write("<p id=\"g%d\"></p>\n" % self._barID)
- self._output.write("""<script type="text/javascript">
- thedata%d=[%s];
- mybar(thedata%d,"#g%d");
- </script>""" % (self._barID,datastr,self._barID,self._barID))
- self._barID = self._barID + 1
- def _getIndex(self,runids,data):
- return([[runids.index(x[0]),x[1]] for x in data])
- def visitHistory(self,hist):
- data=hist.data
- runidstr = "".join(joinit([str(x) for x in hist.runids],","))
- serieelems=[]
- for core in data:
- serieelems.append("{name: '%s',values: %s}" % (core,self._getIndex(hist.runids,data[core])))
- seriestr = "".join(joinit(serieelems,","))
- datastr="""{
- series: [%s],
- dates: [%s]
- };""" %(seriestr,runidstr);
- #print(datastr)
- self._output.write("<p id=\"hi%d\"></p>\n" % self._histID)
- self._output.write("""<script type="text/javascript">
- thehdata%d=%s
- myhist(thehdata%d,"#hi%d");
- </script>""" % (self._histID,datastr,self._histID,self._histID))
- self._histID = self._histID + 1
- def visitText(self,text):
- self._output.write("<p>\n")
- self._output.write(text.text)
- self._output.write("</p>\n")
- def visitTable(self,table):
- self._output.write("<table>\n")
- self._output.write("<thead>\n")
- self._output.write("<tr>\n")
- firstCore = False
- for col in table.params:
- firstCore = True
- self._output.write("<th class=\"param\">")
- self._output.write(str(col))
- self._output.write("</th>\n")
- if self._reorder == NORMALFORMAT:
- perm,restricted=permutation(ORDEREDCORES,table.cores,self._reorder)
- elif self._reorder == BYDFORMAT:
- perm,restricted=permutation(ORDEREDTYPES,table.cores,self._reorder)
- else:
- restricted = table.cores
- for col in restricted:
- if firstCore:
- self._output.write("<th class=\"firstcore\">")
- else:
- self._output.write("<th class=\"core\">")
- self._output.write(str(col))
- self._output.write("</th>\n")
- firstCore = False
- self._output.write("</tr>\n")
- self._output.write("</thead>\n")
-
- nbParams = len(table.params)
- for row in table.rows:
- self._output.write("<tr>\n")
- i = 0
- row=list(row)
- #print(row)
- params=row[0:nbParams]
- values=row[nbParams:]
- if self._reorder == NORMALFORMAT:
- row = params + reorder(perm,values)
- elif self._reorder == BYDFORMAT:
- row = params + reorder(perm,values)
- else:
- row = params + values
- for elem in row:
- txt=str(elem)
- if txt == 'NA':
- txt = "<span class=\"NA\">" + txt + "</span>"
- if i < nbParams:
- self._output.write("<td class=\"param\">")
- self._output.write(txt)
- self._output.write("</td>\n")
- elif i == nbParams and nbParams != 0:
- self._output.write("<td class=\"firstcore\">")
- self._output.write(txt)
- self._output.write("</td>\n")
- else:
- self._output.write("<td class=\"core\">")
- self._output.write(txt)
- self._output.write("</td>\n")
- i = i + 1
- self._output.write("</tr>\n")
- self._output.write("</table>\n")
- def visitSection(self,section):
- self._id = self._id + 1
- self._sectionID = self._sectionID + 1
- name = section.name
- if section.isTest:
- name = "<span class=\"testname\">" + name + "</span>"
- self._output.write("<h%d id=\"section%d\">%s</h%d>\n" % (self._id,self._sectionID,name,self._id))
- def leaveSection(self,section):
- self._id = self._id - 1
- def visitDocument(self,document):
- self._output.write("""<!doctype html>
- <html>
- <head>
- <meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
- <title>Benchmarks</title>%s</head><body>\n""" % styleSheet)
- if self._regMode and not self._ratioMode:
- self._output.write("<h1>ECPS Benchmark Regressions</h1>\n")
- elif self._ratioMode:
- self._output.write("<h1>ECPS Benchmark Ratios</h1>\n")
- else:
- self._output.write("<h1>ECPS Benchmark Summary</h1>\n")
-
- if document.runidHeader:
- self._output.write("<p>Document generated for run ids : %s</p>\n" % document.runidHeader)
- today = date.today()
- d2 = today.strftime("%B %d, %Y")
- self._output.write("<p>Document generated on %s</p>\n" % d2)
- self._output.write(barscript)
- def leaveDocument(self,document):
- document.accept(HTMLToc(self._output))
- self._output.write("</body></html>\n")
|