xref: /aosp_15_r20/external/tensorflow/tensorflow/python/debug/lib/profiling.py (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1# Copyright 2017 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"""Data structures and algorithms for profiling information."""
16
17import os
18
19
20class ProfileDatum(object):
21  """Profile data point."""
22
23  def __init__(self,
24               device_name,
25               node_exec_stats,
26               file_path,
27               line_number,
28               func_name,
29               op_type):
30    """Constructor.
31
32    Args:
33      device_name: (string) name of the device.
34      node_exec_stats: `NodeExecStats` proto.
35      file_path: path to the source file involved in creating the op.
36      line_number: line number in the file involved in creating the op.
37      func_name: name of the function that the line belongs to.
38      op_type: (string) Operation type.
39    """
40    self.device_name = device_name
41    self.node_exec_stats = node_exec_stats
42    self.file_path = file_path
43    self.line_number = line_number
44    self.func_name = func_name
45    if self.file_path:
46      self.file_line_func = "%s:%d(%s)" % (
47          os.path.basename(self.file_path), self.line_number, self.func_name)
48    else:
49      self.file_line_func = ""
50    self.op_type = op_type
51    self.start_time = self.node_exec_stats.all_start_micros
52    self.op_time = (self.node_exec_stats.op_end_rel_micros -
53                    self.node_exec_stats.op_start_rel_micros)
54
55  @property
56  def exec_time(self):
57    """Op execution time plus pre- and post-processing."""
58    return self.node_exec_stats.all_end_rel_micros
59
60
61class AggregateProfile(object):
62  """Profile summary data for aggregating a number of ProfileDatum."""
63
64  def __init__(self, profile_datum):
65    """Constructor.
66
67    Args:
68      profile_datum: (`ProfileDatum`) an instance of `ProfileDatum` to
69        initialize this object with.
70    """
71
72    self.total_op_time = profile_datum.op_time
73    self.total_exec_time = profile_datum.exec_time
74    device_and_node = "%s:%s" % (profile_datum.device_name,
75                                 profile_datum.node_exec_stats.node_name)
76    self._node_to_exec_count = {device_and_node: 1}
77
78  def add(self, profile_datum):
79    """Accumulate a new instance of ProfileDatum.
80
81    Args:
82      profile_datum: (`ProfileDatum`) an instance of `ProfileDatum` to
83        accumulate to this object.
84    """
85
86    self.total_op_time += profile_datum.op_time
87    self.total_exec_time += profile_datum.exec_time
88    device_and_node = "%s:%s" % (profile_datum.device_name,
89                                 profile_datum.node_exec_stats.node_name)
90
91    device_and_node = "%s:%s" % (profile_datum.device_name,
92                                 profile_datum.node_exec_stats.node_name)
93    if device_and_node in self._node_to_exec_count:
94      self._node_to_exec_count[device_and_node] += 1
95    else:
96      self._node_to_exec_count[device_and_node] = 1
97
98  @property
99  def node_count(self):
100    return len(self._node_to_exec_count)
101
102  @property
103  def node_exec_count(self):
104    return sum(self._node_to_exec_count.values())
105