• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2020 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/convert/xplane_to_tools_data.h"
17 
18 #include <utility>
19 #include <vector>
20 
21 #include "absl/strings/str_format.h"
22 #include "absl/strings/string_view.h"
23 #include "tensorflow/core/platform/env.h"
24 #include "tensorflow/core/platform/logging.h"
25 #include "tensorflow/core/platform/protobuf.h"
26 #include "tensorflow/core/profiler/convert/op_stats_to_input_pipeline_analysis.h"
27 #include "tensorflow/core/profiler/convert/op_stats_to_overview_page.h"
28 #include "tensorflow/core/profiler/convert/op_stats_to_pod_viewer.h"
29 #include "tensorflow/core/profiler/convert/op_stats_to_tf_stats.h"
30 #include "tensorflow/core/profiler/convert/xplane_to_memory_profile.h"
31 #include "tensorflow/core/profiler/convert/xplane_to_op_stats.h"
32 #include "tensorflow/core/profiler/convert/xplane_to_tf_data_stats.h"
33 #include "tensorflow/core/profiler/convert/xplane_to_trace_events.h"
34 #include "tensorflow/core/profiler/protobuf/input_pipeline.pb.h"
35 #include "tensorflow/core/profiler/protobuf/kernel_stats.pb.h"
36 #include "tensorflow/core/profiler/protobuf/op_stats.pb.h"
37 #include "tensorflow/core/profiler/protobuf/overview_page.pb.h"
38 #include "tensorflow/core/profiler/protobuf/pod_viewer.pb.h"
39 #include "tensorflow/core/profiler/protobuf/tf_data_stats.pb.h"
40 #include "tensorflow/core/profiler/protobuf/tf_stats.pb.h"
41 #include "tensorflow/core/profiler/protobuf/xplane.pb.h"
42 #include "tensorflow/core/profiler/utils/xplane_schema.h"
43 #include "tensorflow/core/profiler/utils/xplane_utils.h"
44 
45 namespace tensorflow {
46 namespace profiler {
47 
48 namespace {
49 
ConvertXSpaceToTraceEvents(const std::vector<XSpace> & xspaces)50 std::pair<std::string, bool> ConvertXSpaceToTraceEvents(
51     const std::vector<XSpace>& xspaces) {
52   if (xspaces.size() != 1) {
53     LOG(WARNING) << "Trace events tool expects only 1 XSpace path but gets "
54                  << xspaces.size();
55     return std::make_pair("", false);
56   }
57 
58   std::string content;
59   ConvertXSpaceToTraceEventsString(xspaces[0], &content);
60   return std::make_pair(content, true);
61 }
62 
ConvertMultiXSpacesToOverviewPage(const std::vector<XSpace> & xspaces)63 std::pair<std::string, bool> ConvertMultiXSpacesToOverviewPage(
64     const std::vector<XSpace>& xspaces) {
65   OpStatsOptions options;
66   options.generate_kernel_stats_db = true;
67   options.generate_op_metrics_db = true;
68   options.generate_step_db = true;
69   OpStats combined_op_stats;
70   Status status = ConvertMultiXSpacesToCombinedOpStats(xspaces, options,
71                                                        &combined_op_stats);
72   if (!status.ok()) {
73     LOG(WARNING) << "Could not generate OpStats for overview page. Error: "
74                  << status.error_message();
75     return std::make_pair("", false);
76   }
77   // TODO(profiler): xspace should tell whether this is sampling mode.
78   return std::make_pair(
79       ConvertOpStatsToOverviewPage(combined_op_stats).SerializeAsString(),
80       true);
81 }
82 
ConvertMultiXSpacesToInputPipeline(const std::vector<XSpace> & xspaces)83 std::pair<std::string, bool> ConvertMultiXSpacesToInputPipeline(
84     const std::vector<XSpace>& xspaces) {
85   OpStatsOptions options;
86   options.generate_op_metrics_db = true;
87   options.generate_step_db = true;
88   OpStats combined_op_stats;
89   Status status = ConvertMultiXSpacesToCombinedOpStats(xspaces, options,
90                                                        &combined_op_stats);
91   if (!status.ok()) {
92     LOG(WARNING) << "Could not generate OpStats for input pipeline. Error: "
93                  << status.error_message();
94     return std::make_pair("", false);
95   }
96   return std::make_pair(ConvertOpStatsToInputPipelineAnalysis(combined_op_stats)
97                             .SerializeAsString(),
98                         true);
99 }
100 
ConvertMultiXSpacesToTfStats(const std::vector<XSpace> & xspaces)101 std::pair<std::string, bool> ConvertMultiXSpacesToTfStats(
102     const std::vector<XSpace>& xspaces) {
103   OpStatsOptions options;
104   options.generate_op_metrics_db = true;
105   options.generate_kernel_stats_db = true;
106   OpStats combined_op_stats;
107   Status status = ConvertMultiXSpacesToCombinedOpStats(xspaces, options,
108                                                        &combined_op_stats);
109   if (!status.ok()) {
110     LOG(WARNING) << "Could not generate OpStats for tensorflow stats. Error: "
111                  << status.error_message();
112     return std::make_pair("", false);
113   }
114   return std::make_pair(
115       ConvertOpStatsToTfStats(combined_op_stats).SerializeAsString(), true);
116 }
117 
ConvertMultiXSpacesToKernelStats(const std::vector<XSpace> & xspaces)118 std::pair<std::string, bool> ConvertMultiXSpacesToKernelStats(
119     const std::vector<XSpace>& xspaces) {
120   OpStatsOptions options;
121   options.generate_kernel_stats_db = true;
122   OpStats combined_op_stats;
123   Status status = ConvertMultiXSpacesToCombinedOpStats(xspaces, options,
124                                                        &combined_op_stats);
125   if (!status.ok()) {
126     LOG(WARNING) << "Could not generate OpStats for kernel stats. Error: "
127                  << status.error_message();
128     return std::make_pair("", false);
129   }
130   return std::make_pair(combined_op_stats.kernel_stats_db().SerializeAsString(),
131                         true);
132 }
133 
ConvertXSpaceToMemoryProfile(const std::vector<XSpace> & xspaces)134 std::pair<std::string, bool> ConvertXSpaceToMemoryProfile(
135     const std::vector<XSpace>& xspaces) {
136   if (xspaces.size() != 1) {
137     LOG(WARNING) << "Memory profile tool expects only 1 XSpace path but gets "
138                  << xspaces.size();
139     return std::make_pair("", false);
140   }
141   std::string json_output;
142   Status status;
143   status = ConvertXSpaceToMemoryProfileJson(xspaces[0], &json_output);
144   if (!status.ok()) {
145     LOG(WARNING) << "Could not generate memory profile. Error: "
146                  << status.error_message();
147     return std::make_pair("", false);
148   }
149   return std::make_pair(json_output, true);
150 }
151 
ConvertMultiXSpacesToPodViewer(const std::vector<XSpace> & xspaces)152 std::pair<std::string, bool> ConvertMultiXSpacesToPodViewer(
153     const std::vector<XSpace>& xspaces) {
154   OpStatsOptions options;
155   options.generate_op_metrics_db = true;
156   options.generate_step_db = true;
157   OpStats combined_op_stats;
158   Status status = ConvertMultiXSpacesToCombinedOpStats(xspaces, options,
159                                                        &combined_op_stats);
160   if (!status.ok()) {
161     LOG(WARNING) << "Could not generate OpStats for pod_viewer. Error: "
162                  << status.error_message();
163     return std::make_pair("", false);
164   }
165 
166   std::string json_output;
167   protobuf::util::JsonPrintOptions opts;
168   opts.always_print_primitive_fields = true;
169   auto encode_status = protobuf::util::MessageToJsonString(
170       ConvertOpStatsToPodViewer(combined_op_stats), &json_output, opts);
171   if (!encode_status.ok()) {
172     LOG(WARNING) << "Could not convert pod viewer proto to json. Error: "
173                  << encode_status.message();
174     return std::make_pair("", false);
175   }
176   return std::make_pair(json_output, true);
177 }
178 
ConvertMultiXSpacesToTfDataBottleneckAnalysis(const std::vector<XSpace> & xspaces,const std::vector<std::string> & filenames)179 std::pair<std::string, bool> ConvertMultiXSpacesToTfDataBottleneckAnalysis(
180     const std::vector<XSpace>& xspaces,
181     const std::vector<std::string>& filenames) {
182   CombinedTfDataStats combined_tf_data_stats;
183   CombinedTfDataStatsBuilder builder(&combined_tf_data_stats);
184 
185   std::vector<XSpace> mutable_xspaces = xspaces;
186 
187   for (int idx = 0; idx < mutable_xspaces.size(); ++idx) {
188     XPlane* host_plane =
189         FindMutablePlaneWithName(&mutable_xspaces[idx], kHostThreadsPlaneName);
190     if (host_plane == nullptr) {
191       LOG(WARNING) << "Could not find host XPlane for tf data stats: ";
192       return std::make_pair("", false);
193     }
194     absl::string_view host_name = mutable_xspaces[idx].hostnames_size()
195                                       ? mutable_xspaces[idx].hostnames(0)
196                                       : filenames[idx];
197     builder.Add(host_name, host_plane);
198   }
199   builder.Finalize();
200   return std::make_pair(combined_tf_data_stats.SerializeAsString(), true);
201 }
202 
203 }  // namespace
204 
ConvertMultiXSpacesToToolData(const std::vector<XSpace> & xspaces,const std::vector<std::string> & filenames,const absl::string_view tool_name)205 std::pair<std::string, bool> ConvertMultiXSpacesToToolData(
206     const std::vector<XSpace>& xspaces,
207     const std::vector<std::string>& filenames,
208     const absl::string_view tool_name) {
209   if (tool_name == "trace_viewer") {
210     return ConvertXSpaceToTraceEvents(xspaces);
211   } else if (tool_name == "overview_page") {
212     return ConvertMultiXSpacesToOverviewPage(xspaces);
213   } else if (tool_name == "input_pipeline_analyzer") {
214     return ConvertMultiXSpacesToInputPipeline(xspaces);
215   } else if (tool_name == "tensorflow_stats") {
216     return ConvertMultiXSpacesToTfStats(xspaces);
217   } else if (tool_name == "kernel_stats") {
218     return ConvertMultiXSpacesToKernelStats(xspaces);
219   } else if (tool_name == "memory_profile") {
220     return ConvertXSpaceToMemoryProfile(xspaces);
221   } else if (tool_name == "pod_viewer") {
222     return ConvertMultiXSpacesToPodViewer(xspaces);
223   } else if (tool_name == "tf_data_bottleneck_analysis") {
224     return ConvertMultiXSpacesToTfDataBottleneckAnalysis(xspaces, filenames);
225   } else {
226     LOG(WARNING) << "Can not find tool: " << tool_name << ". Please update to "
227                  << "the latest version of Tensorflow.";
228     return std::make_pair("", false);
229   }
230 }
231 
232 }  // namespace profiler
233 }  // namespace tensorflow
234