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