[mlpack-svn] r15601 - in mlpack/conf/jenkins-conf/benchmark: benchmark util

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Fri Aug 9 12:42:50 EDT 2013


Author: marcus
Date: Fri Aug  9 12:42:50 2013
New Revision: 15601

Log:
Add templates to create the reports and functions to generate the pages.

Added:
   mlpack/conf/jenkins-conf/benchmark/benchmark/make_reports.py
   mlpack/conf/jenkins-conf/benchmark/util/template.py

Added: mlpack/conf/jenkins-conf/benchmark/benchmark/make_reports.py
==============================================================================
--- (empty file)
+++ mlpack/conf/jenkins-conf/benchmark/benchmark/make_reports.py	Fri Aug  9 12:42:50 2013
@@ -0,0 +1,281 @@
+'''
+  @file make_reports.py
+  @author Marcus Edel
+
+  Functions to generate the reports.
+'''
+
+import os, sys, inspect
+
+# Import the util path, this method even works if the path contains
+# symlinks to modules.
+cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(
+  os.path.split(inspect.getfile(inspect.currentframe()))[0], '../util')))
+if cmd_subfolder not in sys.path:
+  sys.path.insert(0, cmd_subfolder)
+
+from graph import *
+from parser import *
+from log import *
+from database import *
+from template import *
+from misc import *
+
+import argparse
+import glob
+import re
+
+'''
+Create the top line chart.
+
+ at param db - The Database object.
+ at return The filename of the line chart.
+'''
+def CreateTopLineChart(db):
+  build, results = db.GetResultsSum("mlpack")
+
+  GenerateSingleLineChart(results, "reports/img/mlpack_top_" + str(build) + ".png")
+  return "img/mlpack_top_" + str(build) + ".png"
+
+'''
+Create the table with the timings.
+
+ at param data - Dictionary which contains the timing data.
+ at libraries - List which contains the library names.
+ at return HTML code which contains the header and the timing data.
+'''
+def CreateTimingTable(data, libraries):
+  # Create the table header.
+  header = ""
+  for library in libraries:
+    header += "<th>" + library + "</th>"
+
+  # Create the table timing content.
+  timingTable = ""
+  for dataset, timings in data.items():
+    timingTable += "<tr><td>" + dataset + "</td>"
+    for time in timings:
+
+      # Highlight the data with the best timing.
+      if min(timings) == time:
+        time = str(time) + "s" if isFloat(time) else time 
+        timingTable += '<td><p class="text-success"><strong>' + time + '</strong></p></td>'
+      else:
+        time = str(time) + "s" if isFloat(time) else time 
+        timingTable += "<td>" + time + "</td>"
+
+    timingTable += "</tr>"    
+
+  return (header, timingTable)
+
+'''
+Create the table with the datasets informations.
+
+ at results List of a List which contains the datasets informations.
+ at return HTML code which contains the dataset informations.
+'''
+def CreateDatasetTable(results):
+  datasets = []
+  datasetTable = ""
+
+  for result in results:
+    for data in result:
+      datasetName = data[8]
+
+      if datasetName not in datasets:
+       datasets.append(datasetName)
+
+       datasetTable += "<tr><td>" + datasetName + "</td>"
+       datasetTable += "<td>" + "{0:.5f}".format(data[9]) + " MB</td>"
+       datasetTable += "<td>" + str(data[10]) + "</td>"
+       datasetTable += "<td>" + str(data[11]) + "</td>"
+       datasetTable += "<td>" + str(data[12]) + "</td>"
+       datasetTable += "</tr>"
+
+  return datasetTable
+
+'''
+Create the method container with the informations from the database.
+
+ at param db - The database object.
+ at return HTML code which contains the information for the container.
+'''
+def MethodReports(db):
+  methodsPage = ""
+
+  # Get the latest builds.
+  libraryIds  = db.GetLibraryIds()
+  buildIds = []
+  for libraryid in libraryIds:
+    buildIds.append((db.GetLatestBuildFromLibary(libraryid[0]), libraryid[1]))  
+
+  # Iterate throw all methods and create for each method a new container.
+  for method in db.GetAllMethods():
+    methodResults = []
+    methodLibararies = []
+    for buildId in buildIds:
+      results = db.GetMethodResultsForLibary(buildId[0], method[0])
+
+      if results:        
+        methodLibararies.append(buildId[1])
+        methodResults.append(results)
+
+    if methodResults:
+      # Generate a "unique" name for the bar chart.
+      chartName = "img/bar_" + str(hash(str(method[1:]) + str(buildIds))) + ".png"
+
+      # Create the bar chart.
+      ChartInfo = GenerateBarChart(methodResults, methodLibararies, 
+          "reports/" + chartName)
+      numDatasets, totalTime, failure, timeouts, bestLibCount, timingData = ChartInfo
+
+      # Create the timing table.
+      header, timingTable = CreateTimingTable(timingData, methodLibararies)
+      datasetTable = CreateDatasetTable(methodResults)
+
+      # Create the container.
+      reportValues = {}
+      reportValues["methodName"] = str(method[1:][0])
+      reportValues["parameters"] = str(method[1:][1]) if method[1:][1] else "None"
+
+      # Calculate the percent for the progress bar.
+      negative = (((numDatasets - bestLibCount) / float(numDatasets)) * 100.0)
+      reportValues["progressPositive"] = "{0:.2f}".format(100 - negative) + "%"
+      reportValues["progressNegative"] = "{0:.2f}".format(negative) + "%"
+
+      reportValues["barChart"] = chartName
+      reportValues["numLibararies"] = str(len(methodLibararies))
+      reportValues["numDatasets"] = numDatasets
+      reportValues["totalTime"] = totalTime
+      reportValues["failure"] = failure
+      reportValues["timeouts"] = timeouts
+      reportValues["timingHeader"] = header
+      reportValues["timingTable"] = timingTable
+      reportValues["datasetTable"] = datasetTable
+
+      methodsPage += methodTemplate % reportValues
+
+  return methodsPage
+
+'''
+Search the highest index_number.html number.
+
+ at return The highest index_number.html number and the file count.
+'''
+def GetMaxIndex():
+  files = glob.glob("reports/index*.html")
+
+  maxId = 0
+  for f in files:
+    pattern = re.compile(br"""
+        .*?index_(?P<id>.*?).html
+        """, re.VERBOSE|re.MULTILINE|re.DOTALL)
+    
+    match = pattern.match(f)
+    if match:
+      i = int(match.group("id"))
+      if i > maxId:
+        maxId = i
+  return (maxId, len(files))
+
+'''
+Adjust the pagination for all index.html files.
+'''
+def AdjustPagination():
+  maxId, files = GetMaxIndex()
+
+  for i in range(1, files + 1):
+    with open("reports/index_" + str(i) + ".html", "r+") as fid:
+      content = fid.read()
+      pattern = '<ul class="pagination">'
+      pos = content.rfind(pattern)
+      content = content[:pos+len(pattern)]
+
+      if i == 1:
+        content += '<li><a href="index.html">&laquo;</a></li>\n'
+      else:
+        content += '<li><a href="index_' + str(i - 1) + '.html">&laquo;</a></li>\n'
+      
+      if i == maxId:
+        content += '<li><a href="#">&raquo;</a></li>'
+      else:
+        content += '<li><a href="index_' + str(i + 1) + '.html">&raquo;</a></li>\n'
+
+      content += paginationTemplate
+      fid.seek(0)
+      fid.write(content)
+      fid.truncate()  
+
+'''
+Get the pagination for the new index.html file.
+
+ at return The new pagination as HTML code.
+'''
+def NewPagination():
+  maxId, files = GetMaxIndex()
+
+  pagination = '<li><a href="#">&laquo;</a></li>\n'
+  if maxId > 0:
+    pagination += '<li><a href="index_1.html">&raquo;</a></li>\n'
+  else:    
+    pagination += '<li><a href="#">&raquo;</a></li>'
+
+  return pagination
+
+'''
+Rename the index_number.html files.
+'''
+def ShiftReports(): 
+  maxId, files = GetMaxIndex()
+  if maxId > 0 and os.path.isfile("reports/index.html"):
+    os.rename("reports/index.html", "reports/index_" + str(maxId + 1) + ".html")
+  elif files > 0 and os.path.isfile("reports/index.html"):
+    os.rename("reports/index.html", "reports/index_1.html")
+
+'''
+Create the new report.
+
+ at param configfile - Create the reports with the given configuration file.
+'''
+def Main(configfile):
+  # Reports settings.
+  database = "reports/benchmark.db"
+
+  # Read Config.
+  config = Parser(configfile, verbose=False)
+  streamData = config.StreamMerge()
+
+  # Read the general block and set the attributes.
+  if "general" in streamData:
+    for key, value in streamData["general"]:
+      if key == "database":
+        database = value
+
+  db = Database(database)
+
+  ShiftReports()
+  AdjustPagination()
+
+  # Get the values for the new index.html file.
+  reportValues = {}
+  reportValues["topLineChart"] = CreateTopLineChart(db)
+  reportValues["pagination"] = NewPagination()
+  reportValues["methods"] = MethodReports(db)
+
+  template = pageTemplate % reportValues
+
+  # Write the new index.html file.
+  with open("reports/index.html", 'w') as fid:
+    fid.write(template)
+
+if __name__ == '__main__':
+  parser = argparse.ArgumentParser(description="""Perform the benchmark with the
+      given config.""")
+  parser.add_argument('-c','--config', help='Configuration file name.', 
+      required=True)
+
+  args = parser.parse_args()
+
+  if args:
+    Main(args.config)
+  
\ No newline at end of file

