[LNT] r292658 - LNT graph New Setting options to use mean as aggregation function

A Bergen via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 20 14:01:05 PST 2017


Author: sudofortune
Date: Fri Jan 20 16:01:04 2017
New Revision: 292658

URL: http://llvm.org/viewvc/llvm-project?rev=292658&view=rev
Log:
LNT graph New Setting options to use mean as aggregation function

Added a new settings option in LNT graph to use the mean instead of min/max as the aggregation function.
Added that this setting persists for the duration of the session.
Added simple test cases

Differential Revision: https://reviews.llvm.org/D27494

Added:
    lnt/trunk/tests/server/ui/statsTester.py
Modified:
    lnt/trunk/lnt/server/ui/templates/v4_graph.html
    lnt/trunk/lnt/server/ui/views.py
    lnt/trunk/lnt/util/stats.py
    lnt/trunk/tests/server/ui/V4Pages.py

Modified: lnt/trunk/lnt/server/ui/templates/v4_graph.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/v4_graph.html?rev=292658&r1=292657&r2=292658&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/v4_graph.html (original)
+++ lnt/trunk/lnt/server/ui/templates/v4_graph.html Fri Jan 20 16:01:04 2017
@@ -56,7 +56,7 @@ function init_graph() {
         },
       highlight : {
 {% if revision_range is not none %}
-        range: {{revision_range|tojson|safe}} 
+        range: {{revision_range|tojson|safe}}
 {% else %}
         enabled: false
 {% endif %}
@@ -73,7 +73,7 @@ function init_graph() {
   graph_options['grid']['markings'] = baseline_plots;
   var tmp_plots = update_graphplots(graph_plots);
   var main_plot = $.plot(graph, tmp_plots, graph_options);
-  
+
   // Add tooltips.
   graph.bind("plotclick", function (e, p, i) {
       update_tooltip(e, p, i, show_tooltip, tmp_plots);
@@ -112,7 +112,7 @@ function init_graph() {
       }));
   });
   bind_zoom_bar(main_plot);
-	
+
 }
 
 
