[LNT] r269653 - [profile] Document how to use and create profile data

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Mon May 16 06:38:00 PDT 2016


Author: jamesm
Date: Mon May 16 08:37:59 2016
New Revision: 269653

URL: http://llvm.org/viewvc/llvm-project?rev=269653&view=rev
Log:
[profile] Document how to use and create profile data

This document hopefully explains how to generate profile data either from the LNT client or without, how to upload that to the LNT server and how to create new adapters for different input profile formats.

It will no doubt need to be expanded when people notice all the implicit assumptions I've made that have escaped my tunnel vision.

Added:
    lnt/trunk/docs/profiles.rst
Modified:
    lnt/trunk/docs/contents.rst
    lnt/trunk/docs/importing_data.rst
    lnt/trunk/lnt/server/ui/static/docs/index.html
    lnt/trunk/lnt/testing/profile/profile.py
    lnt/trunk/lnt/testing/profile/profilev1impl.py
    lnt/trunk/lnt/testing/util/commands.py

Modified: lnt/trunk/docs/contents.rst
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/docs/contents.rst?rev=269653&r1=269652&r2=269653&view=diff
==============================================================================
--- lnt/trunk/docs/contents.rst (original)
+++ lnt/trunk/docs/contents.rst Mon May 16 08:37:59 2016
@@ -22,6 +22,8 @@ Contents
 
    developer_guide
 
+   profiles
+   
    todo
 
 Indices and tables
@@ -39,3 +41,4 @@ Module Listing
    :maxdepth: 2
 
    modules/testing
+   

Modified: lnt/trunk/docs/importing_data.rst
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/docs/importing_data.rst?rev=269653&r1=269652&r2=269653&view=diff
==============================================================================
--- lnt/trunk/docs/importing_data.rst (original)
+++ lnt/trunk/docs/importing_data.rst Mon May 16 08:37:59 2016
@@ -88,4 +88,5 @@ Make sure that:
      used to detect if between compiler versions, the generated code has
      changed.
    * ".compile": represents the compile time of the program.
-   All of these metrics are optional.
+
+ All of these metrics are optional.

