experiment_runner.py revision fd356fb31c4340851fecc750230d05c9518b125c
10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#!/usr/bin/python
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Copyright 2011 Google Inc. All Rights Reserved.
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport getpass
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport time
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom experiment_status import ExperimentStatus
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom results_report import HTMLResultsReport
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom results_report import TextResultsReport
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom utils import command_executer
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom utils import logger
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom utils.email_sender import EmailSender
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom utils.file_utils import FileUtils
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass ExperimentRunner(object):
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  STATUS_TIME_DELAY = 30
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  THREAD_MONITOR_DELAY = 2
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def __init__(self, experiment):
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self._experiment = experiment
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l = logger.GetLogger()
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self._ce = command_executer.GetCommandExecuter(self.l)
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self._terminated = False
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _Run(self, experiment):
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    status = ExperimentStatus(experiment)
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    experiment.Run()
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    last_status_time = 0
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      while not experiment.IsComplete():
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if last_status_time + self.STATUS_TIME_DELAY < time.time():
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          last_status_time = time.time()
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          border = "=============================="
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          self.l.LogOutput(border)
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          self.l.LogOutput(status.GetProgressString())
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          self.l.LogOutput(status.GetStatusString())
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          logger.GetLogger().LogOutput(border)
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        time.sleep(self.THREAD_MONITOR_DELAY)
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except KeyboardInterrupt:
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      self._terminated = True
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      self.l.LogError("Ctrl-c pressed. Cleaning up...")
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      experiment.Terminate()
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _PrintTable(self, experiment):
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput(TextResultsReport(experiment).GetReport())
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _Email(self, experiment):
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Only email by default if a new run was completed.
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    send_mail = False
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for benchmark_run in experiment.benchmark_runs:
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      if not benchmark_run.cache_hit:
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        send_mail = True
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        break
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not send_mail:
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      return
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    label_names = []
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for label in experiment.labels:
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      label_names.append(label.name)
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    subject = "%s: %s" % (experiment.name, " vs. ".join(label_names))
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    text_report = TextResultsReport(experiment).GetReport()
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    text_report = "<pre style='font-size: 13px'>%s</pre>" % text_report
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    html_report = HTMLResultsReport(experiment).GetReport()
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    attachment = EmailSender.Attachment("report.html", html_report)
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    EmailSender().SendEmail([getpass.getuser()],
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            subject,
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            text_report,
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            attachments=[attachment],
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            msg_type="html")
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _StoreResults (self, experiment):
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if self._terminated:
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      return
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    results_directory = experiment.results_directory
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    FileUtils().RmDir(results_directory)
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    FileUtils().MkDirP(results_directory)
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Storing experiment file.")
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    experiment_file_path = os.path.join(results_directory,
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                        "experiment.exp")
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    FileUtils().WriteFile(experiment_file_path, experiment.experiment_file)
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Storing results report.")
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    results_table_path = os.path.join(results_directory, "results.html")
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    report = HTMLResultsReport(experiment).GetReport()
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    FileUtils().WriteFile(results_table_path, report)
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Storing results of each benchmark run.")
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for benchmark_run in experiment.benchmark_runs:
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      benchmark_run_name = filter(str.isalnum, benchmark_run.name)
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      try:
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if benchmark_run.perf_results:
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          benchmark_run_path = os.path.join(results_directory,
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                            benchmark_run_name)
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          FileUtils().MkDirP(benchmark_run_path)
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          FileUtils().WriteFile(os.path.join(benchmark_run_path, "perf.report"),
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                benchmark_run.perf_results.report)
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          FileUtils().WriteFile(os.path.join(benchmark_run_path, "perf.out"),
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                benchmark_run.perf_results.output)
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao          if os.path.isfile(benchmark_run.perf_processor.host_data_file):
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._ce.RunCommand("cp %s %s" %
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                (benchmark_run.perf_processor.host_data_file,
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 os.path.join(benchmark_run_path, "perf.data")))
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      except Exception, e:
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.l.LogError(e)
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def Run(self):
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self._Run(self._experiment)
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self._PrintTable(self._experiment)
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not self._terminated:
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      self._StoreResults(self._experiment)
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      self._Email(self._experiment)
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass MockExperimentRunner(ExperimentRunner):
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def __init__(self, experiment):
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    super(MockExperimentRunner, self).__init__(experiment)
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _Run(self, experiment):
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Would run the following experiment: '%s'." %
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     experiment.name)
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _PrintTable(self, experiment):
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Would print the experiment table.")
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _Email(self, experiment):
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Would send result email.")
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao  def _StoreResults(self, experiment):
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self.l.LogOutput("Would store the results.")
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao