• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2016 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 
16 #include "tensorflow/core/profiler/internal/print_model_analysis.h"
17 
18 #include <stdio.h>
19 #include <memory>
20 #include <utility>
21 
22 #include "tensorflow/c/checkpoint_reader.h"
23 #include "tensorflow/core/framework/graph.pb.h"
24 #include "tensorflow/core/lib/core/errors.h"
25 #include "tensorflow/core/profiler/internal/advisor/tfprof_advisor.h"
26 #include "tensorflow/core/profiler/internal/tfprof_stats.h"
27 #include "tensorflow/core/profiler/tfprof_log.pb.h"
28 #include "tensorflow/core/profiler/tfprof_options.h"
29 #include "tensorflow/core/profiler/tfprof_options.pb.h"
30 #include "tensorflow/core/profiler/tfprof_output.pb.h"
31 #include "tensorflow/core/protobuf/config.pb.h"
32 
33 namespace tensorflow {
34 namespace tfprof {
35 namespace {
36 TFStats* tf_stat = nullptr;
37 
RunProfile(const string & command,const string & options,TFStats * tf_stats)38 string RunProfile(const string& command, const string& options,
39                   TFStats* tf_stats) {
40   if (command == kCmds[4]) {
41     AdvisorOptionsProto option_pb;
42     if (!option_pb.ParseFromString(options)) {
43       fprintf(stderr, "Cannot parse AdvisorOptionsProto\n");
44       return "";
45     }
46     tf_stats->BuildAllViews();
47     return Advisor(tf_stats).Advise(option_pb).SerializeAsString();
48   } else {
49     tf_stats->BuildView(command);
50   }
51 
52   Options opts;
53   tensorflow::Status s = Options::FromProtoStr(options, &opts);
54   if (!s.ok()) {
55     fprintf(stderr, "%s\n", s.ToString().c_str());
56     return "";
57   }
58 
59   if (opts.output_type == kOutput[1]) {
60     printf("\n=========================Options=============================\n");
61     printf("%s", opts.ToString().c_str());
62     printf("\n==================Model Analysis Report======================\n");
63     string ret = "";
64     if (command == kCmds[2] || command == kCmds[3]) {
65       ret = tf_stats->ShowMultiGraphNode(command, opts).SerializeAsString();
66     } else if (command == kCmds[0] || command == kCmds[1]) {
67       ret = tf_stats->ShowGraphNode(command, opts).SerializeAsString();
68     } else {
69       fprintf(stderr, "Unknown command: %s\n", command.c_str());
70     }
71     printf("\n======================End of Report==========================\n");
72     fflush(stdout);
73     return ret;
74   }
75   if (command == kCmds[2] || command == kCmds[3]) {
76     return tf_stats->ShowMultiGraphNode(command, opts).SerializeAsString();
77   } else if (command == kCmds[0] || command == kCmds[1]) {
78     return tf_stats->ShowGraphNode(command, opts).SerializeAsString();
79   } else {
80     fprintf(stderr, "Unknown command: %s\n", command.c_str());
81     return "";
82   }
83 }
84 }  // namespace
85 
NewProfiler(const string * graph,const string * op_log)86 bool NewProfiler(const string* graph, const string* op_log) {
87   std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
88   if (graph && !graph->empty()) {
89     if (!graph_ptr->ParseFromString(*graph)) {
90       if (!protobuf::TextFormat::ParseFromString(*graph, graph_ptr.get())) {
91         fprintf(stderr, "Failed to parse graph\n");
92         return false;
93       }
94     }
95   }
96 
97   std::unique_ptr<OpLogProto> op_log_ptr;
98   if (op_log && !op_log->empty()) {
99     op_log_ptr.reset(new OpLogProto());
100     if (!op_log_ptr->ParseFromString(*op_log)) {
101       fprintf(stderr, "Failed to parse OpLogProto.\n");
102       return false;
103     }
104   }
105   tf_stat = new TFStats(std::move(graph_ptr), nullptr, std::move(op_log_ptr),
106                         nullptr);
107   return true;
108 }
109 
ProfilerFromFile(const string * filename)110 void ProfilerFromFile(const string* filename) {
111   CHECK(!tf_stat) << "Currently only 1 living tfprof profiler is allowed";
112   CHECK(filename) << "Missing profile filename to init profiler from file";
113   tf_stat = new TFStats(*filename, nullptr);
114 }
115 
DeleteProfiler()116 void DeleteProfiler() {
117   if (tf_stat) {
118     delete tf_stat;
119     tf_stat = nullptr;
120   }
121 }
122 
AddStep(int64 step,const string * graph,const string * run_meta,const string * op_log)123 double AddStep(int64 step, const string* graph, const string* run_meta,
124                const string* op_log) {
125   CHECK(tf_stat);
126 
127   if (graph && !graph->empty()) {
128     std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
129     if (!graph_ptr->ParseFromString(*graph)) {
130       if (!protobuf::TextFormat::ParseFromString(*graph, graph_ptr.get())) {
131         fprintf(stderr, "Failed to parse graph\n");
132       }
133     }
134     tf_stat->AddGraph(std::move(graph_ptr));
135   }
136 
137   CHECK(run_meta && !run_meta->empty());
138   // TODO(xpan): Better error handling.
139   std::unique_ptr<RunMetadata> run_meta_ptr(new RunMetadata());
140   run_meta_ptr->ParseFromString(*run_meta);
141   tf_stat->AddRunMeta(step, std::move(run_meta_ptr));
142 
143   if (op_log && !op_log->empty()) {
144     std::unique_ptr<OpLogProto> op_log_ptr;
145     op_log_ptr.reset(new OpLogProto());
146     op_log_ptr->ParseFromString(*op_log);
147     tf_stat->AddOpLogProto(std::move(op_log_ptr));
148   }
149   return tf_stat->run_coverage();
150 }
151 
Profile(const string * command,const string * options)152 string Profile(const string* command, const string* options) {
153   CHECK(tf_stat);
154   CHECK(command) << "command mustn't be null";
155   CHECK(options) << "options mustn't be null";
156   return RunProfile(*command, *options, tf_stat);
157 }
158 
SerializeToString()159 string SerializeToString() {
160   CHECK(tf_stat);
161   string content;
162   tf_stat->SerializeToString(&content);
163   return content;
164 }
165 
WriteProfile(const string * filename)166 void WriteProfile(const string* filename) {
167   CHECK(tf_stat);
168   CHECK(filename) << "empty file name when asking to write profile.";
169   tf_stat->WriteProfile(*filename);
170 }
171 
PrintModelAnalysis(const string * graph,const string * run_meta,const string * op_log,const string * command,const string * options)172 string PrintModelAnalysis(const string* graph, const string* run_meta,
173                           const string* op_log, const string* command,
174                           const string* options) {
175   CHECK(command) << "command mustn't be null";
176   CHECK(options) << "options mustn't be null";
177   std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
178   if (graph && !graph->empty()) {
179     graph_ptr->ParseFromString(*graph);
180   }
181 
182   std::unique_ptr<RunMetadata> run_meta_ptr;
183   if (run_meta && !run_meta->empty()) {
184     run_meta_ptr.reset(new RunMetadata());
185     run_meta_ptr->ParseFromString(*run_meta);
186   }
187 
188   std::unique_ptr<OpLogProto> op_log_ptr;
189   if (op_log && !op_log->empty()) {
190     op_log_ptr.reset(new OpLogProto());
191     op_log_ptr->ParseFromString(*op_log);
192   }
193 
194   // TODO(xpan): Maybe need to init the checkpoint reader?
195   std::unique_ptr<checkpoint::CheckpointReader> ckpt_reader;
196 
197   TFStats tf_stats(std::move(graph_ptr), std::move(run_meta_ptr),
198                    std::move(op_log_ptr), std::move(ckpt_reader));
199 
200   return RunProfile(*command, *options, &tf_stats);
201 }
202 
203 }  // namespace tfprof
204 }  // namespace tensorflow
205