Added: lnt/trunk/docs/profiles.rst
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/docs/profiles.rst?rev=269653&view=auto
==============================================================================
--- lnt/trunk/docs/profiles.rst (added)
+++ lnt/trunk/docs/profiles.rst Mon May 16 08:37:59 2016
@@ -0,0 +1,130 @@
+Performance profiles
+====================
+
+LNT has support for storing and displaying performance profiles. The intent of these profiles is to expose code generation differences between test samples and to allow easy identification of hot sections of code.
+
+Principles of profiles in LNT
+-----------------------------
+
+Profiles in LNT are represented in a custom format. The user interface operates purely on queries to this custom format. Adapters are written to convert from other formats to LNT's profile format. Profile data is uploaded as part of the normal JSON report to the LNT server.
+
+Producing profile data
+----------------------
+
+Profile generation can be driven directly through python API calls (for which ``lnt profile`` is a wrapper) or using the ``lnt runtests`` tool.
+
+Producing profile data via ``lnt runtests test-suite``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. note::
+
+   Profile collection via LNT is currently only supported on **Linux systems** as the only adapter that has currently been written uses Linux's ``perf`` infrastructure. When more adapters have been written, LNT can grow support for them.
+
+If your test system is already using ``lnt runtests`` to build and run tests, the simplest way to produce profiles is simply to add a single parameter::
+
+  --use-perf=all
+
+The ``--use-perf`` option specifies what to use Linux Perf for. The options are:
+
+* ``none``: Don't use ``perf`` for anything
+* ``time``: Use ``perf`` to measure compile and execution time. This can be much more accurate than ``time``.
+* ``profile``: Use ``perf`` for profiling only.
+* ``all``: Use ``perf`` for profiling and timing.
+
+The produced profiles live alongside each test executable, named ``$TEST.perf_data``. These profiles are processed and converted into LNT's profile format at the end of test execution and are inserted into the produced ``report.json``.
+
+Producing profile data without ``lnt runtests test-suite``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A supported usecase of LNT is to use the LNT server for performance tracking but to use a different test driver than ``lnt runtests`` to actually build, run and collect statistics for tests.
+
+The profiling data sits inside the JSON report submitted to LNT. This section will describe how to add profile data to an already-existing JSON report; See :ref:`importing_data` for details of the general structure of the JSON report.
+
+The first step is to produce the profile data itself in LNT format suitable for sending via JSON. To import a profile, use the ``lnt profile upgrade`` command::
+
+  lnt profile upgrade my_profile.perf_data /tmp/my_profile.lntprof
+
+``my_profile.perf_data`` is assumed here to be in Linux Perf format but can be any format for which an adapter is registered (this currently is only Linux Perf but it is expected that more will be added over time).
+
+``/tmp/my_profile.lntprof`` is now an LNT profile in a space-efficient binary form. To prepare it to be sent via JSON, we must base-64 encode it::
+
+  base64 -i /tmp/my_profile.lntprof -o /tmp/my_profile.txt
+
+Now we just need to add it to the report. Profiles look similar to hashes in that they are samples with string data::
+
+  {
+     "Machine": {
+       ...
+     },
+     "Run": {
+       ...
+     },
+     "Tests": [
+          {
+              "Data": [
+                  0.1056,
+                  0.1055
+              ],
+              "Info": {},
+              "Name": "nts.suite1/program1.exec"
+          },
+          {
+              "Data": [
+                  "eJxNj8EOgjAMhu99Cm9wULMOEHgBE888QdkASWCQFWJ8e1v04JIt+9f//7qmfkVoEj8yMXdzO70v/RJn2hJYrRQiveSWATdJvwe3jUtgecgh9Wsh9T6gyJvKUjm0kegK0mmt9UCjJUSgB5q8KsobUJOQ96dozr8tAbRApPbssOeCcm83ddoLC7ijMcA/RGUUwXt7iviPEDLJN92yh62LR7I8aBUMysgLnaKNFNzzMo8y7uGplQ4sa/j6rfn60WYaGdRhtT9fP5+JUW4="
+              ],
+              "Info": {},
+              "Name": "nts.suite2/program1.profile"
+          }
+      ]
+   }
+
+
+Supported formats
+-----------------
+
+Linux Perf
+~~~~~~~~~~
+
+Perf profiles are read directly from the binary ``perf.data`` file without using the ``perf`` wrapper tool or any Linux/GPL headers. This makes it runnable on non-Linux platforms although this is only really useful for debugging as the profiled binary / libraries are expected to be readable.
+
+The perf import code uses a C++ extension called cPerf that was written for the LNT project. It is less functional than ``perf annotate`` or ``perf report`` but produces much the same data in a machine readable form about 6x quicker. It is written in C++ because it is difficult to write readable Python that performs efficiently on binary data. Once the event stream has been aggregated, a python dictionary object is created and processing returns to Python. Speed is important at this stage because the profile import may be running on older or less powerful hardware and LLVM's test-suite contains several hundred tests that must be imported!
+
+.. note::
+
+   In recent versions of Perf a new subcommand exists: ``perf data``. This outputs the event trace in `CTF format <https://www.efficios.com/ctf>`_ which can then be queried using `babeltrace <http://diamon.org/babeltrace/>`_ and its Python bindings. This would allow to remove a lot of custom code in LNT as long as it is similarly performant.
+
+Adding support for a new profile format
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To create a new profile adapter, a new Python class must be created in the ``lnt.testing.profile`` package which subclasses the ``ProfileImpl`` class:
+
+.. autoclass:: lnt.testing.profile.profile.ProfileImpl
+   :members:
+
+Your subclass can either implement all functions as specified, or do what ``perf.py`` does which is only implement the ``checkFile()`` and ``deserialize()`` static functions. In this model inside ``deserialize()`` you would parse your profile data into a simple dictionary structure and create a ``ProfileV1Impl`` object from it. This is a really simple profile implementation that just works from a dictionary representation:
+
+.. automodule:: lnt.testing.profile.profilev1impl
+   :members:
+
+Viewing profiles
+----------------
+
+Once profiles are submitted to LNT, they are available either through a manual URL or through the "runs" page.
+
+On the run results page, "view profile" links should appear when table rows are hovered over if profile data is available.
+
+.. note::
+
+   It is known that this hover-over effect isn't touchscreen friendly and is perhaps unintuitive. This page should be modified soon to make the profile data link more obvious.
+
+Alternatively a profile can be viewed by manually constructing a URL::
+
+  db_default/v4/nts/profile/<test-id>/<run1-id>/<run2-id>
+
+Where:
+
+* ``test-id`` is the database TestID of the test to display
+* ``run1-id`` is the database RunID of the run to appear on the left of the display
+* ``run2-id`` is the database RunID of the run to appear on the right of the display
+
+Obviously, this URL is somewhat hard to construct, so using the links from the run page as above is recommended.

