mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-02-20 20:09:11 +00:00
cpustate: now generates a timeline csv as well as stats
This commit is contained in:
parent
4d3feeba64
commit
a85e45c6b0
@ -95,6 +95,11 @@ class CpuStatesProcessor(ResultProcessor):
|
||||
By default proportional values will be reported as percentages, if this
|
||||
flag is enabled, they will be reported as ratios instead.
|
||||
"""),
|
||||
Parameter('create_timeline', kind=bool, default=True,
|
||||
description="""
|
||||
Create a CSV with the timeline of core power states over the course of the run
|
||||
as well as the usual stats reports.
|
||||
"""),
|
||||
|
||||
]
|
||||
|
||||
@ -128,7 +133,11 @@ class CpuStatesProcessor(ResultProcessor):
|
||||
self.logger.debug('Text trace does not appear to have been generated; skipping this iteration.')
|
||||
return
|
||||
self.logger.debug('Generating power state reports from trace...')
|
||||
parallel_report, powerstate_report = report_power_stats(
|
||||
if self.create_timeline:
|
||||
timeline_csv_file = os.path.join(context.output_directory, 'power_states.csv')
|
||||
else:
|
||||
timeline_csv_file = None
|
||||
parallel_report, powerstate_report = report_power_stats( # pylint: disable=unbalanced-tuple-unpacking
|
||||
trace_file=trace.path,
|
||||
idle_state_names=self.idle_state_names,
|
||||
core_names=self.core_names,
|
||||
@ -137,6 +146,7 @@ class CpuStatesProcessor(ResultProcessor):
|
||||
first_cluster_state=self.first_cluster_state,
|
||||
first_system_state=self.first_system_state,
|
||||
use_ratios=self.use_ratios,
|
||||
timeline_csv_file=timeline_csv_file,
|
||||
)
|
||||
if parallel_report is None:
|
||||
self.logger.warning('No power state reports generated; are power '
|
||||
|
@ -285,6 +285,40 @@ def gather_core_states(system_state_stream, freq_dependent_idle_states=None): #
|
||||
yield (system_state.timestamp, core_states)
|
||||
|
||||
|
||||
class PowerStateTimeline(object):
|
||||
|
||||
def __init__(self, filepath, core_names, idle_state_names):
|
||||
self.filepath = filepath
|
||||
self.idle_state_names = idle_state_names
|
||||
self._wfh = open(filepath, 'w')
|
||||
self.writer = csv.writer(self._wfh)
|
||||
if core_names:
|
||||
headers = ['ts'] + ['{} CPU{}'.format(c, i)
|
||||
for i, c in enumerate(core_names)]
|
||||
self.writer.writerow(headers)
|
||||
|
||||
def update(self, timestamp, core_states): # NOQA
|
||||
row = [timestamp]
|
||||
for idle_state, frequency in core_states:
|
||||
if frequency is None:
|
||||
if idle_state is None or idle_state == -1:
|
||||
row.append(None)
|
||||
else:
|
||||
row.append(self.idle_state_names[idle_state])
|
||||
else: # frequency is not None
|
||||
if idle_state == -1:
|
||||
row.append(frequency)
|
||||
elif idle_state is None:
|
||||
row.append(None)
|
||||
else:
|
||||
row.append('{} ({})'.format(self.idle_state_names[idle_state],
|
||||
frequency))
|
||||
self.writer.writerow(row)
|
||||
|
||||
def report(self):
|
||||
self._wfh.close()
|
||||
|
||||
|
||||
class ParallelStats(object):
|
||||
|
||||
def __init__(self, core_clusters, use_ratios=False):
|
||||
@ -498,15 +532,21 @@ def build_idle_domains(core_clusters, # NOQA
|
||||
|
||||
def report_power_stats(trace_file, idle_state_names, core_names, core_clusters,
|
||||
num_idle_states, first_cluster_state=sys.maxint,
|
||||
first_system_state=sys.maxint, use_ratios=False):
|
||||
first_system_state=sys.maxint, use_ratios=False,
|
||||
timeline_csv_file=None):
|
||||
# pylint: disable=too-many-locals
|
||||
trace = TraceCmdTrace()
|
||||
ps_processor = PowerStateProcessor(core_clusters,
|
||||
num_idle_states=num_idle_states,
|
||||
first_cluster_state=first_cluster_state,
|
||||
first_system_state=first_system_state)
|
||||
parallel_stats = ParallelStats(core_clusters, use_ratios)
|
||||
power_state_stats = PowerStateStats(core_names, idle_state_names, use_ratios)
|
||||
reporters = [
|
||||
ParallelStats(core_clusters, use_ratios),
|
||||
PowerStateStats(core_names, idle_state_names, use_ratios)
|
||||
]
|
||||
if timeline_csv_file:
|
||||
reporters.append(PowerStateTimeline(timeline_csv_file,
|
||||
core_names, idle_state_names))
|
||||
|
||||
event_stream = trace.parse(trace_file, names=['cpu_idle', 'cpu_frequency'])
|
||||
transition_stream = stream_cpu_power_transitions(event_stream)
|
||||
@ -514,18 +554,20 @@ def report_power_stats(trace_file, idle_state_names, core_names, core_clusters,
|
||||
core_state_stream = gather_core_states(power_state_stream)
|
||||
|
||||
for timestamp, states in core_state_stream:
|
||||
parallel_stats.update(timestamp, states)
|
||||
power_state_stats.update(timestamp, states)
|
||||
for reporter in reporters:
|
||||
reporter.update(timestamp, states)
|
||||
|
||||
parallel_report = parallel_stats.report()
|
||||
ps_report = power_state_stats.report()
|
||||
|
||||
return (parallel_report, ps_report)
|
||||
reports = []
|
||||
for reporter in reporters:
|
||||
report = reporter.report()
|
||||
if report:
|
||||
reports.append(report)
|
||||
return reports
|
||||
|
||||
|
||||
def main():
|
||||
# pylint: disable=unbalanced-tuple-unpacking
|
||||
args = parse_arguments()
|
||||
|
||||
parallel_report, powerstate_report = report_power_stats(
|
||||
trace_file=args.infile,
|
||||
idle_state_names=args.idle_state_names,
|
||||
@ -535,6 +577,7 @@ def main():
|
||||
first_cluster_state=args.first_cluster_state,
|
||||
first_system_state=args.first_system_state,
|
||||
use_ratios=args.ratios,
|
||||
timeline_csv_file=args.timeline_file,
|
||||
)
|
||||
parallel_report.write(os.path.join(args.output_directory, 'parallel.csv'))
|
||||
powerstate_report.write(os.path.join(args.output_directory, 'cpustate.csv'))
|
||||
@ -576,7 +619,7 @@ def parse_arguments(): # NOQA
|
||||
core names on the assumption that all cores with the same name are on the
|
||||
same cluster.
|
||||
''')
|
||||
parser.add_argument('-i', '--idle-state-names', type=SplitListAction,
|
||||
parser.add_argument('-i', '--idle-state-names', action=SplitListAction,
|
||||
help='''
|
||||
Comma-separated list of idle state names. The number of names must match
|
||||
--num-idle-states if that was explicitly specified.
|
||||
@ -599,6 +642,11 @@ def parse_arguments(): # NOQA
|
||||
By default proportional values will be reported as percentages, if this
|
||||
flag is enabled, they will be reported as ratios instead.
|
||||
''')
|
||||
parser.add_argument('-t', '--timeline-file', metavar='FILE',
|
||||
help='''
|
||||
A timeline of core power states will be written to the specified file in
|
||||
CSV format.
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user