xref: /aosp_15_r20/external/toolchain-utils/bestflags/example_algorithms.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1# Copyright 2013 The ChromiumOS Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""An example main file running the algorithms.
5
6Part of the Chrome build flags optimization.
7
8An example use of the framework. It parses the input json configuration file.
9Then it initiates the variables of the generation. Finally, it sets up the
10processes for different modules and runs the experiment.
11"""
12
13__author__ = "[email protected] (Yuheng Long)"
14
15import json
16import multiprocessing
17from optparse import OptionParser
18import sys
19
20import flags
21from genetic_algorithm import GAGeneration
22from pipeline_process import PipelineProcess
23import pipeline_worker
24from steering import Steering
25from task import BUILD_STAGE
26from task import Task
27from task import TEST_STAGE
28import testing_batch
29
30
31parser = OptionParser()
32
33parser.add_option(
34    "-f",
35    "--file",
36    dest="filename",
37    help="configuration file FILE input",
38    metavar="FILE",
39)
40
41# The meta data for the genetic algorithm.
42BUILD_CMD = "BUILD_CMD"
43TEST_CMD = "TEST_CMD"
44OUTPUT = "OUTPUT"
45DEFAULT_OUTPUT = "output"
46CONF = "CONF"
47DEFAULT_CONF = "conf"
48NUM_BUILDER = "NUM_BUILDER"
49DEFAULT_NUM_BUILDER = 1
50NUM_TESTER = "NUM_TESTER"
51DEFAULT_NUM_TESTER = 1
52STOP_THRESHOLD = "STOP_THRESHOLD"
53DEFAULT_STOP_THRESHOLD = 1
54NUM_CHROMOSOMES = "NUM_CHROMOSOMES"
55DEFAULT_NUM_CHROMOSOMES = 20
56NUM_TRIALS = "NUM_TRIALS"
57DEFAULT_NUM_TRIALS = 20
58MUTATION_RATE = "MUTATION_RATE"
59DEFAULT_MUTATION_RATE = 0.01
60
61
62def _ProcessGA(meta_data):
63    """Set up the meta data for the genetic algorithm.
64
65    Args:
66      meta_data: the meta data for the genetic algorithm.
67    """
68    assert BUILD_CMD in meta_data
69    build_cmd = meta_data[BUILD_CMD]
70
71    assert TEST_CMD in meta_data
72    test_cmd = meta_data[TEST_CMD]
73
74    if OUTPUT not in meta_data:
75        output_file = DEFAULT_OUTPUT
76    else:
77        output_file = meta_data[OUTPUT]
78
79    if CONF not in meta_data:
80        conf_file = DEFAULT_CONF
81    else:
82        conf_file = meta_data[CONF]
83
84    if NUM_BUILDER not in meta_data:
85        num_builders = DEFAULT_NUM_BUILDER
86    else:
87        num_builders = meta_data[NUM_BUILDER]
88
89    if NUM_TESTER not in meta_data:
90        num_testers = DEFAULT_NUM_TESTER
91    else:
92        num_testers = meta_data[NUM_TESTER]
93
94    if STOP_THRESHOLD not in meta_data:
95        stop_threshold = DEFAULT_STOP_THRESHOLD
96    else:
97        stop_threshold = meta_data[STOP_THRESHOLD]
98
99    if NUM_CHROMOSOMES not in meta_data:
100        num_chromosomes = DEFAULT_NUM_CHROMOSOMES
101    else:
102        num_chromosomes = meta_data[NUM_CHROMOSOMES]
103
104    if NUM_TRIALS not in meta_data:
105        num_trials = DEFAULT_NUM_TRIALS
106    else:
107        num_trials = meta_data[NUM_TRIALS]
108
109    if MUTATION_RATE not in meta_data:
110        mutation_rate = DEFAULT_MUTATION_RATE
111    else:
112        mutation_rate = meta_data[MUTATION_RATE]
113
114    specs = flags.ReadConf(conf_file)
115
116    # Initiate the build/test command and the log directory.
117    Task.InitLogCommand(build_cmd, test_cmd, output_file)
118
119    # Initiate the build/test command and the log directory.
120    GAGeneration.InitMetaData(
121        stop_threshold, num_chromosomes, num_trials, specs, mutation_rate
122    )
123
124    # Generate the initial generations.
125    generation_tasks = testing_batch.GenerateRandomGATasks(
126        specs, num_chromosomes, num_trials
127    )
128    generations = [GAGeneration(generation_tasks, set([]), 0)]
129
130    # Execute the experiment.
131    _StartExperiment(num_builders, num_testers, generations)
132
133
134def _ParseJson(file_name):
135    """Parse the input json file.
136
137    Parse the input json file and call the proper function to perform the
138    algorithms.
139
140    Args:
141      file_name: the input json file name.
142    """
143
144    experiments = json.load(open(file_name))
145
146    for experiment in experiments:
147        if experiment == "GA":
148            # An GA experiment
149            _ProcessGA(experiments[experiment])
150
151
152def _StartExperiment(num_builders, num_testers, generations):
153    """Set up the experiment environment and execute the framework.
154
155    Args:
156      num_builders: number of concurrent builders.
157      num_testers: number of concurrent testers.
158      generations: the initial generation for the framework.
159    """
160
161    manager = multiprocessing.Manager()
162
163    # The queue between the steering algorithm and the builder.
164    steering_build = manager.Queue()
165    # The queue between the builder and the tester.
166    build_test = manager.Queue()
167    # The queue between the tester and the steering algorithm.
168    test_steering = manager.Queue()
169
170    # Set up the processes for the builder, tester and steering algorithm module.
171    build_process = PipelineProcess(
172        num_builders,
173        "builder",
174        {},
175        BUILD_STAGE,
176        steering_build,
177        pipeline_worker.Helper,
178        pipeline_worker.Worker,
179        build_test,
180    )
181
182    test_process = PipelineProcess(
183        num_testers,
184        "tester",
185        {},
186        TEST_STAGE,
187        build_test,
188        pipeline_worker.Helper,
189        pipeline_worker.Worker,
190        test_steering,
191    )
192
193    steer_process = multiprocessing.Process(
194        target=Steering,
195        args=(set([]), generations, test_steering, steering_build),
196    )
197
198    # Start the processes.
199    build_process.start()
200    test_process.start()
201    steer_process.start()
202
203    # Wait for the processes to finish.
204    build_process.join()
205    test_process.join()
206    steer_process.join()
207
208
209def main(argv):
210    (options, _) = parser.parse_args(argv)
211    assert options.filename
212    _ParseJson(options.filename)
213
214
215if __name__ == "__main__":
216    main(sys.argv)
217