Example #1
0
 def test_cost_exterior(self):
     self.MY_SEED = 101
     problem, inputs = generate_random_problem(self.MY_SEED)
     print(problem.edges)
     print(get_level_sets(problem.partial_order))
     print(generate_entire_program(inputs, problem))
     print(list(problem.partial_order.edges))
Example #2
0
 def test_cost_small_vars_many_expressions(self):
     self.MY_SEED = 101
     problem, inputs = generate_random_problem(self.MY_SEED, 20, 4)
     print(problem.edges)
     print(get_level_sets(problem.partial_order))
     print(generate_entire_program(inputs, problem))
     print(list(problem.partial_order.edges))
Example #3
0
def compute_greedy_order(problem, edges_prime, decided_tiling, b, eta):
    gamma = {}
    level_sets = detail.get_level_sets(problem.partial_order)
    last_level_set = level_sets[-1]
    for edge_name in last_level_set & edges_prime:
        gamma[edge_name] = get_edge_min_cost(problem, edge_name,
                                             decided_tiling)

    for level_set in reversed(level_sets[1:-1]):
        for edge_name in level_set & edges_prime:
            gamma[edge_name] = get_edge_min_cost(problem, edge_name, decided_tiling) \
                               + sum_descendants(problem, edge_name, gamma)
    assert len(gamma) == len(
        edges_prime), "Something went wrong with compute greedy order"
    i = 0
    sorted_eps = list(gamma.items())
    sorted_eps = [(elem[1], elem[0]) for elem in sorted_eps]
    sorted_eps.sort(reverse=True)
    edges_double_prime = set()
    while len(edges_double_prime) < b and i < len(sorted_eps):
        if sorted_eps[i][0] >= eta * sorted_eps[0][0]:
            edges_double_prime.add(sorted_eps[i][1])
        else:
            return edges_double_prime
        i += 1
    return edges_double_prime
Example #4
0
def find_local_solution(problem):
    assigned = {var_name: False for var_name in problem.variables}
    retile_cost = 0.0
    for level_set in detail.get_level_sets(problem.partial_order)[1:]:
        level_set_sortable = [(problem.edges[edge_name].program_index,
                               edge_name) for edge_name in level_set]
        level_set_sortable.sort()
        for index, edge_name in level_set_sortable:
            edge = problem.edges[edge_name]
            cost_dict = edge.get_cost_dict()
            # Basically MAX_INT
            min_cost = sys.maxsize
            local_vars = [
                problem.variables[var_name] for var_name in edge.vars
            ]
            for alg in edge.options:
                cost_table = cost_dict[alg]()
                #print(cost_table)
                # There is no real protection here from reassigning
                # variable's tiling, outside of that variable's name
                # being present in assigned, we might want to add some
                # extra protection for that
                choices = [
                    var.idx if assigned[var.name] else None
                    for var in local_vars
                ]
                reduction = 0
                for i in range(len(choices)):
                    if choices[i] is not None:
                        cost_table = cost_table.take(indices=choices[i],
                                                     axis=i - reduction)
                        reduction += 1

                if not isinstance(cost_table, np.ndarray):
                    tmp_cost = cost_table
                else:
                    tmp_cost = cost_table.min()

                if tmp_cost < min_cost:
                    min_cost = tmp_cost
                    min_loc = np.unravel_index(cost_table.argmin(),
                                               cost_table.shape)
                    edge.set_idx_with_val(alg)
                    count = 0
                    for i in range(len(choices)):
                        if choices[i] is None:
                            var_stripped_idx = edge.vars.index(
                                local_vars[i].name)
                            var_non_stripped_name = edge._vars[
                                var_stripped_idx]
                            if var_non_stripped_name[-1] == 'T':
                                local_vars[i].idx = (min_loc[count] + 1) % 2
                            else:
                                local_vars[i].idx = min_loc[count]
                            count += 1
            for var_name in edge.vars:
                assigned[var_name] = True
    return problem
    def test_problem_supplied_size_four_tests(self):
        self.MY_SEED = 101
        num_expressions = 80
        num_input_vars = 30
        problem, inputs = generate_random_problem(self.MY_SEED, num_expressions, num_input_vars)

        print(problem.edges)
        print(get_level_sets(problem.partial_order))
        print(generate_entire_program(inputs, problem))
        print(list(problem.partial_order.edges))
        run_four_tests([], [], verbosity=1, prob=problem, skip_real_exhaustive=True)
Example #6
0
def generate_entire_program(inputs, problem):
    # TODO add some functionality for obtaining
    # level sets of variables from the edge graph
    small_dim = 100
    large_dim = 3000
    dimension_map = {MatrixSize.small_small: (small_dim, small_dim),
                     MatrixSize.small_large: (small_dim, large_dim),
                     MatrixSize.large_small: (large_dim, small_dim),
                     MatrixSize.large_large: (large_dim, large_dim)}
    program = ""
    for i in inputs:
        row_dim, col_dim = dimension_map[problem.variables[i].size]
        program += (str(i)+" = np.random("+str(row_dim)+", "+str(col_dim)+")\n")
    for i in get_level_sets(problem.partial_order)[1:]:
        while len(i) > 0:
            elem = random.choice(list(i))
            i.remove(elem)
            program += (str(problem.edges[elem])+'\n')
    return program
Example #7
0
 def init_variables(self, vertex_sizes, duplicate_outputs, initial_locality_distribution, variables=None):
     if variables is not None:
         self.variables = variables
         return
     # Initialize all of the variables in the input layer
     for i in range(len(vertex_sizes)):
         for var in vertex_sizes[i]:
             if not self.even_dist and var in \
                     initial_locality_distribution.keys():
                 dist = initial_locality_distribution[var]
             else:
                 dist = []
             self.variables[var] = Vertex(var, MatrixSize(i + 1), 0, 'row', dist)
     # The first level set is the artificial '_begin_' node
     for level_set in detail.get_level_sets(self.partial_order)[1:]:
         for edge_name in level_set:
             edge = self.edges[edge_name]
             output_size_func = self.get_output_size_calculator(edge)
             operands = [self.get_size_and_distribution(k)
                         for k in edge._inputs]
             generation = duplicate_outputs[edge.output].index(edge)
             # TODO - Might be worthwhile to verify that this output
             # only happens once in this level_set as output,
             # otherwise we're doing something wrong in the dependency
             # graph generation. But maybe that should just be a test?
             out_size, out_dist = output_size_func(operands)
             var_name = edge.output+str(generation)
             # This is a temporary measure. We might want to do more nuanced
             # analyses where we discriminate between reassignments. If so,
             # this should be a higher level config setting
             use_duplicates = False
             if use_duplicates:
                 self.variables[var_name] = Vertex(var_name, out_size, generation, 'row', out_dist)
             else:
                 if edge.output not in self.variables.keys():
                     self.variables[edge.output] = Vertex(edge.output, out_size,
                                                          0, 'row',
                                                          out_dist)
Example #8
0
 def test_sub_problem_level_sets(self):
     sub_edges = ['_begin_', 'add0', 'mul2']
     sub_prob = self.get_sub_problem(sub_edges)
     level_sets = detail.get_level_sets(sub_prob.partial_order)
     self.assertEqual(level_sets, [{'_begin_'}, {'add0', 'mul2'}])
Example #9
0
 def test_level_sets(self):
     level_sets = detail.get_level_sets(self.problem.partial_order)
     self.assertEqual(
         level_sets,
         [{'_begin_'}, {'add0', 'mul4', 'mul2'}, {'add3', 'add1'}])