Modified: lnt/trunk/lnt/server/ui/static/docs/index.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/static/docs/index.html?rev=269653&r1=269652&r2=269653&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/static/docs/index.html (original)
+++ lnt/trunk/lnt/server/ui/static/docs/index.html Mon May 16 08:37:59 2016
@@ -1,12 +1,226 @@
 <!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8">
-        <title>Missing Docs</title>
-    </head>
-    <body>
-        <h1>Docs are missing</h1>
-        <p>LNT documentation must be installed using the makefile in /docs
-        inside the LNT source tree.  Until then, this page is displayed.</p>
-    </body>
-</html>
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>LNT — LNT 0.4.1dev documentation</title>
+    
+    <link rel="stylesheet" href="_static/basic.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/bootstrap-3.3.6/css/bootstrap.min.css" type="text/css" />
+    <link rel="stylesheet" href="_static/bootstrap-3.3.6/css/bootstrap-theme.min.css" type="text/css" />
+    <link rel="stylesheet" href="_static/bootstrap-sphinx.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    './',
+        VERSION:     '0.4.1dev',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <script type="text/javascript" src="_static/js/jquery-1.11.0.min.js"></script>
+    <script type="text/javascript" src="_static/js/jquery-fix.js"></script>
+    <script type="text/javascript" src="_static/bootstrap-3.3.6/js/bootstrap.min.js"></script>
+    <script type="text/javascript" src="_static/bootstrap-sphinx.js"></script>
+    <link rel="top" title="LNT 0.4.1dev documentation" href="contents.html" />
+<style type="text/css">
+  table.right { float: right; margin-left: 20px; }
+  table.right td { border: 1px solid #ccc; }
+</style>
+
+  </head>
+  <body role="document">
+
+  <div id="navbar" class="navbar navbar-inverse navbar-default navbar-fixed-top">
+    <div class="container">
+      <div class="navbar-header">
+        <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
+        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button>
+        <a class="navbar-brand" href="contents.html">
+          LNT</a>
+        <span class="navbar-text navbar-version pull-left"><b>0.4.1dev</b></span>
+      </div>
+
+        <div class="collapse navbar-collapse nav-collapse">
+          <ul class="nav navbar-nav">
+            
+                <li><a href="/">Back</a></li>
+            
+            
+              <li class="dropdown globaltoc-container">
+  <a role="button"
+     id="dLabelGlobalToc"
+     data-toggle="dropdown"
+     data-target="#"
+     href="contents.html">Sections <b class="caret"></b></a>
+  <ul class="dropdown-menu globaltoc"
+      role="menu"
+      aria-labelledby="dLabelGlobalToc"><ul>
+<li class="toctree-l1"><a class="reference internal" href="intro.html">Introduction</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="intro.html#installation">Installation</a></li>
+<li class="toctree-l2"><a class="reference internal" href="intro.html#development">Development</a></li>
+<li class="toctree-l2"><a class="reference internal" href="intro.html#architecture">Architecture</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="quickstart.html">Quickstart Guide</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="quickstart.html#installation">Installation</a></li>
+<li class="toctree-l2"><a class="reference internal" href="quickstart.html#running-tests">Running Tests</a></li>
+<li class="toctree-l2"><a class="reference internal" href="quickstart.html#viewing-results">Viewing Results</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="tools.html">The <code class="docutils literal"><span class="pre">lnt</span></code> Tool</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="tools.html#client-side-tools">Client-Side Tools</a></li>
+<li class="toctree-l2"><a class="reference internal" href="tools.html#server-side-tools">Server-Side Tools</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="tests.html">Test Producers</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="tests.html#running-a-local-server">Running a Local Server</a></li>
+<li class="toctree-l2"><a class="reference internal" href="tests.html#running-tests">Running Tests</a></li>
+<li class="toctree-l2"><a class="reference internal" href="tests.html#built-in-tests">Built-in Tests</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="changes.html">Changelog</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="changes.html#id1">0.4.1</a></li>
+<li class="toctree-l2"><a class="reference internal" href="changes.html#id2">0.4.0</a></li>
+<li class="toctree-l2"><a class="reference internal" href="changes.html#id3">0.3.0</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="concepts.html">Concepts</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="concepts.html#orders-machines-and-tests">Orders Machines and Tests</a></li>
+<li class="toctree-l2"><a class="reference internal" href="concepts.html#runs-and-samples">Runs and Samples</a></li>
+<li class="toctree-l2"><a class="reference internal" href="concepts.html#test-suites">Test Suites</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="importing_data.html">Importing Data from Other Test Systems</a></li>
+<li class="toctree-l1"><a class="reference internal" href="developer_guide.html">Developer Guide</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="developer_guide.html#installation">Installation</a></li>
+<li class="toctree-l2"><a class="reference internal" href="developer_guide.html#running-lnt-s-regression-tests">Running LNT’s Regression Tests</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="profiles.html">Performance profiles</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="profiles.html#principles-of-profiles-in-lnt">Principles of profiles in LNT</a></li>
+<li class="toctree-l2"><a class="reference internal" href="profiles.html#producing-profile-data">Producing profile data</a></li>
+<li class="toctree-l2"><a class="reference internal" href="profiles.html#supported-formats">Supported formats</a></li>
+<li class="toctree-l2"><a class="reference internal" href="profiles.html#viewing-profiles">Viewing profiles</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="todo.html">TODO</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="todo.html#major-features">Major Features</a></li>
+<li class="toctree-l2"><a class="reference internal" href="todo.html#minor-features">Minor Features</a></li>
+<li class="toctree-l2"><a class="reference internal" href="todo.html#v0-4-redesign">v0.4 Redesign</a></li>
+</ul>
+</li>
+</ul>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="modules/testing.html"><code class="docutils literal"><span class="pre">lnt.testing</span></code> – Test Data Creation</a></li>
+</ul>
+</ul>
+</li>
+              
+                <li class="dropdown">
+  <a role="button"
+     id="dLabelLocalToc"
+     data-toggle="dropdown"
+     data-target="#"
+     href="#">Page <b class="caret"></b></a>
+  <ul class="dropdown-menu localtoc"
+      role="menu"
+      aria-labelledby="dLabelLocalToc"></ul>
+</li>
+              
+            
+            
+              
+                
+              
+            
+            
+            
+            
+              <li class="hidden-sm"></li>
+            
+          </ul>
+
+          
+            
+<form class="navbar-form navbar-right" action="search.html" method="get">
+ <div class="form-group">
+  <input type="text" name="q" class="form-control" placeholder="Search" />
+ </div>
+  <input type="hidden" name="check_keywords" value="yes" />
+  <input type="hidden" name="area" value="default" />
+</form>
+          
+        </div>
+    </div>
+  </div>
+
+<div class="container">
+  <div class="row">
+    <div class="col-md-12 content">
+      
+<h1>LNT - LLVM Performance Tracking Software</h1>
+
+<p>
+  LNT is LLVM's performance tracking software. This is the web page for the LNT
+  software itself, the current online version of the server is available
+  at <a href="http://llvm.org/perf/">http://llvm.org/perf/</a>.
+</p>
+
+<h2>Documentation</h2>
+<table class="contentstable" align="center" style="margin-left: 30px">
+  <tr>
+    <td width="50%">
+      <p class="biglink"><a class="biglink" href="contents.html">
+          Contents</a><br/>
+        <span class="linkdescr">for a complete overview</span></p>
+      <p class="biglink"><a class="biglink" href="search.html">
+          Search page</a><br/>
+        <span class="linkdescr">search the documentation</span></p>
+    </td><td width="50%">
+      <p class="biglink"><a class="biglink" href="genindex.html">
+          General Index</a><br/>
+        <span class="linkdescr">all functions, classes, terms</span></p>
+      <p class="biglink"><a class="biglink" href="modindex.html">
+          Module Index</a><br/>
+        <span class="linkdescr">quick access to all documented modules</span></p>
+  </td></tr>
+</table>
+
+<h2>Source</h2>
+<p>LNT is available in the LLVM SVN repository:
+  <tt>svn co
+    <a href="http://llvm.org/svn/llvm-project/lnt/trunk">
+      http://llvm.org/svn/llvm-project/lnt/trunk</a></tt>.</p>
+
+
+    </div>
+      
+  </div>
+</div>
+<footer class="footer">
+  <div class="container">
+    <p class="pull-right">
+      <a href="#">Back to top</a>
+      
+    </p>
+    <p>
+        © Copyright 2016, Daniel Dunbar.<br/>
+      Last updated on 2016-05-16.<br/>
+      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.1.<br/>
+    </p>
+  </div>
+</footer>
+  </body>
+</html>
\ No newline at end of file

Modified: lnt/trunk/lnt/testing/profile/profile.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/testing/profile/profile.py?rev=269653&r1=269652&r2=269653&view=diff
==============================================================================
--- lnt/trunk/lnt/testing/profile/profile.py (original)
+++ lnt/trunk/lnt/testing/profile/profile.py Mon May 16 08:37:59 2016
@@ -188,7 +188,7 @@ class ProfileImpl(object):
     def getTopLevelCounters(self):
         """
         Return a dict containing the counters for the entire profile. These will
-        be absolute numbers: {'cycles': 5000.0} for example.
+        be absolute numbers: ``{'cycles': 5000.0}`` for example.
         """
         raise NotImplementedError("Abstract class")
 
@@ -196,8 +196,9 @@ class ProfileImpl(object):
         """
         Return the format for the disassembly strings returned by getCodeForFunction().
         Possible values are:
-          'raw'                   - No interpretation available - pure strings.
-          'marked-up-disassembly' - LLVM marked up disassembly format.
+
+        * ``raw``                   - No interpretation available - pure strings.
+        * ``marked-up-disassembly`` - LLVM marked up disassembly format.
         """
         raise NotImplementedError("Abstract class")
     
@@ -206,25 +207,27 @@ class ProfileImpl(object):
         Return a dict containing function names to information about that function.
 
         The information dict contains:
-          - 'counters' - counter values for the function.
-          - 'length' - number of times to call getCodeForFunction to obtain all
-                       instructions.
+
+        * ``counters`` - counter values for the function.
+        * ``length`` - number of times to call getCodeForFunction to obtain all instructions.
 
         The dict should *not* contain disassembly / function contents.
         The counter values must be percentages, not absolute numbers.
 
-        E.g. {'main': {'counters': {'cycles': 50.0, 'branch-misses': 0}, 'length': 200},
-              'dotest': {'counters': {'cycles': 50.0, 'branch-misses': 0}, 'length': 4}}
+        E.g.::
+
+          {'main': {'counters': {'cycles': 50.0, 'branch-misses': 0}, 'length': 200},
+           'dotest': {'counters': {'cycles': 50.0, 'branch-misses': 0}, 'length': 4}}
         """
         raise NotImplementedError("Abstract class")
 
     def getCodeForFunction(self, fname):
         """
-        Return a *generator* which will return, for every invocation, a three-tuple:
+        Return a *generator* which will return, for every invocation, a three-tuple::
 
           (counters, address, text)
 
-        Where counters is a dict : (e.g.) {'cycles': 50.0}, text is in the
+        Where counters is a dict : (e.g.) ``{'cycles': 50.0}``, text is in the
         format as returned by getDisassemblyFormat(), and address is an integer.
 
         The counter values must be percentages (of the function total), not

Modified: lnt/trunk/lnt/testing/profile/profilev1impl.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/testing/profile/profilev1impl.py?rev=269653&r1=269652&r2=269653&view=diff
==============================================================================
--- lnt/trunk/lnt/testing/profile/profilev1impl.py (original)
+++ lnt/trunk/lnt/testing/profile/profilev1impl.py Mon May 16 08:37:59 2016
@@ -7,23 +7,23 @@ ProfileV1 files not clever in any way. T
 the profile data layed out in the most obvious way for production/consumption
 that are then pickled and compressed.
 
-They are expected to be created by simply storing into the self.data member.
+They are expected to be created by simply storing into the ``self.data`` member.
 
-The self.data member has this format:
+The ``self.data`` member has this format::
 
-{
- counters: {'cycles': 12345.0, 'branch-misses': 200.0}, # Counter values are absolute.
- disassembly-format: 'raw',
- functions: {
-   name: {
-     counters: {'cycles': 45.0, ...}, # Note counters are now percentages.
-     data: [
-       [463464, {'cycles': 23.0, ...}, '\tadd r0, r0, r1'}],
-       ...
-     ]
-   }
+  {
+   counters: {'cycles': 12345.0, 'branch-misses': 200.0}, # Counter values are absolute.
+   disassembly-format: 'raw',
+   functions: {
+     name: {
+       counters: {'cycles': 45.0, ...}, # Note counters are now percentages.
+       data: [
+         [463464, {'cycles': 23.0, ...}, '\tadd r0, r0, r1'}],
+         ...
+       ]
+     }
+    }
   }
-}
     """
 
     def __init__(self, data):

Modified: lnt/trunk/lnt/testing/util/commands.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/testing/util/commands.py?rev=269653&r1=269652&r2=269653&view=diff
==============================================================================
--- lnt/trunk/lnt/testing/util/commands.py (original)
+++ lnt/trunk/lnt/testing/util/commands.py Mon May 16 08:37:59 2016
@@ -8,7 +8,12 @@ import os
 import sys
 import logging
 import time
-from flask import current_app
+try:
+    from flask import current_app
+except:
+    # We may be imported from Sphinx. Don't error if current_app isn't available here -
+    # instead error when it is used.
+    pass
 # FIXME: Find a better place for this code.
 
 LOGGER_NAME = "lnt.server.ui.app"




More information about the llvm-commits mailing list