@@ -157,6 +157,11 @@ function init_page() {
           <table class="table table-striped table-hover table-condensed">
             <tbody>
               <tr>
+                <td>Mean() as Aggregation</td>
+                <td><input type="checkbox" name="switch_min_mean" value="yes"
+                    {{ 'checked' if options.switch_min_mean else ""}}></td>
+              </tr>
+              <tr>
                 <td>Hide Line Plot:</td>
                 <td><input type="checkbox" name="hide_lineplot" value="yes"
                      {{ 'checked' if options.hide_lineplot else ""}}></td>
@@ -230,7 +235,7 @@ function init_page() {
           <input type="hidden" name="{{name}}" value="{{value}}">
           {% endif %}
           {% endfor %}
-            
+
           <input class="btn btn-primary" style="clear: left; width: 100%"
                  type="submit" name="submit" value="Update" />
           </form>
@@ -253,7 +258,7 @@ function init_page() {
             </div>
         </td>
     </tr>
-  
+
     <tr>
         <td colspan="2">
             <div id="overview" style="height:80px;margin-top:20px;margin-left:20px"></div>
@@ -261,7 +266,7 @@ function init_page() {
     </td>
 
 </table>
-  
+
   <h3>Legend</h3>
   <table class="table table-condensed table-hover table-striped">
     <tr>

Modified: lnt/trunk/lnt/server/ui/views.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/views.py?rev=292658&r1=292657&r2=292658&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/views.py (original)
+++ lnt/trunk/lnt/server/ui/views.py Fri Jan 20 16:01:04 2017
@@ -7,6 +7,7 @@ import copy
 import json
 
 import flask
+from flask import session
 from flask import abort
 from flask import current_app
 from flask import g
@@ -220,7 +221,7 @@ def v4_machine(id):
                            associated_runs=associated_runs)
     except NoResultFound as e:
         abort(404)
-        
+
 class V4RequestInfo(object):
     def __init__(self, run_id, only_html_body=True):
         self.db = request.get_db()
@@ -302,7 +303,7 @@ class V4RequestInfo(object):
         classes = {
             'table': 'table table-striped table-condensed table-hover'
         }
-        
+
         reports = lnt.server.reporting.runs.generate_run_report(
             self.run, baseurl=db_url_for('index', _external=True),
             only_html_body=only_html_body, result=None,
@@ -505,9 +506,25 @@ def v4_graph():
     from lnt.external.stats import stats as ext_stats
 
     ts = request.get_testsuite()
+    switch_min_mean_local = False
 
+    if 'switch_min_mean_session' not in session:
+        session['switch_min_mean_session'] = False
     # Parse the view options.
-    options = {}
+    options = {'min_mean_checkbox': 'min()'}
+    if 'submit' in request.args:  # user pressed a button
+        if 'switch_min_mean' in request.args:  # user checked mean() checkbox
+            session['switch_min_mean_session'] = options['switch_min_mean'] = \
+                bool(request.args.get('switch_min_mean'))
+            switch_min_mean_local = session['switch_min_mean_session']
+        else:  # mean() check box is not checked
+            session['switch_min_mean_session'] = options['switch_min_mean'] = \
+                bool(request.args.get('switch_min_mean'))
+            switch_min_mean_local = session['switch_min_mean_session']
+    else:  # new page was loaded by clicking link, not submit button
+        options['switch_min_mean'] = switch_min_mean_local = \
+            session['switch_min_mean_session']
+
     options['hide_lineplot'] = bool(request.args.get('hide_lineplot'))
     show_lineplot = not options['hide_lineplot']
     options['show_mad'] = show_mad = bool(request.args.get('show_mad'))
@@ -769,8 +786,12 @@ def v4_graph():
 
             values = [v*normalize_by for v in data]
             aggregation_fn = min
+
+            if switch_min_mean_local:
+                aggregation_fn = lnt.util.stats.agg_mean
             if field.bigger_is_better:
                 aggregation_fn = max
+
             agg_value, agg_index = \
                 aggregation_fn((value, index)
                                for (index, value) in enumerate(values))
@@ -780,7 +801,7 @@ def v4_graph():
             metadata["date"] = str(dates[agg_index])
             if runs:
                 metadata["runID"] = str(runs[agg_index])
-            
+
             if len(graph_datum) > 1:
                 # If there are more than one plot in the graph, also label the
                 # test name.
@@ -795,7 +816,7 @@ def v4_graph():
                     point_metadata = dict(metadata)
                     point_metadata["date"] = str(dates[i])
                     points_data.append((x, v, point_metadata))
-            
+
             # Add the standard deviation error bar, if requested.
             if show_stddev:
                 mean = stats.mean(values)
@@ -1234,7 +1255,7 @@ def health():
     if queue_length > 10:
         explode = True
         msg = "Queue too long."
-    
+
     import resource
     stats = resource.getrusage(resource.RUSAGE_SELF)
     mem = stats.ru_maxrss
@@ -1299,7 +1320,7 @@ def v4_matrix():
     for each dataset to add, there will be a "plot.n=.m.b.f" where m is machine
     ID, b is benchmark ID and f os field kind offset. "n" is used to unique
     the paramters, and is ignored.
-    
+
     """
     ts = request.get_testsuite()
     # Load the matrix request parameters.
@@ -1379,9 +1400,9 @@ def v4_matrix():
             limit = int(limit)
             if limit != -1:
                 q = q.limit(limit)
-            
+
         req.samples = defaultdict(list)
-        
+
         for s in q.all():
             req.samples[s[1]].append(s[0])
             all_orders.add(s[1])
@@ -1484,7 +1505,7 @@ def v4_matrix():
         show_mad = False
         show_all_samples = False
         show_sample_counts = False
-        
+
     return render_template("v4_matrix.html",
                            testsuite_name=g.testsuite_name,
                            associated_runs=data_parameters,

Modified: lnt/trunk/lnt/util/stats.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/util/stats.py?rev=292658&r1=292657&r2=292658&view=diff
==============================================================================
--- lnt/trunk/lnt/util/stats.py (original)
+++ lnt/trunk/lnt/util/stats.py Fri Jan 20 16:01:04 2017
@@ -25,6 +25,23 @@ def mean(l):
     else:
         return None
 
+def agg_mean(pairs):
+    """Aggregation function in views.py receives input via enumerate and
+       produces a tuple.
+       Input: (value, index)
+       Output: (mean, 0), or (None, None) on invalid input.
+    """
+    if not pairs:
+        return (None, None)
+    my_sum = 0.0
+    counter = 0
+    for item in pairs:
+        my_sum += item[0]
+        counter += 1
+    if counter > 0:
+        return (my_sum / counter, 0)
+    return (None, None)
+
 
 def median(l):
     if not l:

Modified: lnt/trunk/tests/server/ui/V4Pages.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/V4Pages.py?rev=292658&r1=292657&r2=292658&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/V4Pages.py (original)
+++ lnt/trunk/tests/server/ui/V4Pages.py Fri Jan 20 16:01:04 2017
@@ -206,7 +206,7 @@ def main():
 
     # Fetch the index page.
     check_code(client, '/')
-    
+
     # Rules the index page.
     check_code(client, '/rules')
 
@@ -267,7 +267,7 @@ def main():
                expected_code=HTTP_NOT_FOUND)
     #  Check baselines work.
     check_code(client, '/v4/nts/graph?plot.0=1.3.2&baseline.60=3')
-    
+
     # Check some variations of the daily report work.
     check_code(client, '/v4/nts/daily_report/2012/4/12')
     check_code(client, '/v4/nts/daily_report/2012/4/11')
@@ -424,18 +424,21 @@ def main():
     # Check some variations of the daily report work.
     check_code(client, '/v4/compile/daily_report/2014/6/5?day_start=16')
     check_code(client, '/v4/compile/daily_report/2014/6/4')
-    
+
     check_redirect(client, '/v4/nts/regressions/new_from_graph/1/1/1/1', '/v4/nts/regressions/1')
     check_code(client, '/v4/nts/regressions/')
     check_code(client, '/v4/nts/regressions/?machine_filter=machine2')
     check_code(client, '/v4/nts/regressions/?machine_filter=machine0')
 
     check_code(client, '/v4/nts/regressions/1')
-    
+
     check_json(client, '/v4/nts/regressions/1?json=True')
-    
-    
 
+    # Make sure the new option does not break anything
+    check_code(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2&submit=Update')
+    check_json(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2&json=true&submit=Update')
+    check_code(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2')
+    check_json(client, '/db_default/v4/nts/graph?switch_min_mean=yes&plot.0=1.3.2&json=true')
 
 if __name__ == '__main__':
     main()

Added: lnt/trunk/tests/server/ui/statsTester.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/statsTester.py?rev=292658&view=auto
==============================================================================
--- lnt/trunk/tests/server/ui/statsTester.py (added)
+++ lnt/trunk/tests/server/ui/statsTester.py Fri Jan 20 16:01:04 2017
@@ -0,0 +1,55 @@
+#
+# create temporary instance
+# Cleanup temporary directory in case one remained from a previous run - also
+# see PR9904.
+# RUN: rm -rf %t.instance
+# RUN: python %{shared_inputs}/create_temp_instance.py \
+# RUN:   %s %{shared_inputs}/SmallInstance %t.instance \
+# RUN:   %S/Inputs/V4Pages_extra_records.sql
+#
+# RUN: python %s %t.instance
+
+import unittest
+
+import lnt.util.stats as stats
+
+INDEX = 0
+
+
+class TestLNTStatsTester(unittest.TestCase):
+
+    def loc_test_agg_mean(self, values):
+        if values is None:
+            return stats.agg_mean(None)
+        agg_value, agg_index = stats.agg_mean((value, index) for (index, value) in enumerate(values))
+        return (agg_value, agg_index)
+
+    def test_agg_mean(self):
+        test_list1 = [1, 2, 3, 4, 6]
+        self.assertEqual(self.loc_test_agg_mean(test_list1), (3.2, INDEX))
+        test_list2 = [1.0, 2.0, 3.0, 4.0]
+        self.assertEqual(self.loc_test_agg_mean(test_list2), (2.5, INDEX))
+        test_list3 = [1.0]
+        self.assertEqual(self.loc_test_agg_mean(test_list3), (1.0, INDEX))
+        self.assertEqual(self.loc_test_agg_mean([]), (None, None))
+        self.assertEqual(self.loc_test_agg_mean(None), (None, None))
+
+        # Test it exactly how it is called in views.py without indirection
+        agg_value, agg_index = stats.agg_mean((value, index) for (index, value) in enumerate(test_list1))
+        self.assertEqual((3.2, INDEX), (agg_value, agg_index))
+        agg_value, agg_index = stats.agg_mean((value, index) for (index, value) in enumerate(test_list2))
+        self.assertEqual((2.5, INDEX), (agg_value, agg_index))
+        agg_value, agg_index = stats.agg_mean((value, index) for (index, value) in enumerate(test_list3))
+        self.assertEqual((1.0, INDEX), (agg_value, agg_index))
+
+if __name__ == '__main__':
+    try:
+        unittest.main()
+    except AttributeError:
+        # Command line parameters are treaded as test cases, when \
+        # running with lit rather than python directly.
+        import sys
+        if len(sys.argv) != 2:
+            sys.exit("Something went horribly wrong. You need parameters.")
+        del sys.argv[1:]
+        unittest.main()




More information about the llvm-commits mailing list