1 /* Copyright 2019 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 #include "tensorflow/core/profiler/utils/xplane_builder.h"
16
17 #include <algorithm>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 #include "absl/container/flat_hash_map.h"
23 #include "absl/strings/string_view.h"
24 #include "absl/types/optional.h"
25 #include "tensorflow/core/platform/types.h"
26 #include "tensorflow/core/profiler/protobuf/xplane.pb.h"
27 #include "tensorflow/core/profiler/utils/math_utils.h"
28
29 namespace tensorflow {
30 namespace profiler {
31
XPlaneBuilder(XPlane * plane)32 XPlaneBuilder::XPlaneBuilder(XPlane* plane)
33 : XStatsBuilder<XPlane>(plane, this), plane_(plane) {
34 for (auto& id_and_metadata : *plane->mutable_event_metadata()) {
35 auto& metadata = id_and_metadata.second;
36 last_event_metadata_id_ =
37 std::max<int64_t>(last_event_metadata_id_, metadata.id());
38 if (!metadata.name().empty()) {
39 event_metadata_by_name_.try_emplace(metadata.name(), &metadata);
40 }
41 }
42 for (auto& id_and_metadata : *plane->mutable_stat_metadata()) {
43 auto& metadata = id_and_metadata.second;
44 last_stat_metadata_id_ =
45 std::max<int64_t>(last_stat_metadata_id_, metadata.id());
46 if (!metadata.name().empty()) {
47 stat_metadata_by_name_.try_emplace(metadata.name(), &metadata);
48 }
49 }
50 for (XLine& line : *plane->mutable_lines()) {
51 lines_by_id_.try_emplace(line.id(), &line);
52 }
53 }
54
GetOrCreateEventMetadata(int64_t metadata_id)55 XEventMetadata* XPlaneBuilder::GetOrCreateEventMetadata(int64_t metadata_id) {
56 XEventMetadata& metadata = (*plane_->mutable_event_metadata())[metadata_id];
57 metadata.set_id(metadata_id);
58 return &metadata;
59 }
60
CreateEventMetadata()61 XEventMetadata* XPlaneBuilder::CreateEventMetadata() {
62 return GetOrCreateEventMetadata(++last_event_metadata_id_);
63 }
64
GetOrCreateEventMetadata(absl::string_view name)65 XEventMetadata* XPlaneBuilder::GetOrCreateEventMetadata(
66 absl::string_view name) {
67 XEventMetadata*& metadata = event_metadata_by_name_[name];
68 if (metadata == nullptr) {
69 metadata = CreateEventMetadata();
70 metadata->set_name(std::string(name));
71 }
72 return metadata;
73 }
74
GetOrCreateEventMetadata(std::string && name)75 XEventMetadata* XPlaneBuilder::GetOrCreateEventMetadata(std::string&& name) {
76 XEventMetadata*& metadata = event_metadata_by_name_[name];
77 if (metadata == nullptr) {
78 metadata = CreateEventMetadata();
79 metadata->set_name(std::move(name));
80 }
81 return metadata;
82 }
83
GetOrCreateEventsMetadata(const std::vector<absl::string_view> & names)84 std::vector<XEventMetadata*> XPlaneBuilder::GetOrCreateEventsMetadata(
85 const std::vector<absl::string_view>& names) {
86 std::vector<XEventMetadata*> metadata;
87 metadata.reserve(names.size());
88 for (absl::string_view name : names) {
89 metadata.push_back(GetOrCreateEventMetadata(name));
90 }
91 return metadata;
92 }
93
GetEventMetadata(absl::string_view name) const94 XEventMetadata* XPlaneBuilder::GetEventMetadata(absl::string_view name) const {
95 auto result = event_metadata_by_name_.find(name);
96 if (result == event_metadata_by_name_.end()) return nullptr;
97 return result->second;
98 }
99
GetStatMetadata(absl::string_view name) const100 XStatMetadata* XPlaneBuilder::GetStatMetadata(absl::string_view name) const {
101 auto result = stat_metadata_by_name_.find(name);
102 if (result == stat_metadata_by_name_.end()) return nullptr;
103 return result->second;
104 }
105
GetOrCreateStatMetadata(int64_t metadata_id)106 XStatMetadata* XPlaneBuilder::GetOrCreateStatMetadata(int64_t metadata_id) {
107 XStatMetadata& metadata = (*plane_->mutable_stat_metadata())[metadata_id];
108 metadata.set_id(metadata_id);
109 return &metadata;
110 }
111
GetStatMetadata(int64_t metadata_id) const112 const XStatMetadata* XPlaneBuilder::GetStatMetadata(int64_t metadata_id) const {
113 auto result = plane_->stat_metadata().find(metadata_id);
114 if (result == plane_->stat_metadata().end()) return nullptr;
115 return &(result->second);
116 }
117
CreateStatMetadata()118 XStatMetadata* XPlaneBuilder::CreateStatMetadata() {
119 return GetOrCreateStatMetadata(++last_stat_metadata_id_);
120 }
121
GetOrCreateStatMetadata(absl::string_view name)122 XStatMetadata* XPlaneBuilder::GetOrCreateStatMetadata(absl::string_view name) {
123 XStatMetadata*& metadata = stat_metadata_by_name_[name];
124 if (metadata == nullptr) {
125 metadata = CreateStatMetadata();
126 metadata->set_name(std::string(name));
127 }
128 return metadata;
129 }
130
GetOrCreateStatMetadata(std::string && name)131 XStatMetadata* XPlaneBuilder::GetOrCreateStatMetadata(std::string&& name) {
132 XStatMetadata*& metadata = stat_metadata_by_name_[name];
133 if (metadata == nullptr) {
134 metadata = CreateStatMetadata();
135 metadata->set_name(std::move(name));
136 }
137 return metadata;
138 }
139
GetOrCreateLine(int64_t line_id)140 XLineBuilder XPlaneBuilder::GetOrCreateLine(int64_t line_id) {
141 XLine*& line = lines_by_id_[line_id];
142 if (line == nullptr) {
143 line = plane_->add_lines();
144 line->set_id(line_id);
145 }
146 return XLineBuilder(line, this);
147 }
148
AddEvent(const XEventMetadata & metadata)149 XEventBuilder XLineBuilder::AddEvent(const XEventMetadata& metadata) {
150 XEvent* event = line_->add_events();
151 event->set_metadata_id(metadata.id());
152 return XEventBuilder(line_, plane_, event);
153 }
154
AddEvent(const XEvent & event)155 XEventBuilder XLineBuilder::AddEvent(const XEvent& event) {
156 XEvent* new_event = line_->add_events();
157 *new_event = event;
158 return XEventBuilder(line_, plane_, new_event);
159 }
160
SetTimestampNsAndAdjustEventOffsets(int64_t timestamp_ns)161 void XLineBuilder::SetTimestampNsAndAdjustEventOffsets(int64_t timestamp_ns) {
162 int64_t offset_ps = NanoToPico(line_->timestamp_ns() - timestamp_ns);
163 line_->set_timestamp_ns(timestamp_ns);
164 if (offset_ps) {
165 for (auto& event : *line_->mutable_events()) {
166 event.set_offset_ps(event.offset_ps() + offset_ps);
167 }
168 }
169 }
170
171 } // namespace profiler
172 } // namespace tensorflow
173