import itertools
import logging
from abc import ABC
from typing import List, Dict
from common_func.info_conf_reader import InfoConfReader
from common_func.trace_view_header_constant import TraceViewHeaderConstant
from common_func.trace_view_manager import TraceViewManager
from msmodel.stars.low_power_model import LowPowerViewModel
from viewer.interface.base_viewer import BaseViewer
class LowPowerViewer(BaseViewer, ABC):
"""
class for get lowpower sample data
(1)Ddie有10个硬件数据:0-I2C_IMON回读;1-AVSBUS_BUS回读;2-AVSBUS_AIC回读;3-AIC结温;4-非AIC结温;5-MEM_DRAM_DIE结温;
6-软件DVFS下发的AIC频率(不使用,通过软件ch10上报);7-PPU上报的AIC平均频率;8-软件DVFS下发的BUS频率(不使用,
通过软件ch11上报);9-PPU上报的BUS平均频率;
6个软件数据:10-软件DVFS下发的AIC频率;11-软件DVFS下发的BUS频率;12-EDP降频POWERBRAKE计数;13-EDP降频IWARNING2计数;
14-EDP降频IWARNING1计数;15-EDP降频IWARNING0计数;
(2)Udie有9个硬件数据:0-Udie结温;1-PMBUS0的回读数据0;2-PMBUS0的回读数据1;3-PMBUS1的回读数据0;4-PMBUS1的回读数据1;
5-PMBUS2的回读数据0;6-PMBUS2的回读数据1;7-PMBUS3的回读数据0;8-PMBUS3的回读数据1;
"""
LOW_POWER_D_DIE_HARD = ['I2C_IMON', 'AVSBUS_BUS', 'AVSBUS_AIC', 'AIC_TEMP', 'Non-AIC_TEMP', 'MEM_DRAM_DIE_TEMP',
'USELESS_DVFS_AIC_Freq', 'PPU_AIC_AVG_Freq', 'USELESS_DVFS_BUS_Freq', 'PPU_BUS_AVG_Freq']
LOW_POWER_D_DIE_SOFT = ['DVFS_AIC_Freq', 'DVFS_BUS_Freq', 'EDP_POWERBRAKE', 'EDP_IWARNING2', 'EDP_IWARNING1',
'EDP_IWARNING0']
LOW_POWER_U_DIE_HARD = ['Udie_TEMP', 'PMBUS0_Data0', 'PMBUS0_Data1', 'PMBUS1_Data0', 'PMBUS1_Data1',
'PMBUS2_Data0', 'PMBUS2_Data1', 'PMBUS3_Data0', 'PMBUS3_Data1']
LOW_POWER_U_DIE_SOFT = []
D_DIE_ID_LIST = [0, 1]
U_DIE_ID_LIST = [2, 3]
DIE_ID_KEY = {
0: "die 0",
1: "die 1",
2: "die 2",
3: "die 3",
}
def __init__(self: any, configs: dict, params: dict) -> None:
super().__init__(configs, params)
self.model_list = {
'low_power': LowPowerViewModel
}
def get_trace_timeline(self: any, datas: list) -> list:
"""
format data to standard timeline format
:return: list
"""
timestamp_index = 0
die_id_index = 1
low_power_hard_index = 2
low_power_soft_index = 12
args_index = 4
pid = InfoConfReader().get_json_pid_data()
tid = InfoConfReader().get_json_tid_data()
meta_data = [['process_name', pid, tid, 'Low Power']]
result = TraceViewManager.metadata_event(meta_data)
event_dict = {}
for data in datas:
local_time = InfoConfReader().trans_into_local_time(raw_timestamp=data[timestamp_index])
die_id = data[die_id_index]
if die_id in self.D_DIE_ID_LIST:
lp_type_hard = self.LOW_POWER_D_DIE_HARD
lp_type_soft = self.LOW_POWER_D_DIE_SOFT
elif die_id in self.U_DIE_ID_LIST:
lp_type_hard = self.LOW_POWER_U_DIE_HARD
lp_type_soft = self.LOW_POWER_U_DIE_SOFT
else:
logging.error(f"Unexpected die id: {die_id}.")
continue
for key, value in itertools.chain(zip(lp_type_hard, data[low_power_hard_index:low_power_soft_index]),
zip(lp_type_soft, data[low_power_soft_index:])):
if key.startswith('USELESS'):
continue
tmp_key = "{}_{}".format(key, local_time)
if tmp_key not in event_dict:
event_dict[tmp_key] = [key, local_time, pid, tid, {self.DIE_ID_KEY.get(die_id): value}]
else:
event_dict.get(tmp_key)[args_index][self.DIE_ID_KEY.get(die_id)] = value
column_trace_data = list(event_dict.values())
result.extend(TraceViewManager.column_graph_trace(TraceViewHeaderConstant.COLUMN_GRAPH_HEAD_LEAST,
column_trace_data))
return result