blob: af0a502f74d1df5fb692831bca22e88c192fb397 [file] [log] [blame]
George Burgess IVed696762016-09-12 18:24:54 -07001#!/usr/bin/env python2
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08002
3# Copyright 2011 Google Inc. All Rights Reserved.
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08004"""The driver script for running performance benchmarks on ChromeOS."""
5
Rahul Chaudhrycbc5a262015-12-30 17:05:14 -08006from __future__ import print_function
7
Rahul Chaudhry4f07bbf2016-01-29 15:10:02 -08008import argparse
Denis Nikitin144f6992019-07-20 20:25:16 -07009import atexit
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080010import os
Luis Lozano45b53c52015-09-30 11:36:27 -070011import signal
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080012import sys
13from experiment_runner import ExperimentRunner
14from experiment_runner import MockExperimentRunner
15from experiment_factory import ExperimentFactory
16from experiment_file import ExperimentFile
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080017from settings_factory import GlobalSettings
Rahul Chaudhryeff2fc12016-02-24 10:12:43 -080018
Caroline Ticea8af9a72016-07-20 12:52:59 -070019# This import causes pylint to warn about "No name 'logger' in module
20# 'cros_utils'". I do not understand why. The import works fine in python.
Rahul Chaudhryeff2fc12016-02-24 10:12:43 -080021# pylint: disable=no-name-in-module
Caroline Ticea8af9a72016-07-20 12:52:59 -070022from cros_utils import logger
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080023
Ahmad Sharif4467f002012-12-20 12:09:49 -080024import test_flag
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080025
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080026
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080027def SetupParserOptions(parser):
28 """Add all options to the parser."""
Manoj Guptaaee96b72016-10-24 13:43:28 -070029 parser.add_argument(
30 '--dry_run',
31 dest='dry_run',
32 help=('Parse the experiment file and '
33 'show what will be done'),
34 action='store_true',
35 default=False)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080036 # Allow each of the global fields to be overridden by passing in
37 # options. Add each global field as an option.
Luis Lozanof2a3ef42015-12-15 13:49:30 -080038 option_settings = GlobalSettings('')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080039 for field_name in option_settings.fields:
40 field = option_settings.fields[field_name]
Manoj Guptaaee96b72016-10-24 13:43:28 -070041 parser.add_argument(
42 '--%s' % field.name,
43 dest=field.name,
44 help=field.description,
45 action='store')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080046
47
48def ConvertOptionsToSettings(options):
49 """Convert options passed in into global settings."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -080050 option_settings = GlobalSettings('option_settings')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080051 for option_name in options.__dict__:
52 if (options.__dict__[option_name] is not None and
53 option_name in option_settings.fields):
54 option_settings.SetField(option_name, options.__dict__[option_name])
55 return option_settings
56
57
58def Cleanup(experiment):
59 """Handler function which is registered to the atexit handler."""
60 experiment.Cleanup()
61
62
Luis Lozano45b53c52015-09-30 11:36:27 -070063def CallExitHandler(signum, _):
64 """Signal handler that transforms a signal into a call to exit.
65
66 This is useful because functionality registered by "atexit" will
67 be called. It also means you can "catch" the signal by catching
68 the SystemExit exception.
69 """
70 sys.exit(128 + signum)
71
72
Manoj Guptaaee96b72016-10-24 13:43:28 -070073def RunCrosperf(argv):
Rahul Chaudhry4f07bbf2016-01-29 15:10:02 -080074 parser = argparse.ArgumentParser()
Luis Lozanof81680c2013-03-15 14:44:13 -070075
Manoj Guptaaee96b72016-10-24 13:43:28 -070076 parser.add_argument(
77 '--noschedv2',
78 dest='noschedv2',
79 default=False,
80 action='store_true',
81 help=('Do not use new scheduler. '
82 'Use original scheduler instead.'))
83 parser.add_argument(
84 '-l',
85 '--log_dir',
86 dest='log_dir',
87 default='',
88 help='The log_dir, default is under <crosperf_logs>/logs')
Denis Nikitin144f6992019-07-20 20:25:16 -070089 parser.add_argument(
90 '--no_hwp',
91 default=False,
92 action='store_true',
93 help='Disable intel_pstate on Intel CPU with HWP support.')
Luis Lozanof81680c2013-03-15 14:44:13 -070094
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080095 SetupParserOptions(parser)
Rahul Chaudhry4f07bbf2016-01-29 15:10:02 -080096 options, args = parser.parse_known_args(argv)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080097
98 # Convert the relevant options that are passed in into a settings
99 # object which will override settings in the experiment file.
100 option_settings = ConvertOptionsToSettings(options)
Luis Lozanof81680c2013-03-15 14:44:13 -0700101 log_dir = os.path.abspath(os.path.expanduser(options.log_dir))
102 logger.GetLogger(log_dir)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800103
104 if len(args) == 2:
105 experiment_filename = args[1]
106 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800107 parser.error('Invalid number arguments.')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800108
109 working_directory = os.getcwd()
Ahmad Sharif4467f002012-12-20 12:09:49 -0800110 if options.dry_run:
111 test_flag.SetTestMode(True)
112
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800113 experiment_file = ExperimentFile(
114 open(experiment_filename, 'rb'), option_settings)
115 if not experiment_file.GetGlobalSettings().GetField('name'):
Ahmad Sharif822c55d2012-02-08 20:55:47 -0800116 experiment_name = os.path.basename(experiment_filename)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800117 experiment_file.GetGlobalSettings().SetField('name', experiment_name)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800118 experiment = ExperimentFactory().GetExperiment(experiment_file,
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800119 working_directory, log_dir)
Denis Nikitin144f6992019-07-20 20:25:16 -0700120 if options.no_hwp:
121 experiment.intel_pstate = 'no_hwp'
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800122
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800123 json_report = experiment_file.GetGlobalSettings().GetField('json_report')
Caroline Ticeef4ca8a2015-08-25 12:53:38 -0700124
Luis Lozano45b53c52015-09-30 11:36:27 -0700125 signal.signal(signal.SIGTERM, CallExitHandler)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800126 atexit.register(Cleanup, experiment)
127
128 if options.dry_run:
Caroline Tice6e8726d2015-12-09 12:42:13 -0800129 runner = MockExperimentRunner(experiment, json_report)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800130 else:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700131 runner = ExperimentRunner(
132 experiment, json_report, using_schedv2=(not options.noschedv2))
Han Shenba649282015-08-05 17:19:55 -0700133
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800134 runner.Run()
135
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800136
Manoj Guptaaee96b72016-10-24 13:43:28 -0700137def Main(argv):
138 try:
139 RunCrosperf(argv)
140 except Exception as ex:
141 # Flush buffers before exiting to avoid out of order printing
142 sys.stdout.flush()
143 sys.stderr.flush()
144 print('Crosperf error: %s' % repr(ex))
145 sys.stdout.flush()
146 sys.stderr.flush()
147 sys.exit(1)
148
149
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800150if __name__ == '__main__':
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800151 Main(sys.argv)