# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Hill climbing unitest.

Part of the Chrome build flags optimization.

Test the best branching hill climbing algorithms, genetic algorithm and
iterative elimination algorithm.
"""

__author__ = 'yuhenglong@google.com (Yuheng Long)'

import multiprocessing
import random
import sys
import unittest

import flags
from flags import Flag
from flags import FlagSet
from genetic_algorithm import GAGeneration
from genetic_algorithm import GATask
from hill_climb_best_neighbor import HillClimbingBestBranch
from iterative_elimination import IterativeEliminationFirstGeneration
import pipeline_process
from steering import Steering
from task import BUILD_STAGE
from task import Task
from task import TEST_STAGE


# The number of flags be tested.
NUM_FLAGS = 5

# The value range of the flags.
FLAG_RANGES = 10

# The following variables are meta data for the Genetic Algorithm.
STOP_THRESHOLD = 20
NUM_CHROMOSOMES = 10
NUM_TRIALS = 20
MUTATION_RATE = 0.03


def _GenerateRandomRasks(specs):
  """Generate a task that has random values.

  Args:
    specs: A list of spec from which the flag set is created.

  Returns:
    A set containing a task that has random values.
  """

  flag_set = []

  for spec in specs:
    numeric_flag_match = flags.Search(spec)
    if numeric_flag_match:
      # Numeric flags.
      start = int(numeric_flag_match.group('start'))
      end = int(numeric_flag_match.group('end'))

      value = random.randint(start - 1, end - 1)
      if value != start - 1:
        # If the value falls in the range, this flag is enabled.
        flag_set.append(Flag(spec, value))
    else:
      # Boolean flags.
      if random.randint(0, 1):
        flag_set.append(Flag(spec))

  return set([Task(FlagSet(flag_set))])


def _GenerateAllFlagsTasks(specs):
  """Generate a task that all the flags are enable.

  All the boolean flags in the specs will be enabled and all the numeric flag
  with have the largest legal value.

  Args:
    specs: A list of spec from which the flag set is created.

  Returns:
    A set containing a task that has all flags enabled.
  """

  flag_set = []

  for spec in specs:
    numeric_flag_match = flags.Search(spec)

    if numeric_flag_match:
      value = (int(numeric_flag_match.group('end')) - 1)
    else:
      value = -1
    flag_set.append(Flag(spec, value))

  return set([Task(FlagSet(flag_set))])


def _GenerateNoFlagTask():
  return set([Task(FlagSet([]))])


def GenerateRandomGATasks(specs, num_tasks, num_trials):
  """Generate a set of tasks for the Genetic Algorithm.

  Args:
    specs: A list of spec from which the flag set is created.
    num_tasks: number of tasks that should be generated.
    num_trials: the maximum number of tries should be attempted to generate the
      set of tasks.

  Returns:
    A set of randomly generated tasks.
  """

  tasks = set([])

  total_trials = 0
  while len(tasks) < num_tasks and total_trials < num_trials:
    new_flag = FlagSet([Flag(spec) for spec in specs if random.randint(0, 1)])
    new_task = GATask(new_flag)

    if new_task in tasks:
      total_trials += 1
    else:
      tasks.add(new_task)
      total_trials = 0

  return tasks


def _GenerateInitialFlags(specs, spec):
  """Generate the flag_set of a task in the flag elimination algorithm.

  Set the value of all the flags to the largest value, except for the flag that
  contains spec.

  For example, if the specs are [-finline-limit=[1-1000], -fstrict-aliasing] and
  the spec is -finline-limit=[1-1000], then the result is
  [-finline-limit=[1-1000]:-finline-limit=998,
   -fstrict-aliasing:-fstrict-aliasing]

  Args:
    specs: an array of specifications from which the result flag_set is created.
      The flag_set contains one and only one flag that contain the specification
      spec.
    spec: The flag containing this spec should have a value that is smaller than
      the highest value the flag can have.

  Returns:
    An array of flags, each of which contains one spec in specs. All the values
    of the flags are the largest values in specs, expect the one that contains
    spec.
  """

  flag_set = []
  for other_spec in specs:
    numeric_flag_match = flags.Search(other_spec)
    # Found the spec in the array specs.
    if other_spec == spec:
      # Numeric flag will have a value that is smaller than the largest value
      # and Boolean flag will be deleted.
      if numeric_flag_match:
        end = int(numeric_flag_match.group('end'))
        flag_set.append(flags.Flag(other_spec, end - 2))

      continue

    # other_spec != spec
    if numeric_flag_match:
      # numeric flag
      end = int(numeric_flag_match.group('end'))
      flag_set.append(flags.Flag(other_spec, end - 1))
      continue

    # boolean flag
    flag_set.append(flags.Flag(other_spec))

  return flag_set


def _GenerateAllIterativeEliminationTasks(specs):
  """Generate the initial tasks for the negative flag elimination algorithm.

  Generate the base line task that turns on all the boolean flags and sets the
  value to be the largest value for the numeric flag.

  For example, if the specs are [-finline-limit=[1-1000], -fstrict-aliasing],
  the base line is [-finline-limit=[1-1000]:-finline-limit=999,
  -fstrict-aliasing:-fstrict-aliasing]

  Generate a set of task, each turns off one of the flag or sets a value that is
  smaller than the largest value for the flag.

  Args:
    specs: an array of specifications from which the result flag_set is created.

  Returns:
    An array containing one generation of the initial tasks for the negative
    flag elimination algorithm.
  """

  # The set of tasks to be generated.
  results = set([])
  flag_set = []

  for spec in specs:
    numeric_flag_match = flags.Search(spec)
    if numeric_flag_match:
      # Numeric flag.
      end_value = int(numeric_flag_match.group('end'))
      flag_set.append(flags.Flag(spec, end_value - 1))
      continue

    # Boolean flag.
    flag_set.append(flags.Flag(spec))

  # The base line task that set all the flags to their largest values.
  parent_task = Task(flags.FlagSet(flag_set))
  results.add(parent_task)

  for spec in specs:
    results.add(Task(flags.FlagSet(_GenerateInitialFlags(specs, spec))))

  return [IterativeEliminationFirstGeneration(results, parent_task)]


def _ComputeCost(cost_func, specs, flag_set):
  """Compute the mock cost of the flag_set using the input cost function.

  All the boolean flags in the specs will be enabled and all the numeric flag
  with have the largest legal value.

  Args:
    cost_func: The cost function which is used to compute the mock cost of a
      dictionary of flags.
    specs: All the specs that are used in the algorithm. This is used to check
      whether certain flag is disabled in the flag_set dictionary.
    flag_set: a dictionary of the spec and flag pairs.

  Returns:
    The mock cost of the input dictionary of the flags.
  """

  values = []

  for spec in specs:
    # If a flag is enabled, its value is added. Otherwise a padding 0 is added.
    values.append(flag_set[spec].GetValue() if spec in flag_set else 0)

  # The cost function string can use the values array.
  return eval(cost_func)


def _GenerateTestFlags(num_flags, upper_bound, file_name):
  """Generate a set of mock flags and write it to a configuration file.

  Generate a set of mock flags

  Args:
    num_flags: Number of numeric flags to be generated.
    upper_bound: The value of the upper bound of the range.
    file_name: The configuration file name into which the mock flags are put.
  """

  with open(file_name, 'w') as output_file:
    num_flags = int(num_flags)
    upper_bound = int(upper_bound)
    for i in range(num_flags):
      output_file.write('%s=[1-%d]\n' % (i, upper_bound))


def _TestAlgorithm(cost_func, specs, generations, best_result):
  """Test the best result the algorithm should return.

  Set up the framework, run the input algorithm and verify the result.

  Args:
    cost_func: The cost function which is used to compute the mock cost of a
      dictionary of flags.
    specs: All the specs that are used in the algorithm. This is used to check
      whether certain flag is disabled in the flag_set dictionary.
    generations: The initial generations to be evaluated.
    best_result: The expected best result of the algorithm. If best_result is
      -1, the algorithm may or may not return the best value. Therefore, no
      assertion will be inserted.
  """

  # Set up the utilities to test the framework.
  manager = multiprocessing.Manager()
  input_queue = manager.Queue()
  output_queue = manager.Queue()
  pp_steer = multiprocessing.Process(target=Steering,
                                     args=(set(), generations, output_queue,
                                           input_queue))
  pp_steer.start()

  # The best result of the algorithm so far.
  result = sys.maxint

  while True:
    task = input_queue.get()

    # POISONPILL signal the ends of the algorithm.
    if task == pipeline_process.POISONPILL:
      break

    task.SetResult(BUILD_STAGE, (0, 0, 0, 0, 0))

    # Compute the mock cost for the task.
    task_result = _ComputeCost(cost_func, specs, task.GetFlags())
    task.SetResult(TEST_STAGE, task_result)

    # If the mock result of the current task is the best so far, set this
    # result to be the best result.
    if task_result < result:
      result = task_result

    output_queue.put(task)

  pp_steer.join()

  # Only do this test when best_result is not -1.
  if best_result != -1:
    assert best_result == result


class MockAlgorithmsTest(unittest.TestCase):
  """This class mock tests different steering algorithms.

  The steering algorithms are responsible for generating the next set of tasks
  to run in each iteration. This class does a functional testing on the
  algorithms. It mocks out the computation of the fitness function from the
  build and test phases by letting the user define the fitness function.
  """

  def _GenerateFlagSpecifications(self):
    """Generate the testing specifications."""

    mock_test_file = 'scale_mock_test'
    _GenerateTestFlags(NUM_FLAGS, FLAG_RANGES, mock_test_file)
    return flags.ReadConf(mock_test_file)

  def testBestHillClimb(self):
    """Test the best hill climb algorithm.

    Test whether it finds the best results as expected.
    """

    # Initiate the build/test command and the log directory.
    Task.InitLogCommand(None, None, 'output')

    # Generate the testing specs.
    specs = self._GenerateFlagSpecifications()

    # Generate the initial generations for a test whose cost function is the
    # summation of the values of all the flags.
    generation_tasks = _GenerateAllFlagsTasks(specs)
    generations = [HillClimbingBestBranch(generation_tasks, set([]), specs)]

    # Test the algorithm. The cost function is the summation of all the values
    # of all the flags. Therefore, the best value is supposed to be 0, i.e.,
    # when all the flags are disabled.
    _TestAlgorithm('sum(values[0:len(values)])', specs, generations, 0)

    # This test uses a cost function that is the negative of the previous cost
    # function. Therefore, the best result should be found in task with all the
    # flags enabled.
    cost_function = 'sys.maxint - sum(values[0:len(values)])'
    all_flags = list(generation_tasks)[0].GetFlags()
    cost = _ComputeCost(cost_function, specs, all_flags)

    # Generate the initial generations.
    generation_tasks = _GenerateNoFlagTask()
    generations = [HillClimbingBestBranch(generation_tasks, set([]), specs)]

    # Test the algorithm. The cost function is negative of the summation of all
    # the values of all the flags. Therefore, the best value is supposed to be
    # 0, i.e., when all the flags are disabled.
    _TestAlgorithm(cost_function, specs, generations, cost)

  def testGeneticAlgorithm(self):
    """Test the Genetic Algorithm.

    Do a functional testing here and see how well it scales.
    """

    # Initiate the build/test command and the log directory.
    Task.InitLogCommand(None, None, 'output')

    # Generate the testing specs.
    specs = self._GenerateFlagSpecifications()
    # Initiate the build/test command and the log directory.
    GAGeneration.InitMetaData(STOP_THRESHOLD, NUM_CHROMOSOMES, NUM_TRIALS,
                              specs, MUTATION_RATE)

    # Generate the initial generations.
    generation_tasks = GenerateRandomGATasks(specs, NUM_CHROMOSOMES,
                                             NUM_TRIALS)
    generations = [GAGeneration(generation_tasks, set([]), 0)]

    # Test the algorithm.
    _TestAlgorithm('sum(values[0:len(values)])', specs, generations, -1)
    cost_func = 'sys.maxint - sum(values[0:len(values)])'
    _TestAlgorithm(cost_func, specs, generations, -1)

  def testIterativeElimination(self):
    """Test the iterative elimination algorithm.

    Test whether it finds the best results as expected.
    """

    # Initiate the build/test command and the log directory.
    Task.InitLogCommand(None, None, 'output')

    # Generate the testing specs.
    specs = self._GenerateFlagSpecifications()

    # Generate the initial generations. The generation contains the base line
    # task that turns on all the flags and tasks that each turn off one of the
    # flags.
    generations = _GenerateAllIterativeEliminationTasks(specs)

    # Test the algorithm. The cost function is the summation of all the values
    # of all the flags. Therefore, the best value is supposed to be 0, i.e.,
    # when all the flags are disabled.
    _TestAlgorithm('sum(values[0:len(values)])', specs, generations, 0)

    # This test uses a cost function that is the negative of the previous cost
    # function. Therefore, the best result should be found in task with all the
    # flags enabled.
    all_flags_tasks = _GenerateAllFlagsTasks(specs)
    cost_function = 'sys.maxint - sum(values[0:len(values)])'
    # Compute the cost of the task that turns on all the flags.
    all_flags = list(all_flags_tasks)[0].GetFlags()
    cost = _ComputeCost(cost_function, specs, all_flags)

    # Test the algorithm. The cost function is negative of the summation of all
    # the values of all the flags. Therefore, the best value is supposed to be
    # 0, i.e., when all the flags are disabled.
    # The concrete type of the generation decides how the next generation will
    # be generated.
    _TestAlgorithm(cost_function, specs, generations, cost)

if __name__ == '__main__':
  unittest.main()
