experiment_runner.py revision 0dcbc4b1714260820fd4b8d6536fbb05e139cc0f
1#!/usr/bin/python
2
3# Copyright 2011 Google Inc. All Rights Reserved.
4
5import getpass
6import os
7import time
8from experiment_status import ExperimentStatus
9from results_report import HTMLResultsReport
10from results_report import TextResultsReport
11from utils import logger
12from utils.email_sender import EmailSender
13from utils.file_utils import FileUtils
14
15
16class ExperimentRunner(object):
17  STATUS_TIME_DELAY = 30
18  THREAD_MONITOR_DELAY = 2
19
20  def __init__(self, experiment):
21    self._experiment = experiment
22    self.l = logger.GetLogger()
23    self._terminated = False
24
25  def _Run(self, experiment):
26    status = ExperimentStatus(experiment)
27    experiment.Run()
28    last_status_time = 0
29    try:
30      while not experiment.IsComplete():
31        if last_status_time + self.STATUS_TIME_DELAY < time.time():
32          last_status_time = time.time()
33          border = "=============================="
34          self.l.LogOutput(border)
35          self.l.LogOutput(status.GetProgressString())
36          self.l.LogOutput(status.GetStatusString())
37          logger.GetLogger().LogOutput(border)
38        time.sleep(self.THREAD_MONITOR_DELAY)
39    except KeyboardInterrupt:
40      self._terminated = True
41      self.l.LogError("Ctrl-c pressed. Cleaning up...")
42      experiment.Terminate()
43
44  def _PrintTable(self, experiment):
45    self.l.LogOutput(TextResultsReport(experiment).GetReport())
46
47  def _Email(self, experiment):
48    # Only email by default if a new run was completed.
49    send_mail = False
50    for benchmark_run in experiment.benchmark_runs:
51      if not benchmark_run.cache_hit:
52        send_mail = True
53        break
54    if not send_mail:
55      return
56
57    label_names = []
58    for label in experiment.labels:
59      label_names.append(label.name)
60    subject = "%s: %s" % (experiment.name, " vs. ".join(label_names))
61
62    text_report = TextResultsReport(experiment).GetReport()
63    text_report = "<pre style='font-size: 13px'>%s</pre>" % text_report
64    html_report = HTMLResultsReport(experiment).GetReport()
65    attachment = EmailSender.Attachment("report.html", html_report)
66    EmailSender().SendEmail([getpass.getuser()],
67                            subject,
68                            text_report,
69                            attachments=[attachment],
70                            msg_type="html")
71
72  def _StoreResults (self, experiment):
73    if self._terminated:
74      return
75    results_directory = experiment.results_directory
76    FileUtils().RmDir(results_directory)
77    FileUtils().MkDirP(results_directory)
78    self.l.LogOutput("Storing experiment file.")
79    experiment_file_path = os.path.join(results_directory,
80                                        "experiment.exp")
81    FileUtils().WriteFile(experiment_file_path, experiment.experiment_file)
82
83    self.l.LogOutput("Storing results report.")
84    results_table_path = os.path.join(results_directory, "results.html")
85    report = HTMLResultsReport(experiment).GetReport()
86    FileUtils().WriteFile(results_table_path, report)
87
88    self.l.LogOutput("Storing results of each benchmark run.")
89    for benchmark_run in experiment.benchmark_runs:
90      benchmark_run_name = filter(str.isalnum, benchmark_run.name)
91      try:
92        if benchmark_run.perf_results:
93          benchmark_run_path = os.path.join(results_directory,
94                                            benchmark_run_name)
95          FileUtils().MkDirP(benchmark_run_path)
96          FileUtils().WriteFile(os.path.join(benchmark_run_path, "perf.report"),
97                                benchmark_run.perf_results.report)
98          FileUtils().WriteFile(os.path.join(benchmark_run_path, "perf.out"),
99                                benchmark_run.perf_results.output)
100      except Exception, e:
101        self.l.LogError(e)
102
103  def Run(self):
104    self._Run(self._experiment)
105    self._PrintTable(self._experiment)
106    if not self._terminated:
107      self._StoreResults(self._experiment)
108      self._Email(self._experiment)
109
110
111class MockExperimentRunner(ExperimentRunner):
112  def __init__(self, experiment):
113    super(MockExperimentRunner, self).__init__(experiment)
114
115  def _Run(self, experiment):
116    self.l.LogOutput("Would run the following experiment: '%s'." %
117                     experiment.name)
118
119  def _PrintTable(self, experiment):
120    self.l.LogOutput("Would print the experiment table.")
121
122  def _Email(self, experiment):
123    self.l.LogOutput("Would send result email.")
124
125  def _StoreResults(self, experiment):
126    self.l.LogOutput("Would store the results.")
127