diff options
author | Ahmad Sharif <asharif@chromium.org> | 2012-05-07 12:02:16 -0700 |
---|---|---|
committer | Ahmad Sharif <asharif@chromium.org> | 2012-05-07 12:02:16 -0700 |
commit | fd356fb31c4340851fecc750230d05c9518b125c (patch) | |
tree | 694f1a93f568d5e46655c30bb76cb71d7400f11b /crosperf | |
parent | 92ab7af223c82fe8897bacea8b32028828eab018 (diff) | |
download | toolchain-utils-fd356fb31c4340851fecc750230d05c9518b125c.tar.gz |
Synced repos to: 60208
Diffstat (limited to 'crosperf')
-rw-r--r-- | crosperf/autotest_runner.py | 3 | ||||
-rw-r--r-- | crosperf/benchmark_run.py | 94 | ||||
-rw-r--r-- | crosperf/experiment.py | 6 | ||||
-rw-r--r-- | crosperf/experiment_runner.py | 7 | ||||
-rw-r--r-- | crosperf/perf_processor.py | 68 | ||||
-rw-r--r-- | crosperf/results_cache.py | 21 |
6 files changed, 112 insertions, 87 deletions
diff --git a/crosperf/autotest_runner.py b/crosperf/autotest_runner.py index 5df71ac5..3b91d81b 100644 --- a/crosperf/autotest_runner.py +++ b/crosperf/autotest_runner.py @@ -1,9 +1,8 @@ #!/usr/bin/python - +# # Copyright 2011 Google Inc. All Rights Reserved. from utils import command_executer -from utils import utils class AutotestRunner(object): diff --git a/crosperf/benchmark_run.py b/crosperf/benchmark_run.py index b2822a4f..f7c37c3f 100644 --- a/crosperf/benchmark_run.py +++ b/crosperf/benchmark_run.py @@ -11,6 +11,10 @@ import traceback from results_cache import Result from utils import logger from utils import command_executer +from autotest_runner import AutotestRunner +from perf_processor import PerfProcessor +from results_cache import ResultsCache + STATUS_FAILED = "FAILED" STATUS_SUCCEEDED = "SUCCEEDED" @@ -24,7 +28,7 @@ class BenchmarkRun(threading.Thread): def __init__(self, name, benchmark_name, autotest_name, autotest_args, label_name, chromeos_root, chromeos_image, board, iteration, cache_conditions, outlier_range, profile_counters, profile_type, - machine_manager, cache, autotest_runner, perf_processor, + machine_manager, logger_to_use): threading.Thread.__init__(self) self.name = name @@ -37,6 +41,7 @@ class BenchmarkRun(threading.Thread): self.chromeos_image = os.path.expanduser(chromeos_image) self.board = board self.iteration = iteration + self.result = None self.results = {} self.terminated = False self.retval = None @@ -46,9 +51,9 @@ class BenchmarkRun(threading.Thread): self.profile_counters = profile_counters self.profile_type = profile_type self.machine_manager = machine_manager - self.cache = cache - self.autotest_runner = autotest_runner - self.perf_processor = perf_processor + self.cache = ResultsCache() + self.autotest_runner = AutotestRunner(self._logger) + self.perf_processor = None self.machine = None self.full_name = self.autotest_name self.cache_conditions = cache_conditions @@ -58,58 +63,26 @@ class BenchmarkRun(threading.Thread): self.failure_reason = "" self._ce = command_executer.GetCommandExecuter(self._logger) - def MeanExcludingOutliers(self, array, outlier_range): - """Return the arithmetic mean excluding outliers.""" - mean = sum(array) / len(array) - array2 = [] - - for v in array: - if mean != 0 and abs(v - mean) / mean < outlier_range: - array2.append(v) - - if array2: - return sum(array2) / len(array2) - else: - return mean - - def ParseResults(self, output): - p = re.compile("^-+.*?^-+", re.DOTALL | re.MULTILINE) - matches = p.findall(output) - for i in range(len(matches)): - results = matches[i] - results_dict = {} - for line in results.splitlines()[1:-1]: - mo = re.match("(.*\S)\s+\[\s+(PASSED|FAILED)\s+\]", line) - if mo: - results_dict[mo.group(1)] = mo.group(2) - continue - mo = re.match("(.*\S)\s+(.*)", line) - if mo: - results_dict[mo.group(1)] = mo.group(2) - - return results_dict - return {} - - def ProcessResults(self, result, cache_hit): + def ProcessResults(self): # Generate results from the output file. - results_dir = self._GetResultsDir(result.out) - self.full_name = os.path.basename(results_dir) - self.results = result.keyvals + self.full_name = os.path.basename(self.results_dir) + self.results = self.result.keyvals # Store the autotest output in the cache also. - if not cache_hit: - self.cache.StoreResult(result) - self.cache.StoreAutotestOutput(results_dir) - + if not self.cache_hit: + self.cache.StoreResult(self.result) + self.cache.StoreAutotestOutput(self.results_dir) + + self.perf_processor = PerfProcessor(self.results_dir, + self.chromeos_root, + self.board, + self._logger) # Generate a perf report and cache it. if self.profile_type: - if cache_hit: + if self.cache_hit: self.perf_results = self.cache.ReadPerfResults() else: - self.perf_results = (self.perf_processor. - GeneratePerfResults(results_dir, - self.chromeos_root, - self.board)) + self.perf_results = self.perf_processor.GeneratePerfResults() self.cache.StorePerfResults(self.perf_results) # If there are valid results from perf stat, combine them with the @@ -139,31 +112,32 @@ class BenchmarkRun(threading.Thread): self.cache_conditions, self._logger) - result = self.cache.ReadResult() - self.cache_hit = (result is not None) + self.result = self.cache.ReadResult() + self.cache_hit = (self.result is not None) - if result: + if self.result: self._logger.LogOutput("%s: Cache hit." % self.name) - self._logger.LogOutput(result.out + "\n" + result.err) + self._logger.LogOutput(self.result.out + "\n" + self.result.err) + self.results_dir = self._GetResultsDir(self.result.out) else: self._logger.LogOutput("%s: No cache hit." % self.name) self.status = STATUS_WAITING # Try to acquire a machine now. self.machine = self.AcquireMachine() self.cache.remote = self.machine.name - result = self.RunTest(self.machine) + self.result = self.RunTest(self.machine) if self.terminated: return - if not result.retval: + if not self.result.retval: self.status = STATUS_SUCCEEDED else: if self.status != STATUS_FAILED: self.status = STATUS_FAILED self.failure_reason = "Return value of autotest was non-zero." - self.ProcessResults(result, self.cache_hit) + self.ProcessResults() except Exception, e: self._logger.LogError("Benchmark run: '%s' failed: %s" % (self.name, e)) @@ -216,18 +190,18 @@ class BenchmarkRun(threading.Thread): self.run_completed = True # Include the keyvals in the result. - results_dir = self._GetResultsDir(out) - keyvals = self._GetKeyvals(results_dir) + self.results_dir = self._GetResultsDir(out) + keyvals = self._GetKeyvals() keyvals["retval"] = retval result = Result(out, err, retval, keyvals) return result - def _GetKeyvals(self, results_dir): + def _GetKeyvals(self): full_results_dir = os.path.join(self.chromeos_root, "chroot", - results_dir.lstrip("/")) + self.results_dir.lstrip("/")) command = "find %s -regex .*results/keyval$" % full_results_dir [ret, out, err] = self._ce.RunCommand(command, return_output=True) keyvals_dict = {} diff --git a/crosperf/experiment.py b/crosperf/experiment.py index 83889b06..8ac1a700 100644 --- a/crosperf/experiment.py +++ b/crosperf/experiment.py @@ -66,9 +66,6 @@ class Experiment(object): logger_to_use = logger.Logger(os.path.dirname(__file__), "run.%s" % (full_name), True) - ar = AutotestRunner(logger_to_use=logger_to_use) - rc = ResultsCache() - pp = PerfProcessor(logger_to_use=logger_to_use) benchmark_run = BenchmarkRun(benchmark_run_name, benchmark.name, benchmark.autotest_name, @@ -83,9 +80,6 @@ class Experiment(object): benchmark.profile_counters, benchmark.profile_type, self.machine_manager, - rc, - ar, - pp, logger_to_use) benchmark_runs.append(benchmark_run) diff --git a/crosperf/experiment_runner.py b/crosperf/experiment_runner.py index 3da1d63d..6b73f5d9 100644 --- a/crosperf/experiment_runner.py +++ b/crosperf/experiment_runner.py @@ -8,6 +8,7 @@ import time from experiment_status import ExperimentStatus from results_report import HTMLResultsReport from results_report import TextResultsReport +from utils import command_executer from utils import logger from utils.email_sender import EmailSender from utils.file_utils import FileUtils @@ -20,6 +21,7 @@ class ExperimentRunner(object): def __init__(self, experiment): self._experiment = experiment self.l = logger.GetLogger() + self._ce = command_executer.GetCommandExecuter(self.l) self._terminated = False def _Run(self, experiment): @@ -97,6 +99,11 @@ class ExperimentRunner(object): benchmark_run.perf_results.report) FileUtils().WriteFile(os.path.join(benchmark_run_path, "perf.out"), benchmark_run.perf_results.output) + if os.path.isfile(benchmark_run.perf_processor.host_data_file): + self._ce.RunCommand("cp %s %s" % + (benchmark_run.perf_processor.host_data_file, + os.path.join(benchmark_run_path, "perf.data"))) + except Exception, e: self.l.LogError(e) diff --git a/crosperf/perf_processor.py b/crosperf/perf_processor.py index 031f35d2..8e6f1cd6 100644 --- a/crosperf/perf_processor.py +++ b/crosperf/perf_processor.py @@ -1,11 +1,11 @@ #!/usr/bin/python - +# # Copyright 2011 Google Inc. All Rights Reserved. import os import re + from utils import command_executer -from utils import utils class PerfProcessor(object): @@ -14,18 +14,54 @@ class PerfProcessor(object): self.report = report self.output = output - def __init__(self, logger_to_use=None): + def __init__(self, results_dir, chromeos_root, board, logger_to_use=None): self._logger = logger_to_use self._ce = command_executer.GetCommandExecuter(self._logger) + self._results_dir = results_dir + self._chromeos_root = chromeos_root + self._board = board + self._perf_relative_dir = os.path.basename(self._results_dir) + self.host_data_file = self.FindSingleFile( + "perf.data", os.path.join( + chromeos_root, + "chroot", + self._results_dir.lstrip("/"))) + self.perf_out = self.FindSingleFile( + "perf.out", os.path.join( + chromeos_root, + "chroot", + self._results_dir.lstrip("/"))) + + def FindSingleFile(self, name, path): + find_command = ("find %s -name %s" % (path, name)) + ret, out, err = self._ce.RunCommand(find_command, return_output=True) + if ret == 0: + data_files = out.splitlines() + if len(data_files) == 0: + # No data file, no report to generate. + data_file = None + else: + assert len(data_files) == 1, "More than 1 perf.out file found" + data_file = data_files[0] + return data_file + + + def GeneratePerfResults(self): + perf_location = os.path.join(self._results_dir, + self._perf_relative_dir) + if self.perf_out != None: + output = self._ReadPerfOutput() - def GeneratePerfResults(self, results_dir, chromeos_root, board): - perf_location = os.path.join(results_dir, - os.path.basename(results_dir), - "profiling/iteration.1") - host_perf_location = os.path.join(chromeos_root, "chroot", - perf_location.lstrip("/")) - report = self._GeneratePerfReport(perf_location, chromeos_root, board) - output = self._ReadPerfOutput(host_perf_location) + if self.host_data_file != None: + perf_location = os.path.join(self._results_dir, + self._perf_relative_dir) + host_perf_location = os.path.dirname(self.host_data_file) + report = self._GeneratePerfReport(perf_location, + self._chromeos_root, + self._board) + else: + # lets make perf.report have output of stat... + report = output return PerfProcessor.PerfResults(report, output) def ParseStatResults(self, results): @@ -38,16 +74,18 @@ class PerfProcessor(object): result[match.group(2)] = match.group(1) return result - def _ReadPerfOutput(self, perf_location): - perf_output_file = os.path.join(perf_location, "perf.out") - with open(perf_output_file, "rb") as f: + def _ReadPerfOutput(self): + with open(self.perf_out, "rb") as f: return f.read() def _GeneratePerfReport(self, perf_location, chromeos_root, board): perf_data_file = os.path.join(perf_location, "perf.data") # Attempt to build a perf report and keep it with the results. command = ("/usr/sbin/perf report --symfs=/build/%s" - " -i %s --stdio | head -n1000" % (board, perf_data_file)) + " --vmlinux /build/%s/usr/lib/debug/boot/vmlinux" + " --kallsyms /build/%s/boot/System.map-*" + " -i %s --stdio | head -n1000" % (board, board, board, + perf_data_file)) _, out, _ = self._ce.ChrootRunCommand(chromeos_root, command, return_output=True) return out diff --git a/crosperf/results_cache.py b/crosperf/results_cache.py index b8b495e8..0b921b03 100644 --- a/crosperf/results_cache.py +++ b/crosperf/results_cache.py @@ -1,5 +1,5 @@ #!/usr/bin/python - +# # Copyright 2011 Google Inc. All Rights Reserved. import getpass @@ -8,11 +8,12 @@ import hashlib import os import pickle import re + from image_checksummer import ImageChecksummer from perf_processor import PerfProcessor from utils import command_executer from utils import logger -from utils import utils + SCRATCH_DIR = "/home/%s/cros_scratch" % getpass.getuser() RESULTS_FILE = "results.txt" @@ -44,6 +45,9 @@ class CacheConditions(object): # Never a cache hit. FALSE = 4 + # Cache hit if the image path matches the cached image path. + IMAGE_PATH_MATCH = 5 + class ResultsCache(object): CACHE_VERSION = 2 @@ -92,9 +96,18 @@ class ResultsCache(object): checksum = "*" else: checksum = ImageChecksummer().Checksum(self.chromeos_image) - return (hashlib.md5(self.chromeos_image).hexdigest(), + + if read and CacheConditions.IMAGE_PATH_MATCH not in self.cache_conditions: + image_path_checksum = "*" + else: + image_path_checksum = hashlib.md5(self.chromeos_image).hexdigest() + + autotest_args_checksum = hashlib.md5( + "".join(self.autotest_args)).hexdigest() + + return (image_path_checksum, self.autotest_name, str(self.iteration), - ",".join(self.autotest_args), + autotest_args_checksum, checksum, remote, str(self.CACHE_VERSION)) |