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 17This is primarily used by generate_examples.py. See it or 18`make_report_table` for more details on usage. 19""" 20from __future__ import absolute_import 21from __future__ import division 22from __future__ import print_function 23 24import cgi 25import json 26 27FAILED = "FAILED" 28SUCCESS = "SUCCESS" 29NOTRUN = "NOTRUN" 30 31 32def 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> 59body { font-family: Arial; } 60th { background-color: #555555; color: #eeeeee; } 61td { vertical-align: top; } 62td.horiz {width: 50%;} 63pre { white-space: pre-wrap; word-break: keep-all; } 64table {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(""" 72function ShowLog(row, col) { 73 74var log = document.getElementById("log"); 75log.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