aboutsummaryrefslogtreecommitdiff
path: root/crosperf
diff options
context:
space:
mode:
authorAhmad Sharif <asharif@chromium.org>2012-05-07 12:02:16 -0700
committerAhmad Sharif <asharif@chromium.org>2012-05-07 12:02:16 -0700
commitfd356fb31c4340851fecc750230d05c9518b125c (patch)
tree694f1a93f568d5e46655c30bb76cb71d7400f11b /crosperf
parent92ab7af223c82fe8897bacea8b32028828eab018 (diff)
downloadtoolchain-utils-fd356fb31c4340851fecc750230d05c9518b125c.tar.gz
Synced repos to: 60208
Diffstat (limited to 'crosperf')
-rw-r--r--crosperf/autotest_runner.py3
-rw-r--r--crosperf/benchmark_run.py94
-rw-r--r--crosperf/experiment.py6
-rw-r--r--crosperf/experiment_runner.py7
-rw-r--r--crosperf/perf_processor.py68
-rw-r--r--crosperf/results_cache.py21
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))