Home | History | Annotate | Download | only in testing
      1 # Copyright 2017 The TensorFlow Authors. All Rights Reserved.
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 # ==============================================================================
     15 """Make HTML tables that report where TF and TOCO failed to convert models.
     16 
     17 This is primarily used by generate_examples.py. See it or
     18 `make_report_table` for more details on usage.
     19 """
     20 from __future__ import absolute_import
     21 from __future__ import division
     22 from __future__ import print_function
     23 
     24 import cgi
     25 import json
     26 
     27 FAILED = "FAILED"
     28 SUCCESS = "SUCCESS"
     29 NOTRUN = "NOTRUN"
     30 
     31 
     32 def make_report_table(fp, title, reports):
     33   """Make an HTML report of the success/failure reports.
     34 
     35   Args:
     36     fp: File-like object in which to put the html.
     37     title: "Title of the zip file this pertains to."
     38     reports: a list of conversion attempts. (report_args, report_vals) i.e.
     39       ({"shape": [1,2,3], "type": "tf.float32"},
     40        {"tf": "SUCCESS", "toco": "FAILURE", "toco_log": "Unsupported type.",
     41         "tf_log": ""})
     42   """
     43   # sort reports by if TOCO failure and then TF failure (reversed)
     44   reports.sort(key=lambda x: x[1]["toco"], reverse=False)
     45   reports.sort(key=lambda x: x[1]["tf"], reverse=True)
     46   def result_cell(x, row, col):
     47     """Produce a cell with the condition string `x`."""
     48     s = cgi.escape(repr(x), quote=True)
     49     color = "#44ff44" if x == SUCCESS else (
     50         "#ff4444" if x == FAILED else "#eeeeee")
     51     handler = "ShowLog(%d, %d)" % (row, col)
     52     fp.write("<td style='background-color: %s' onclick='%s'>%s</td>\n" % (
     53         color, handler, s))
     54 
     55   fp.write("""<html>
     56 <head>
     57 <title>tflite report</title>
     58 <style>
     59 body { font-family: Arial; }
     60 th { background-color: #555555; color: #eeeeee; }
     61 td { vertical-align: top; }
     62 td.horiz {width: 50%;}
     63 pre { white-space: pre-wrap; word-break: keep-all; }
     64 table {width: 100%;}
     65 </style>
     66 </head>
     67 """)
     68   # Write the log data to a javascript variable and also make a function
     69   # in javascript to show the log when an item is clicked.
     70   fp.write("<script> \n")
     71   fp.write("""
     72 function ShowLog(row, col) {
     73 
     74 var log = document.getElementById("log");
     75 log.innerHTML = "<pre>" + data[row][col]  + "</pre>";
     76 }
     77 """)
     78   fp.write("var data = \n")
     79   fp.write(json.dumps([[cgi.escape(x[1]["tf_log"], quote=True),
     80                         cgi.escape(x[1]["toco_log"], quote=True)]
     81                        for x in reports]))
     82   fp.write(";</script>\n")
     83 
     84   # Write the main table and use onclick on the items that have log items.
     85   fp.write("""
     86 <body>
     87 <h1>TOCO Conversion</h1>
     88 <h2>%s</h2>
     89 """ % title)
     90 
     91   # Get a list of keys that are in any of the records.
     92   param_keys = {}
     93   for params, _ in reports:
     94     for k in params.keys():
     95       param_keys[k] = True
     96 
     97   fp.write("<table>\n")
     98   fp.write("<tr><td class='horiz'>\n")
     99   fp.write("<div style='height:1000px; overflow:auto'>\n")
    100   fp.write("<table>\n")
    101   fp.write("<tr>\n")
    102   for p in param_keys:
    103     fp.write("<th>%s</th>\n" % cgi.escape(p, quote=True))
    104   fp.write("<th>TensorFlow</th>\n")
    105   fp.write("<th>TOCO</th>\n")
    106   fp.write("</tr>\n")
    107   for idx, (params, vals) in enumerate(reports):
    108     fp.write("<tr>\n")
    109     for p in param_keys:
    110       fp.write("  <td>%s</td>\n" % cgi.escape(repr(params[p]), quote=True))
    111 
    112     result_cell(vals["tf"], idx, 0)
    113     result_cell(vals["toco"], idx, 1)
    114     fp.write("</tr>\n")
    115   fp.write("</table>\n")
    116   fp.write("</div>\n")
    117   fp.write("</td>\n")
    118   fp.write("<td class='horiz' id='log'></td></tr>\n")
    119   fp.write("</table>\n")
    120   fp.write("<script>\n")
    121   fp.write("</script>\n")
    122   fp.write("""
    123     </body>
    124     </html>
    125     """)
    126