16e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# SPDX-License-Identifier: Apache-2.0 26e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# 36e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# Copyright (C) 2017, ARM Limited, Google, and contributors. 46e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# 56e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# Licensed under the Apache License, Version 2.0 (the "License"); you may 66e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# not use this file except in compliance with the License. 76e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# You may obtain a copy of the License at 86e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# 96e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# http://www.apache.org/licenses/LICENSE-2.0 106e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# 116e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# Unless required by applicable law or agreed to in writing, software 126e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 136e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# See the License for the specific language governing permissions and 156e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# limitations under the License. 166e3604a24925c2ca67f6cf4b3415c0d6c8b80e75Connor O'Brien# 17382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yangfrom trace import Trace 18382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yangimport pandas as pd 19382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yangimport matplotlib.pyplot as plt 20382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yangfrom analysis_module import AnalysisModule 21382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 22382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yangfrom devlib.utils.misc import memoized 23382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 24382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yangclass BinderTransactionAnalysis(AnalysisModule): 25382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 26382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang An analysis wrapper for visualizing binder transactions. 27382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 28382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang This class is currently used to plot transaction buffer 29382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang sizes and queuing delays. 30382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 31382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang to_micro_second = 1000000 32382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 33382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang def __init__(self, trace): 34382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 35382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Initialized by the directory that contains systrace output 36382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 37382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param trace: input Trace object 38382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type trace: :mod:`libs.utils.Trace` 39382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 40382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang super(BinderTransactionAnalysis, self).__init__(trace) 41382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 42382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang @memoized 43382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang def _dfg_alloc_df(self): 44382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 45382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Get a dataframe that captures the time spent in a transaction 46382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang allocation and the size of the buffer allocated sorted by time. 47382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 48382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Transaction and transaction_alloc_buf dataframes are joined 49382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang on transaction(debug_id) 50382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 51382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Example of df returned: 52382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang transaction (debug_id) | pid | delta_t | size 53382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 54382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_start = self._dfg_trace_event("binder_transaction") 55382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_start["start_time"] = df_start.index 56382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_end = self._dfg_trace_event("binder_transaction_alloc_buf") 57382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_end["end_time"] = df_end.index 58382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df = pd.merge(df_start, df_end, on="transaction") 59382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df = df[["transaction", "__comm_x", "__pid_x", 60382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang "start_time", "end_time", 61382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang "data_size", "offsets_size"]] 62382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df["delta_t"] = (df["end_time"] - df["start_time"]) \ 63382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang * BinderTransactionAnalysis.to_micro_second 64382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df["size"] = df["data_size"] - df["offsets_size"] 65382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df = df.loc[df["__comm_x"] == "binderThroughpu"] \ 66382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang [["transaction", "__pid_x", "delta_t", "size"]].sort("delta_t") 67382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang return df 68382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 69382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang @memoized 70382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang def _dfg_queue_df(self): 71382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 72382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Get a dataframe that captures start time, end time, 73382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang and the delta between when a transaction is issued and 74382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang when it is received by the target. 75382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 76382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Transaction and transaction_received dataframes are joined 77382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang on transaction(debug_id) 78382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 79382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Example df: 80382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang transaction (debug_id) | name | start | end | delta 81382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 82382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_send = self._dfg_trace_event("binder_transaction") 83382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_send["start_time"] = df_send.index 84382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 85382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_recv = self._dfg_trace_event("binder_transaction_received") 86382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_recv["end_time"] = df_recv.index 87382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 88382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df = pd.merge(df_send, df_recv, on="transaction") 89382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df = df[["transaction", "__comm_x", "start_time", "end_time"]] 90382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df["delta_t"] = (df["end_time"] - df["start_time"]) \ 91382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang * BinderTransactionAnalysis.to_micro_second 92382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang return df 93382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 94382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang def plot_samples(self, df, y_axis, xlabel, ylabel, 95382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ymin=0, ymax=None, x_axis="index"): 96382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 97382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Generate a plot that features the distribution of y_axis column 98382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang in the given dataframe. x_axis represents the sample points. 99382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 100382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param y_axis: column name of the dataframe we want to plot 101382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type y_axis: str 102382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 103382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param xlabel: label that appears on the plot's x-axis 104382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type xlabel: str 105382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 106382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param ylabel: label that appears on the plot's y-axis 107382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type ylabel: str 108382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 109382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_sorted = df.sort_values(by=y_axis, ascending=True) 110382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_sorted[x_axis] = range(len(df_sorted.index)) 111382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_sorted.plot(kind="scatter", x=x_axis, y=y_axis) 112382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax = plt.gca() 113382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax.set_xlabel(xlabel) 114382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax.set_ylabel(ylabel) 115382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax.set_ylim(ymin=ymin) 116382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang if ymax: 117382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax.set_ylim(ymax=ymax) 118382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang plt.show() 119382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 120382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang def plot_tasks(self, df, threshold, x_axis, y_axis, xlabel, ylabel): 121382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 122382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang Generate a plot that features the tasks whose y_axis column 123382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang in the dataframe is above a certain threshold. 124382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 125382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param x_axis: column name of the dataframe we want to group 126382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang together and use as the x-axis index in the plot 127382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type x_axis: str 128382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 129382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param y_axis: column name of the dataframe we want to plot 130382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type y_axis: str 131382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 132382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param xlabel: label that appears on the plot's x-axis 133382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type xlabel: str 134382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang 135382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :param ylabel: label that appears on the plot's y-axis 136382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang :type ylabel: str 137382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang """ 138382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_sorted = df.sort_values(by=y_axis, ascending=False) 139382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_top = df_sorted[df_sorted[y_axis] > threshold]\ 140382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang .groupby(x_axis).head(1) 141382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang df_top.plot(kind="bar", y=y_axis, x=x_axis) 142382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax = plt.gca() 143382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax.set_xlabel(xlabel) 144382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang ax.set_ylabel(ylabel) 145382239bcd68ea03d3c07ce99062282c28b39a142Sherry Yang plt.show() 146