1e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower/* Copyright 2016 The TensorFlow Authors All Rights Reserved.
2e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
3e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerLicensed under the Apache License, Version 2.0 (the "License");
4e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFloweryou may not use this file except in compliance with the License.
5e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerYou may obtain a copy of the License at
6e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
7e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    http://www.apache.org/licenses/LICENSE-2.0
8e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
9e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerUnless required by applicable law or agreed to in writing, software
10e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerdistributed under the License is distributed on an "AS IS" BASIS,
11e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerSee the License for the specific language governing permissions and
13e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerlimitations under the License.
14e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower==============================================================================*/
15e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
16af23ae65db2585f4a18d0bc5f21f15e94805aa4fA. Unique TensorFlower#include "tensorflow/core/profiler/internal/tfprof_show.h"
17e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
18e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower#include <memory>
19e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower#include <set>
20e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
21e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower#include "tensorflow/core/lib/strings/stringprintf.h"
22e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower#include "tensorflow/core/platform/env.h"
23e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower#include "tensorflow/core/platform/regexp.h"
24e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
25e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowernamespace tensorflow {
26e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowernamespace tfprof {
27e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
28a04353fda800b66c9f6fcb3d3699415db72fb792A. Unique TensorFlowerconst GraphNodeProto& TFShow::Show(const string& prefix, const Options& opts) {
29edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower  if (opts.output_type == kOutput[0]) {
30a7fff05e05693f806ae367eb59efb055844380e5A. Unique TensorFlower    Timeline timeline(opts.step, opts.output_options.at(kTimelineOpts[0]));
31a5b9ef0ec0e9a4f5c42157755ffd180a90063e2bA. Unique TensorFlower    return ShowInternal(opts, &timeline)->proto();
32a5b9ef0ec0e9a4f5c42157755ffd180a90063e2bA. Unique TensorFlower  } else {
33edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    const ShowNode* ret = ShowInternal(opts, nullptr);
34edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    if (opts.output_type == kOutput[1]) {
35a04353fda800b66c9f6fcb3d3699415db72fb792A. Unique TensorFlower      printf("%s", (prefix + ret->formatted_str).c_str());
36edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower      fflush(stdout);
37edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    } else if (opts.output_type == kOutput[2]) {
38edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower      Status s = WriteStringToFile(Env::Default(),
39edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower                                   opts.output_options.at(kFileOpts[0]),
40a04353fda800b66c9f6fcb3d3699415db72fb792A. Unique TensorFlower                                   prefix + ret->formatted_str);
41edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower      if (!s.ok()) {
42edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower        fprintf(stderr, "%s\n", s.ToString().c_str());
43edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower      }
44edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    } else if (opts.output_type == kOutput[3] ||
45edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower               opts.output_type == kOutput[4]) {
46edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    } else {
47edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower      fprintf(stderr, "Unknown output type: %s\n", opts.output_type.c_str());
48edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    }
49edac90c7c75b93ba149823257caf69ac9391c10bA. Unique TensorFlower    return ret->proto();
50e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
51e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}
52e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
53e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlowerbool TFShow::LookUpCheckPoint(const string& name,
54e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower                              std::unique_ptr<TFProfTensor>* tensor) {
55e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  if (name == kTFProfRoot || !ckpt_reader_ || !tensor) {
56e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    return false;
57e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
58e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  std::unique_ptr<Tensor> out_tensor;
59e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  TF_Status* status = TF_NewStatus();
60e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  ckpt_reader_->GetTensor(name, &out_tensor, status);
61e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  if (TF_GetCode(status) != TF_OK) {
62e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    fprintf(stderr, "%s\n", TF_Message(status));
63e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    TF_DeleteStatus(status);
64e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    return false;
65e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
66e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  tensor->reset(new TFProfTensor(std::move(out_tensor)));
67e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  TF_DeleteStatus(status);
68e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  return true;
69e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}
70e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
71c9e3617b4b018a19d83aa395aadb1e1f6017af9dA. Unique TensorFlowerbool TFShow::ShouldShow(const ShowNode* node, const Options& opts,
72c9e3617b4b018a19d83aa395aadb1e1f6017af9dA. Unique TensorFlower                        int depth) const {
73e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  // Always show kTFProfRoot.
74e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  if (node->name() == kTFProfRoot) return true;
75e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
7619c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (node->proto().total_requested_bytes() < opts.min_bytes ||
7719c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower      node->proto().total_peak_bytes() < opts.min_peak_bytes ||
7819c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower      node->proto().total_residual_bytes() < opts.min_residual_bytes ||
7919c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower      node->proto().total_output_bytes() < opts.min_output_bytes ||
8019c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower      node->proto().total_exec_micros() < opts.min_micros ||
8119c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower      node->proto().total_accelerator_exec_micros() <
8219c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower          opts.min_accelerator_micros ||
8319c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower      node->proto().total_cpu_exec_micros() < opts.min_cpu_micros ||
84e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      node->proto().parameters() < opts.min_params ||
85e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      node->proto().float_ops() < opts.min_float_ops ||
865af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower      node->proto().run_count() < opts.min_occurrence ||
87e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      depth > opts.max_depth || !ShouldShowIfExtra(node, opts, depth)) {
88e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    return false;
89e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
90e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
91e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  bool show = false;
92e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  if (opts.show_name_regexes.size() == 1 && opts.show_name_regexes[0] == ".*") {
93e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    show = true;
94e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  } else {
95e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    for (const string& regex : opts.show_name_regexes) {
96e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      if (RE2::FullMatch(node->name(), regex)) {
97e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower        show = true;
98e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower        break;
99e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      }
100e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    }
101e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
102e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  // Don't show if show_name_regexes don't cover it.
103e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  if (!show) return false;
104e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  // Don't show if hide_name_regexes cover it.
105e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  for (const string& regex : opts.hide_name_regexes) {
106e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    if (RE2::FullMatch(node->name(), regex)) return false;
107e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
108e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  return true;
109e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}
110e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
111c9e3617b4b018a19d83aa395aadb1e1f6017af9dA. Unique TensorFlowerbool TFShow::ShouldTrim(const ShowNode* node,
112c9e3617b4b018a19d83aa395aadb1e1f6017af9dA. Unique TensorFlower                        const std::vector<string>& regexes) const {
113e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  for (const string& regex : regexes) {
114e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    if (RE2::FullMatch(node->name(), regex)) {
115e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      return true;
116e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    }
117e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
118e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  return false;
119e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}
120e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
121a7fff05e05693f806ae367eb59efb055844380e5A. Unique TensorFlowerbool TFShow::ReAccount(ShowNode* node, const Options& opts) {
122a7fff05e05693f806ae367eb59efb055844380e5A. Unique TensorFlower  node->ReInit(opts.step);
123e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  if (opts.account_type_regexes.size() == 1 &&
124e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      opts.account_type_regexes[0] == ".*") {
125e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    return true;
126e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
127e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  for (const string& regex : opts.account_type_regexes) {
128e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    for (const string& type : node->node->op_types()) {
129e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      if (RE2::FullMatch(type, regex)) {
130e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower        return true;
131e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower      }
132e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower    }
133e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  }
134e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower  return false;
135e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}
136e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower
13719c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlowerstring TFShow::FormatNodeMemory(ShowNode* node, int64 bytes,
13819c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower                                int64 total_bytes) const {
13919c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  string memory = FormatMemory(total_bytes);
14019c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (node->account) {
14119c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    memory = FormatMemory(bytes) + "/" + memory;
14219c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  } else {
14319c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    memory = "--/" + memory;
14419c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
14519c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  return memory;
14619c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower}
14719c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower
148c9e3617b4b018a19d83aa395aadb1e1f6017af9dA. Unique TensorFlowerstring TFShow::FormatNode(ShowNode* node, const Options& opts) const {
14961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  std::vector<string> info;
15061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[2]) != opts.select.end()) {
15161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    const string shape = FormatShapes(node->node->shape());
15261a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    if (!shape.empty()) {
15361a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower      info.push_back(shape);
15461a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    }
15561a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    string params = FormatNumber(node->proto().total_parameters()) + " params";
15661a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    if (node->account) {
15761a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower      params = FormatNumber(node->proto().parameters()) + "/" + params;
15861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    } else {
15961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower      params = "--/" + params;
16061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    }
16161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    info.push_back(params);
16261a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
16361a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[3]) != opts.select.end()) {
16461a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    string fops = FormatNumber(node->proto().total_float_ops()) + " flops";
16561a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    if (node->account) {
16661a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower      fops = FormatNumber(node->proto().float_ops()) + "/" + fops;
16761a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    } else {
16861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower      fops = "--/" + fops;
16961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    }
17061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    info.push_back(fops);
17161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
17219c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  std::vector<string> attrs;
17361a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[0]) != opts.select.end()) {
17419c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    info.push_back(FormatNodeMemory(node, node->proto().requested_bytes(),
17519c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower                                    node->proto().total_requested_bytes()));
17619c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
17719c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (opts.select.find(kShown[11]) != opts.select.end()) {
17819c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    info.push_back(FormatNodeMemory(node, node->proto().peak_bytes(),
17919c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower                                    node->proto().total_peak_bytes()));
18019c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
18119c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (opts.select.find(kShown[12]) != opts.select.end()) {
18219c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    info.push_back(FormatNodeMemory(node, node->proto().residual_bytes(),
18319c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower                                    node->proto().total_residual_bytes()));
18419c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
18519c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (opts.select.find(kShown[13]) != opts.select.end()) {
18619c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    info.push_back(FormatNodeMemory(node, node->proto().output_bytes(),
18719c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower                                    node->proto().total_output_bytes()));
18861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
18961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[1]) != opts.select.end()) {
19006fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    info.push_back(FormatTotalExecTime(node, opts));
19106fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    info.push_back(FormatAcceleratorExecTime(node, opts));
19206fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    info.push_back(FormatCPUExecTime(node, opts));
19306fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  }
19406fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  if (opts.select.find(kShown[9]) != opts.select.end() &&
19506fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower      opts.select.find(kShown[1]) == opts.select.end()) {
19606fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    info.push_back(FormatAcceleratorExecTime(node, opts));
19706fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  }
19806fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  if (opts.select.find(kShown[10]) != opts.select.end() &&
19906fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower      opts.select.find(kShown[1]) == opts.select.end()) {
20006fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    info.push_back(FormatCPUExecTime(node, opts));
20161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
20261a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[5]) != opts.select.end()) {
20361a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    if (node->proto().devices_size() > 0) {
20461a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower      info.push_back(str_util::Join(node->proto().devices(), "|"));
20561a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    }
20661a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
20761a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[6]) != opts.select.end()) {
208ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower    const std::set<string>& op_types = node->node->op_types();
20961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    info.push_back(str_util::Join(op_types, "|"));
21061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
2115af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower  if (opts.select.find(kShown[7]) != opts.select.end()) {
2125af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    string run = FormatNumber(node->proto().total_run_count());
2135af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    if (node->account) {
2145af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower      run = FormatNumber(node->proto().run_count()) + "/" + run;
2155af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    } else {
2165af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower      run = "--/" + run;
2175af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    }
2185af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    string definition = FormatNumber(node->proto().total_definition_count());
2195af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    if (node->account) {
2205af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower      definition = "1/" + definition;
2215af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    } else {
2225af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower      definition = "--/" + definition;
2235af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    }
2245af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    info.push_back(run + "|" + definition);
2255af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower  }
226ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower  if (opts.select.find(kShown[8]) != opts.select.end()) {
227ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower    std::vector<string> shape_vec;
228ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower    for (const auto& s : node->node->input_shapes()) {
229ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower      if (s.second.empty()) {
230ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower        shape_vec.push_back(strings::Printf("%d:unknown", s.first));
231ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower      } else {
232ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower        shape_vec.push_back(strings::Printf(
233ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower            "%d:%s", s.first, str_util::Join(s.second, "x").c_str()));
234ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower      }
235ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower    }
236ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower    info.push_back(str_util::Join(shape_vec, "|"));
237ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower  }
23861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower
23961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  return strings::Printf("%s (%s)", node->name().c_str(),
24061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower                         str_util::Join(info, ", ").c_str());
24161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower}
24261a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower
243c9e3617b4b018a19d83aa395aadb1e1f6017af9dA. Unique TensorFlowerstring TFShow::FormatLegend(const Options& opts) const {
24461a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  std::vector<string> legends;
24561a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[2]) != opts.select.end()) {
24661a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    legends.push_back("# parameters");
24761a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
24861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[3]) != opts.select.end()) {
24961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    legends.push_back("# float_ops");
25061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
25161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[0]) != opts.select.end()) {
25219c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    legends.push_back("requested bytes");
25319c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
25419c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (opts.select.find(kShown[11]) != opts.select.end()) {
25519c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    legends.push_back("peak bytes");
25619c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
25719c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (opts.select.find(kShown[12]) != opts.select.end()) {
25819c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower    legends.push_back("residual bytes");
25919c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  }
26019c27ef0d52c20a12800005751d36f96bd948869A. Unique TensorFlower  if (opts.select.find(kShown[13]) != opts.select.end()) {
26161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    legends.push_back("output bytes");
26261a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
26361a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[1]) != opts.select.end()) {
26406fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    legends.push_back("total execution time");
26506fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    legends.push_back("accelerator execution time");
26606fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    legends.push_back("cpu execution time");
26706fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  }
26806fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  if (opts.select.find(kShown[9]) != opts.select.end() &&
26906fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower      opts.select.find(kShown[1]) == opts.select.end()) {
27006fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    legends.push_back("accelerator execution time");
27106fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  }
27206fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower  if (opts.select.find(kShown[10]) != opts.select.end() &&
27306fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower      opts.select.find(kShown[1]) == opts.select.end()) {
27406fc77c5e264813a9e2effddad8307bbf7efae43A. Unique TensorFlower    legends.push_back("cpu execution time");
27561a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
27661a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[5]) != opts.select.end()) {
27761a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    legends.push_back("assigned devices");
27861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
27961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  if (opts.select.find(kShown[6]) != opts.select.end()) {
28061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower    legends.push_back("op types");
28161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  }
2825af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower  if (opts.select.find(kShown[7]) != opts.select.end()) {
2835af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower    legends.push_back("op count (run|defined)");
2845af6b3e40161ead74390278053de81908bfd7674A. Unique TensorFlower  }
285ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower  if (opts.select.find(kShown[8]) != opts.select.end()) {
286ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower    legends.push_back("input shapes");
287ad03277a72e0d454e4408f9afed07c63c977115dA. Unique TensorFlower  }
28861a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower  return strings::Printf("node name | %s\n",
28961a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower                         str_util::Join(legends, " | ").c_str());
29061a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower}
29161a36c4383ffa6f0479875fe32cad5a2b9c74dddA. Unique TensorFlower
292e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}  // namespace tfprof
293e4a63b578f97c9dca26fd4d3a364f90a94cb45b5A. Unique TensorFlower}  // namespace tensorflow
294