def retag(self, tag_value=None): """ Create a new Iteration object which is identical to ``self``, except for the tag. If provided, ``tag_value`` is used as new tag; otherwise, an internally generated tag is used. """ if self.tag is None: return self._rebuild() properties = [tagger(tag_value or (ntags() + 1)) if i.name == 'tag' else i for i in self.properties] return self._rebuild(properties=properties)
def unfold_blocked_tree(node): """ Unfold nested IterationFolds. Examples -------- Given a section of Iteration/Expression tree as below: :: for i = 1 to N-1 // folded for j = 1 to N-1 // folded foo1() Assuming a fold with offset 1 in both /i/ and /j/ and body ``foo2()``, create: :: for i = 1 to N-1 for j = 1 to N-1 foo1() for i = 2 to N-2 for j = 2 to N-2 foo2() """ # Search the unfolding candidates candidates = [] for tree in retrieve_iteration_tree(node): handle = tuple(i for i in tree if i.is_IterationFold) if handle: # Sanity check assert IsPerfectIteration().visit(handle[0]) candidates.append(handle) # Perform unfolding tag = ntags() mapper = {} for tree in candidates: trees = list(zip(*[i.unfold() for i in tree])) # Update tag for i, _tree in enumerate(list(trees)): trees[i] = tuple(j.retag(tag + i) for j in _tree) trees = optimize_unfolded_tree(trees[:-1], trees[-1]) mapper[tree[0]] = List(body=trees) # Insert the unfolded Iterations in the Iteration/Expression tree processed = Transformer(mapper).visit(node) return processed