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))
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))
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
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)
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
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)
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'}])
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'}])