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