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