def stree_section(stree): """ Add NodeSections to a ScheduleTree. A NodeSection, or simply "section", defines a sub-tree with the following properties: * The root is a node of type NodeSection; * The immediate children of the root are nodes of type NodeIteration; * The Dimensions of the immediate children are either: * identical, OR * different, but all of type SubDimension; * The Dimension of the immediate children cannot be a TimeDimension. """ class Section(object): def __init__(self, node): self.parent = node.parent try: self.dim = node.dim except AttributeError: self.dim = None self.nodes = [node] def is_compatible(self, node): return self.parent == node.parent and self.dim.root == node.dim.root # Search candidate sections sections = [] for i in range(stree.height): # Find all sections at depth `i` section = None for n in findall(stree, filter_=lambda n: n.depth == i): if any(p in flatten(s.nodes for s in sections) for p in n.ancestors): # Already within a section continue elif n.is_Sync: # SyncNodes are self-contained sections.append(Section(n)) section = None elif n.is_Iteration: if n.dim.is_Time and SEQUENTIAL in n.properties: # If n.dim.is_Time, we end up here in 99.9% of the cases. # Sometimes, however, time is a PARALLEL Dimension (e.g., # think of `norm` Operators) section = None elif section is None or not section.is_compatible(n): section = Section(n) sections.append(section) else: section.nodes.append(n) else: section = None # Transform the schedule tree by adding in sections for i in sections: insert(NodeSection(), i.parent, i.nodes) return stree
def section(stree): """ Create sections in a :class:`ScheduleTree`. A section is a sub-tree with the following properties: :: * The root is a node of type :class:`NodeSection`; * The immediate children of the root are nodes of type :class:`NodeIteration` and have same parent. * The :class:`Dimension` of the immediate children are either: :: * identical, OR * different, but all of type :class:`SubDimension`; * The :class:`Dimension` of the immediate children cannot be a :class:`TimeDimension`. """ class Section(object): def __init__(self, node): self.parent = node.parent self.dim = node.dim self.nodes = [node] def is_compatible(self, node): return (self.parent == node.parent and (self.dim == node.dim or node.dim.is_Sub)) # Search candidate sections sections = [] for i in range(stree.height): # Find all sections at depth `i` section = None for n in findall(stree, filter_=lambda n: n.depth == i): if any(p in flatten(s.nodes for s in sections) for p in n.ancestors): # Already within a section continue elif not n.is_Iteration or n.dim.is_Time: section = None elif section is None or not section.is_compatible(n): section = Section(n) sections.append(section) else: section.nodes.append(n) # Transform the schedule tree by adding in sections for i in sections: node = NodeSection() processed = [] for n in list(i.parent.children): if n in i.nodes: n.parent = node if node not in processed: processed.append(node) else: processed.append(n) i.parent.children = processed return stree
def st_section(stree): """ Add NodeSections to a ScheduleTree. A NodeSection, or simply "section", defines a sub-tree with the following properties: * The root is a node of type NodeSection; * The immediate children of the root are nodes of type NodeIteration; * The Dimensions of the immediate children are either: * identical, OR * different, but all of type SubDimension; * The Dimension of the immediate children cannot be a TimeDimension. """ class Section(object): def __init__(self, node): self.parent = node.parent self.dim = node.dim self.nodes = [node] def is_compatible(self, node): return self.parent == node.parent and self.dim.root == node.dim.root # Search candidate sections sections = [] for i in range(stree.height): # Find all sections at depth `i` section = None for n in findall(stree, filter_=lambda n: n.depth == i): if any(p in flatten(s.nodes for s in sections) for p in n.ancestors): # Already within a section continue elif not n.is_Iteration or n.dim.is_Time: section = None elif section is None or not section.is_compatible(n): section = Section(n) sections.append(section) else: section.nodes.append(n) # Transform the schedule tree by adding in sections for i in sections: insert(NodeSection(), i.parent, i.nodes) return stree