def clusterize(exprs): """ Group a sequence of :class:`ir.Eq`s into one or more :class:`Cluster`s. """ clusters = ClusterGroup() flowmap = detect_flow_directions(exprs) prev = None for idx, e in enumerate(exprs): if e.is_Tensor: scalars = [i for i in exprs[prev:idx] if i.is_Scalar] # Iteration space ispace = IterationSpace.merge(e.ispace, *[i.ispace for i in scalars]) # Enforce iteration directions fdirs, _ = force_directions(flowmap, lambda d: ispace.directions.get(d)) ispace = IterationSpace(ispace.intervals, ispace.sub_iterators, fdirs) # Data space dspace = DataSpace.merge(e.dspace, *[i.dspace for i in scalars]) # Prepare for next range prev = idx clusters.append(PartialCluster(scalars + [e], ispace, dspace)) # Group PartialClusters together where possible clusters = groupby(clusters) # Introduce conditional PartialClusters clusters = guard(clusters) return clusters.finalize()
def squash(self, other): """Concatenate the expressions in ``other`` to those in ``self``. ``self`` and ``other`` must have same ``ispace``. Duplicate expressions are dropped. The :class:`DataSpace` is updated accordingly.""" assert self.ispace.is_compatible(other.ispace) self.exprs.extend([i for i in other.exprs if i not in self.exprs]) self.dspace = DataSpace.merge(self.dspace, other.dspace) self.ispace = IterationSpace.merge(self.ispace, other.ispace)
def squash(self, other): """ Concatenate the expressions in ``other`` to those in ``self``. ``self`` and ``other`` must have same ``ispace``. Duplicate expressions are dropped. The DataSpace is updated accordingly. """ assert self.ispace.is_compatible(other.ispace) self.exprs.extend([i for i in other.exprs if i not in self.exprs or i.is_Increment]) self.dspace = DataSpace.merge(self.dspace, other.dspace) self.ispace = IterationSpace.merge(self.ispace, other.ispace)
def from_clusters(cls, *clusters): """ Build a new Cluster from a sequence of pre-existing Clusters with compatible IterationSpace. """ assert len(clusters) > 0 root = clusters[0] assert all(root.ispace.is_compatible(c.ispace) for c in clusters) exprs = chain(*[c.exprs for c in clusters]) ispace = IterationSpace.merge(*[c.ispace for c in clusters]) dspace = DataSpace.merge(*[c.dspace for c in clusters]) return Cluster(exprs, ispace, dspace)
def dspace(self): """Return the DataSpace of this ClusterGroup.""" return DataSpace.merge(*[i.dspace for i in self])
def dspace(self): """Return the cumulative :class:`DataSpace` of this ClusterGroup.""" return DataSpace.merge(*[i.dspace for i in self])