Esempio n. 1
0
def analyze_dependence(program):
    program_w_attributes = assign_node_ids(program)
    graph = DependenceGraph()
    for (ref1, ref2) in iterate_unique_reference_pairs(program_w_attributes):
        for dependence_dv in iterate_dependence_direction_vectors(ref1, ref2):
            for ref1_then_ref2_dv in iterate_execution_order_direction_vector(
                    ref1, ref2):
                logger.debug(
                    f'Testing:\n'
                    f'{ref1.pprint()} -> {ref2.pprint()}:, '
                    f'dep({dependence_dv}) exe_order({ref1_then_ref2_dv})')
                dv1 = calculate_valid_direction_vector(dependence_dv,
                                                       ref1_then_ref2_dv)
                if dv1 is not None:
                    logger.debug(f'Valid direction vector: {dv1}')
                    graph.add(ref1, ref2, dv1)

            dependence_dv_inv = negate_direction_vector(dependence_dv)
            for ref2_then_ref1_dv in iterate_execution_order_direction_vector(
                    ref2, ref1):
                logger.debug(
                    f'Testing:\n'
                    f'{ref2.pprint()} -> {ref2.pprint()}:, '
                    f'dep({dependence_dv_inv}) exe_order({ref2_then_ref1_dv})')
                dv2 = calculate_valid_direction_vector(dependence_dv_inv,
                                                       ref2_then_ref1_dv)
                if dv2 is not None:
                    logger.debug(f'Valid direction vector: {dv2}')
                    graph.add(ref2, ref1, dv2)
    return graph, program_w_attributes
Esempio n. 2
0
class LoopFusion(Transform):
  def pre_apply(self, fn):    
    self.graph = DependenceGraph()
    self.graph.visit_fn(fn)
    self.waiting = self.graph.nodes
    self.added = set([])
    self.scopes = []
    
  def post_apply(self, fn):
    if len(self.waiting) != 0:
      print "Statement nodes not added:"
      for stmt_node in self.waiting:
        print " -- ", stmt_node 
      assert False, "Not all statements added back to program!"
    
  def transform_block(self, old_stmts):
    """
    Do an extremely slow and inefficient topological sort 
    (change this later, now just prototyping)
    """
    first_iter = True 
    n_added = 0
    scope = id(old_stmts)
    self.scopes.append(scope)
    new_stmts = []
    while first_iter or n_added > 0:
      n_added = 0
      first_iter = False 
      for node in sorted(list(self.waiting)):
        if node.id not in self.added and \
           node.scope == scope and \
           all(node_id in self.added or node_id == node.id 
               for node_id in node.depends_on):
          self.waiting.remove(node)
          stmt = self.transform_stmt(node.stmt)
          new_stmts.append(stmt)
          self.added.add(node.id)  
          n_added += 1
    self.scopes.pop()
    return new_stmts 
Esempio n. 3
0
 def pre_apply(self, fn):    
   self.graph = DependenceGraph()
   self.graph.visit_fn(fn)
   self.waiting = self.graph.nodes
   self.added = set([])
   self.scopes = []