aboutsummaryrefslogtreecommitdiff
path: root/crosperf/experiment_status.py
diff options
context:
space:
mode:
Diffstat (limited to 'crosperf/experiment_status.py')
-rw-r--r--crosperf/experiment_status.py290
1 files changed, 154 insertions, 136 deletions
diff --git a/crosperf/experiment_status.py b/crosperf/experiment_status.py
index 2ac47c74..fa6b1eec 100644
--- a/crosperf/experiment_status.py
+++ b/crosperf/experiment_status.py
@@ -1,12 +1,10 @@
# -*- coding: utf-8 -*-
-# Copyright 2011 The Chromium OS Authors. All rights reserved.
+# Copyright 2011 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""The class to show the banner."""
-from __future__ import division
-from __future__ import print_function
import collections
import datetime
@@ -14,136 +12,156 @@ import time
class ExperimentStatus(object):
- """The status class."""
-
- def __init__(self, experiment):
- self.experiment = experiment
- self.num_total = len(self.experiment.benchmark_runs)
- self.completed = 0
- self.new_job_start_time = time.time()
- self.log_level = experiment.log_level
-
- def _GetProgressBar(self, num_complete, num_total):
- ret = 'Done: %s%%' % int(100.0 * num_complete / num_total)
- bar_length = 50
- done_char = '>'
- undone_char = ' '
- num_complete_chars = bar_length * num_complete // num_total
- num_undone_chars = bar_length - num_complete_chars
- ret += ' [%s%s]' % (num_complete_chars * done_char,
- num_undone_chars * undone_char)
- return ret
-
- def GetProgressString(self):
- """Get the elapsed_time, ETA."""
- current_time = time.time()
- if self.experiment.start_time:
- elapsed_time = current_time - self.experiment.start_time
- else:
- elapsed_time = 0
- try:
- if self.completed != self.experiment.num_complete:
- self.completed = self.experiment.num_complete
- self.new_job_start_time = current_time
- time_completed_jobs = (
- elapsed_time - (current_time - self.new_job_start_time))
- # eta is calculated as:
- # ETA = (num_jobs_not_yet_started * estimated_time_per_job)
- # + time_left_for_current_job
- #
- # where
- # num_jobs_not_yet_started = (num_total - num_complete - 1)
- #
- # estimated_time_per_job = time_completed_jobs / num_run_complete
- #
- # time_left_for_current_job = estimated_time_per_job -
- # time_spent_so_far_on_current_job
- #
- # The biggest problem with this calculation is its assumption that
- # all jobs have roughly the same running time (blatantly false!).
- #
- # ETA can come out negative if the time spent on the current job is
- # greater than the estimated time per job (e.g. you're running the
- # first long job, after a series of short jobs). For now, if that
- # happens, we set the ETA to "Unknown."
- #
- eta_seconds = (
- float(self.num_total - self.experiment.num_complete - 1) *
- time_completed_jobs / self.experiment.num_run_complete +
- (time_completed_jobs / self.experiment.num_run_complete -
- (current_time - self.new_job_start_time)))
-
- eta_seconds = int(eta_seconds)
- if eta_seconds > 0:
- eta = datetime.timedelta(seconds=eta_seconds)
- else:
- eta = 'Unknown'
- except ZeroDivisionError:
- eta = 'Unknown'
- strings = []
- strings.append('Current time: %s Elapsed: %s ETA: %s' %
- (datetime.datetime.now(),
- datetime.timedelta(seconds=int(elapsed_time)), eta))
- strings.append(
- self._GetProgressBar(self.experiment.num_complete, self.num_total))
- return '\n'.join(strings)
-
- def GetStatusString(self):
- """Get the status string of all the benchmark_runs."""
- status_bins = collections.defaultdict(list)
- for benchmark_run in self.experiment.benchmark_runs:
- status_bins[benchmark_run.timeline.GetLastEvent()].append(benchmark_run)
-
- status_strings = []
- for key, val in status_bins.items():
- if key == 'RUNNING':
- get_description = self._GetNamesAndIterations
- else:
- get_description = self._GetCompactNamesAndIterations
- status_strings.append('%s: %s' % (key, get_description(val)))
-
- thread_status = ''
- thread_status_format = 'Thread Status: \n{}\n'
- if (self.experiment.schedv2() is None and
- self.experiment.log_level == 'verbose'):
- # Add the machine manager status.
- thread_status = thread_status_format.format(
- self.experiment.machine_manager.AsString())
- elif self.experiment.schedv2():
- # In schedv2 mode, we always print out thread status.
- thread_status = thread_status_format.format(
- self.experiment.schedv2().threads_status_as_string())
-
- result = '{}{}'.format(thread_status, '\n'.join(status_strings))
-
- return result
-
- def _GetNamesAndIterations(self, benchmark_runs):
- strings = []
- t = time.time()
- for benchmark_run in benchmark_runs:
- t_last = benchmark_run.timeline.GetLastEventTime()
- elapsed = str(datetime.timedelta(seconds=int(t - t_last)))
- strings.append("'{0}' {1}".format(benchmark_run.name, elapsed))
- return ' %s (%s)' % (len(strings), ', '.join(strings))
-
- def _GetCompactNamesAndIterations(self, benchmark_runs):
- grouped_benchmarks = collections.defaultdict(list)
- for benchmark_run in benchmark_runs:
- grouped_benchmarks[benchmark_run.label.name].append(benchmark_run)
-
- output_segs = []
- for label_name, label_runs in grouped_benchmarks.items():
- strings = []
- benchmark_iterations = collections.defaultdict(list)
- for benchmark_run in label_runs:
- assert benchmark_run.label.name == label_name
- benchmark_name = benchmark_run.benchmark.name
- benchmark_iterations[benchmark_name].append(benchmark_run.iteration)
- for key, val in benchmark_iterations.items():
- val.sort()
- iterations = ','.join(str(v) for v in val)
- strings.append('{} [{}]'.format(key, iterations))
- output_segs.append(' ' + label_name + ': ' + ', '.join(strings) + '\n')
-
- return ' %s \n%s' % (len(benchmark_runs), ''.join(output_segs))
+ """The status class."""
+
+ def __init__(self, experiment):
+ self.experiment = experiment
+ self.num_total = len(self.experiment.benchmark_runs)
+ self.completed = 0
+ self.new_job_start_time = time.time()
+ self.log_level = experiment.log_level
+
+ def _GetProgressBar(self, num_complete, num_total):
+ ret = "Done: %s%%" % int(100.0 * num_complete / num_total)
+ bar_length = 50
+ done_char = ">"
+ undone_char = " "
+ num_complete_chars = bar_length * num_complete // num_total
+ num_undone_chars = bar_length - num_complete_chars
+ ret += " [%s%s]" % (
+ num_complete_chars * done_char,
+ num_undone_chars * undone_char,
+ )
+ return ret
+
+ def GetProgressString(self):
+ """Get the elapsed_time, ETA."""
+ current_time = time.time()
+ if self.experiment.start_time:
+ elapsed_time = current_time - self.experiment.start_time
+ else:
+ elapsed_time = 0
+ try:
+ if self.completed != self.experiment.num_complete:
+ self.completed = self.experiment.num_complete
+ self.new_job_start_time = current_time
+ time_completed_jobs = elapsed_time - (
+ current_time - self.new_job_start_time
+ )
+ # eta is calculated as:
+ # ETA = (num_jobs_not_yet_started * estimated_time_per_job)
+ # + time_left_for_current_job
+ #
+ # where
+ # num_jobs_not_yet_started = (num_total - num_complete - 1)
+ #
+ # estimated_time_per_job = time_completed_jobs / num_run_complete
+ #
+ # time_left_for_current_job = estimated_time_per_job -
+ # time_spent_so_far_on_current_job
+ #
+ # The biggest problem with this calculation is its assumption that
+ # all jobs have roughly the same running time (blatantly false!).
+ #
+ # ETA can come out negative if the time spent on the current job is
+ # greater than the estimated time per job (e.g. you're running the
+ # first long job, after a series of short jobs). For now, if that
+ # happens, we set the ETA to "Unknown."
+ #
+ eta_seconds = float(
+ self.num_total - self.experiment.num_complete - 1
+ ) * time_completed_jobs / self.experiment.num_run_complete + (
+ time_completed_jobs / self.experiment.num_run_complete
+ - (current_time - self.new_job_start_time)
+ )
+
+ eta_seconds = int(eta_seconds)
+ if eta_seconds > 0:
+ eta = datetime.timedelta(seconds=eta_seconds)
+ else:
+ eta = "Unknown"
+ except ZeroDivisionError:
+ eta = "Unknown"
+ strings = []
+ strings.append(
+ "Current time: %s Elapsed: %s ETA: %s"
+ % (
+ datetime.datetime.now(),
+ datetime.timedelta(seconds=int(elapsed_time)),
+ eta,
+ )
+ )
+ strings.append(
+ self._GetProgressBar(self.experiment.num_complete, self.num_total)
+ )
+ return "\n".join(strings)
+
+ def GetStatusString(self):
+ """Get the status string of all the benchmark_runs."""
+ status_bins = collections.defaultdict(list)
+ for benchmark_run in self.experiment.benchmark_runs:
+ status_bins[benchmark_run.timeline.GetLastEvent()].append(
+ benchmark_run
+ )
+
+ status_strings = []
+ for key, val in status_bins.items():
+ if key == "RUNNING":
+ get_description = self._GetNamesAndIterations
+ else:
+ get_description = self._GetCompactNamesAndIterations
+ status_strings.append("%s: %s" % (key, get_description(val)))
+
+ thread_status = ""
+ thread_status_format = "Thread Status: \n{}\n"
+ if (
+ self.experiment.schedv2() is None
+ and self.experiment.log_level == "verbose"
+ ):
+ # Add the machine manager status.
+ thread_status = thread_status_format.format(
+ self.experiment.machine_manager.AsString()
+ )
+ elif self.experiment.schedv2():
+ # In schedv2 mode, we always print out thread status.
+ thread_status = thread_status_format.format(
+ self.experiment.schedv2().threads_status_as_string()
+ )
+
+ result = "{}{}".format(thread_status, "\n".join(status_strings))
+
+ return result
+
+ def _GetNamesAndIterations(self, benchmark_runs):
+ strings = []
+ t = time.time()
+ for benchmark_run in benchmark_runs:
+ t_last = benchmark_run.timeline.GetLastEventTime()
+ elapsed = str(datetime.timedelta(seconds=int(t - t_last)))
+ strings.append("'{0}' {1}".format(benchmark_run.name, elapsed))
+ return " %s (%s)" % (len(strings), ", ".join(strings))
+
+ def _GetCompactNamesAndIterations(self, benchmark_runs):
+ grouped_benchmarks = collections.defaultdict(list)
+ for benchmark_run in benchmark_runs:
+ grouped_benchmarks[benchmark_run.label.name].append(benchmark_run)
+
+ output_segs = []
+ for label_name, label_runs in grouped_benchmarks.items():
+ strings = []
+ benchmark_iterations = collections.defaultdict(list)
+ for benchmark_run in label_runs:
+ assert benchmark_run.label.name == label_name
+ benchmark_name = benchmark_run.benchmark.name
+ benchmark_iterations[benchmark_name].append(
+ benchmark_run.iteration
+ )
+ for key, val in benchmark_iterations.items():
+ val.sort()
+ iterations = ",".join(str(v) for v in val)
+ strings.append("{} [{}]".format(key, iterations))
+ output_segs.append(
+ " " + label_name + ": " + ", ".join(strings) + "\n"
+ )
+
+ return " %s \n%s" % (len(benchmark_runs), "".join(output_segs))