Added: mlpack/conf/jenkins-conf/benchmark/util/template.py
==============================================================================
--- (empty file)
+++ mlpack/conf/jenkins-conf/benchmark/util/template.py	Fri Aug  9 12:42:50 2013
@@ -0,0 +1,150 @@
+'''
+  @file template.py
+  @author Marcus Edel
+
+  This file contains the page templates.
+'''
+
+pageTemplate = """
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="description" content="">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <title></title>
+        <link rel="stylesheet" href="framework/bs3/css/bootstrap.min.css">
+        <link rel="stylesheet" href="framework/font/style.css">
+        <link rel="stylesheet" href="css/style.css">
+    </head>
+    <body>
+  <div class="container">
+    <div class="row">
+      <div class="col-lg-12">
+        <div class="text-center">
+          <h4>Benchmarks</h4>
+        </div>  
+
+        <!-- Container Start -->
+        <div class="container--graph collapse-group well">
+          <div class="container__topContent">
+            <div>
+              <img class="center--image" src="%(topLineChart)s" alt="">
+            </div>          
+          </div>
+        </div>
+
+        %(methods)s
+
+        </div>
+      </div>
+    </div>
+    <div class="pagination--holder">
+      <ul class="pagination">
+        %(pagination)s
+      </ul>
+    </div>
+  </div>
+    <script src="framework/jquery/jquery.min.js"></script>
+    <script src="framework/bs3/js/bootstrap.min.js"></script>
+    <script src="js/slider.js"></script>
+    <!--[if lte IE 7]>
+      <script src="framework/font/lte-ie7.js"></script>
+    <![endif]-->      
+    </body>
+</html>
+"""
+
+paginationTemplate = """
+</ul>
+    </div>
+  </div>
+    <script src="framework/jquery/jquery.min.js"></script>
+    <script src="framework/bs3/js/bootstrap.min.js"></script>
+    <script src="js/slider.js"></script>
+    <!--[if lte IE 7]>
+      <script src="framework/font/lte-ie7.js"></script>
+    <![endif]-->      
+    </body>
+</html>
+"""
+
+methodTemplate = """
+        <!-- Container Start -->
+        <div class="container--graph collapse-group well">
+          <div class="container__topContent">
+            <p class="graph--name">%(methodName)s</p>
+            <div class="holder--progressBar">
+              <span class="progressBar__percentage">%(progressPositive)s</span>
+              <span class="progressBar__firstPart" style="width:%(progressPositive)s;"></span>
+              <span class="progressBar__secondPart" style="width:%(progressNegative)s;"></span>
+            </div>
+            <div class="btn-group">
+              <a href="#collapseOne" class="btn graphs btn-grey icon-bars js-button"></a>
+              <a href="#collapseTwo" class="btn info btn-grey icon-info js-button"></a>
+              <a href="#collapseThree" class="btn memory btn-grey icon-paragraph-right-2 js-button"></a>
+            </div>
+          </div>
+          <div id="collapseOne" class="container__bottomContent graph collapse">
+            <div>
+              <img class="center--image" src="%(barChart)s" alt="">
+            </div>
+            <div>
+              <table class="table table-striped">
+                <thead>
+                  <tr>
+                    <th></th>
+                    %(timingHeader)s
+                  </tr>
+                </thead>
+                <tbody>
+                  %(timingTable)s
+                </tbody>
+              </table>
+            </div>
+          </div>
+          <div id="collapseTwo" class="container__bottomContent infos collapse">
+            <div>
+              <table class="table table-striped">
+                <thead>
+                  <tr>
+                    <th></th>
+                    <th>Size</th>   
+                    <th>Number of Instances</th>
+                    <th>Number of Attributes</th>
+                    <th>Attribute Types</th>                                     
+                  </tr>
+                </thead>
+                <tbody>
+                  %(datasetTable)s
+                </tbody>
+              </table>
+            </div>
+          </div>
+
+          <div id="collapseTwo" class="container__bottomContent memories collapse">
+            <div>
+              <div class="panel">
+                <div class="panel-heading">Massif Log</div>
+                  <div class="row">
+                    
+                  </div>
+              </div>
+
+            </div>
+          </div>
+
+          <div class="container__bottomContent">&#160;</div>
+           <div class="row">
+            <div class="col-lg-2">Libraries: %(numLibararies)s</div>
+            <div class="col-lg-2">Datasets: %(numDatasets)s</div>
+            <div class="col-lg-3">Total time: %(totalTime)s seconds</div>
+            <div class="col-lg-2">Script failure: %(failure)s</div>
+            <div class="col-lg-2">Timeouts failure: %(timeouts)s</div>          
+          </div>
+          <div class="row">
+            <div class="col-lg-10">Parameters: %(parameters)s</div>
+          </div>
+        </div>
+
+"""
\ No newline at end of file



More information about the mlpack-svn mailing list