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 _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
コード例 #4
0
def RandomMutate(specs, flag_set, mutation_rate):
    """Randomly mutate the content of a task.

  Args:
    specs: A list of spec from which the flag set is created.
    flag_set: The current flag set being mutated
    mutation_rate: What fraction of genes to mutate.

  Returns:
    A Genetic Task constructed by randomly mutating the input flag set.
  """

    results_flags = []

    for spec in specs:
        # Randomly choose whether this flag should be mutated.
        if random.randint(0, int(1 / mutation_rate)):
            continue

        # If the flag is not already in the flag set, it is added.
        if spec not in flag_set:
            results_flags.append(Flag(spec))
            continue

        # If the flag is already in the flag set, it is mutated.
        numeric_flag_match = flags.Search(spec)

        # The value of a numeric flag will be changed, and a boolean flag will be
        # dropped.
        if not numeric_flag_match:
            continue

        value = flag_set[spec].GetValue()

        # Randomly select a nearby value of the current value of the flag.
        rand_arr = [value]
        if value + 1 < int(numeric_flag_match.group('end')):
            rand_arr.append(value + 1)

        rand_arr.append(value - 1)
        value = random.sample(rand_arr, 1)[0]

        # If the value is smaller than the start of the spec, this flag will be
        # dropped.
        if value != int(numeric_flag_match.group('start')) - 1:
            results_flags.append(Flag(spec, value))

    return GATask(FlagSet(results_flags))
コード例 #5
0
def _DecreaseFlag(flags_dict, spec):
    """Decrease the value of the flag that has the specification spec.

  If the flag that contains the spec is a boolean flag, it is eliminated.
  Otherwise the flag is a numeric flag, its value will be reduced by one.

  Args:
    flags_dict: The dictionary containing the original flags whose neighbors are
      to be explored.
    spec: The spec in the flags_dict is to be changed.

  Returns:
    Dictionary of neighbor flag that is only different from the original
    dictionary by the spec.
  """

    # The specification must be held by one of the flags.
    assert spec in flags_dict

    # The results this method returns.
    results = flags_dict.copy()

    # This method searches for a pattern [start-end] in the spec. If the spec
    # contains this pattern, it is a numeric flag. Otherwise it is a boolean flag.
    # For example, -finline-limit=[1-1000] is a numeric flag and -falign-jumps is
    # a boolean flag.
    numeric_flag_match = flags.Search(spec)

    if numeric_flag_match:
        # numeric flag
        val = results[spec].GetValue()

        # If the value of the flag is the lower boundary of the specification, this
        # flag will be turned off. Because it already contains the lowest value and
        # can not be decreased any more.
        if val == int(numeric_flag_match.group('start')):
            # Turn off the flag. A flag is turned off if it is not presented in the
            # flags_dict.
            del results[spec]
        else:
            results[spec] = flags.Flag(spec, val - 1)
    else:
        # Turn off the flag. A flag is turned off if it is not presented in the
        # flags_dict.
        del results[spec]

    return results
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 ClimbNext(flags_dict, climb_spec):
    """Get the flags that are different from |flags_dict| by |climb_spec|.

  Given a set of flags, |flags_dict|, return a new set of flags that are
  adjacent along the flag spec |climb_spec|.

  An example flags_dict is {foo=[1-9]:foo=5, bar=[1-5]:bar=2} and climb_spec is
  bar=[1-5]. This method changes the flag that contains the spec bar=[1-5]. The
  results are its neighbors dictionaries, i.e., {foo=[1-9]:foo=5,
  bar=[1-5]:bar=1} and {foo=[1-9]:foo=5, bar=[1-5]:bar=3}.

  Args:
    flags_dict: The dictionary containing the original flags whose neighbors are
      to be explored.
    climb_spec: The spec in the flags_dict is to be changed. The spec is a
      definition in the little language, a string with escaped sequences of the
      form [<start>-<end>] where start and end is an positive integer for a
      fillable value. An example of a spec is "foo[0-9]".

  Returns:
    List of dictionaries of neighbor flags.
  """

    # This method searches for a pattern [start-end] in the spec. If the spec
    # contains this pattern, it is a numeric flag. Otherwise it is a boolean flag.
    # For example, -finline-limit=[1-1000] is a numeric flag and -falign-jumps is
    # a boolean flag.
    numeric_flag_match = flags.Search(climb_spec)

    # If the flags do not contain the spec.
    if climb_spec not in flags_dict:
        results = flags_dict.copy()

        if numeric_flag_match:
            # Numeric flags.
            results[climb_spec] = Flag(climb_spec,
                                       int(numeric_flag_match.group('start')))
        else:
            # Boolean flags.
            results[climb_spec] = Flag(climb_spec)

        return [results]

    # The flags contain the spec.
    if not numeric_flag_match:
        # Boolean flags.
        results = flags_dict.copy()

        # Turn off the flag. A flag is turned off if it is not presented in the
        # flags_dict.
        del results[climb_spec]
        return [results]

    # Numeric flags.
    flag = flags_dict[climb_spec]

    # The value of the flag having spec.
    value = flag.GetValue()
    results = []

    if value + 1 < int(numeric_flag_match.group('end')):
        # If the value is not the end value, explore the value that is 1 larger than
        # the current value.
        neighbor = flags_dict.copy()
        neighbor[climb_spec] = Flag(climb_spec, value + 1)
        results.append(neighbor)

    if value > int(numeric_flag_match.group('start')):
        # If the value is not the start value, explore the value that is 1 lesser
        # than the current value.
        neighbor = flags_dict.copy()
        neighbor[climb_spec] = Flag(climb_spec, value - 1)
        results.append(neighbor)
    else:
        # Delete the value, i.e., turn off the flag. A flag is turned off if it is
        # not presented in the flags_dict.
        neighbor = flags_dict.copy()
        del neighbor[climb_spec]
        results.append(neighbor)

    return results