Exemplo n.º 1
0
def clusterize(exprs):
    """Group a sequence of :class:`ir.Eq`s into one or more :class:`Cluster`s."""

    # Build a graph capturing the dependencies among the input tensor expressions
    mapper = OrderedDict()
    for i, e1 in enumerate(exprs):
        trace = [e2 for e2 in exprs[:i] if Scope([e2, e1]).has_dep] + [e1]
        trace.extend([e2 for e2 in exprs[i + 1:] if Scope([e1, e2]).has_dep])
        mapper[e1] = Bunch(trace=trace, ispace=e1.ispace)

    # Derive the iteration spaces
    queue = list(mapper)
    while queue:
        target = queue.pop(0)

        ispaces = [mapper[i].ispace for i in mapper[target].trace]

        coerced_ispace = mapper[target].ispace.intersection(*ispaces)

        if coerced_ispace != mapper[target].ispace:
            # Something has changed, need to propagate the update
            mapper[target].ispace = coerced_ispace
            queue.extend([i for i in mapper[target].trace if i not in queue])

    # Build a PartialCluster for each tensor expression
    clusters = ClusterGroup()
    for k, v in mapper.items():
        if k.is_Tensor:
            scalars = [i for i in v.trace[:v.trace.index(k)] if i.is_Scalar]
            clusters.append(PartialCluster(scalars + [k], v.ispace))

    # Group PartialClusters together where possible
    clusters = groupby(clusters)

    return clusters.finalize()
Exemplo n.º 2
0
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()
Exemplo n.º 3
0
def clusterize(exprs):
    """Group a sequence of :class:`ir.Eq`s into one or more :class:`Cluster`s."""

    # Group expressions based on data dependences
    groups = group_expressions(exprs)

    clusters = ClusterGroup()
    for g in groups:
        # Coerce iteration space of each expression in each group
        mapper = OrderedDict([(e, e.ispace) for e in g])
        flowmap = detect_flow_directions(g)
        queue = list(g)
        while queue:
            v = queue.pop(0)

            intervals, sub_iterators, directions = mapper[v].args
            forced, clashes = force_directions(flowmap,
                                               lambda i: directions.get(i))
            for e in g:
                intervals = intervals.intersection(
                    mapper[e].intervals.drop(clashes))
            directions = {i: forced[i] for i in directions}
            coerced_ispace = IterationSpace(intervals, sub_iterators,
                                            directions)

            # Need update propagation ?
            if coerced_ispace != mapper[v]:
                mapper[v] = coerced_ispace
                queue.extend([i for i in g if i not in queue])

        # Wrap each tensor expression in a PartialCluster
        for k, v in mapper.items():
            if k.is_Tensor:
                scalars = [i for i in g[:g.index(k)] if i.is_Scalar]
                clusters.append(PartialCluster(scalars + [k], v))

    # Group PartialClusters together where possible
    clusters = groupby(clusters)

    # Introduce conditional PartialClusters
    clusters = guard(clusters)

    return clusters.finalize()
def clusterize(exprs):
    """Group a sequence of :class:`ir.Eq`s into one or more :class:`Cluster`s."""
    # Group expressions based on data dependences
    groups = group_expressions(exprs)

    clusters = ClusterGroup()

    # Coerce iteration direction of each expression in each group
    for g in groups:
        mapper = OrderedDict([(e, e.directions) for e in g])
        flowmap = detect_flow_directions(g)
        queue = list(g)
        while queue:
            k = queue.pop(0)
            directions, _ = force_directions(flowmap,
                                             lambda i: mapper[k].get(i))
            directions = {i: directions[i] for i in mapper[k]}
            # Need update propagation ?
            if directions != mapper[k]:
                mapper[k] = directions
                queue.extend([i for i in g if i not in queue])

        # Wrap each tensor expression in a PartialCluster
        for k, v in mapper.items():
            if k.is_Tensor:
                scalars = [i for i in g[:g.index(k)] if i.is_Scalar]
                intervals, sub_iterators, _ = k.ispace.args
                ispace = IterationSpace(intervals, sub_iterators, v)
                clusters.append(PartialCluster(scalars + [k], ispace,
                                               k.dspace))

    # Group PartialClusters together where possible
    clusters = groupby(clusters)

    # Introduce conditional PartialClusters
    clusters = guard(clusters)

    return clusters.finalize()
Exemplo n.º 5
0
def clusterize(exprs):
    """Group a sequence of LoweredEqs into one or more Clusters."""
    clusters = ClusterGroup()

    # Wrap each LoweredEq in `exprs` within a PartialCluster. The PartialCluster's
    # iteration direction is enforced based on the iteration direction of the
    # surrounding LoweredEqs
    flowmap = detect_flow_directions(exprs)
    for e in exprs:
        directions, _ = force_directions(flowmap,
                                         lambda d: e.ispace.directions.get(d))
        ispace = IterationSpace(e.ispace.intervals, e.ispace.sub_iterators,
                                directions)

        clusters.append(PartialCluster(e, ispace, e.dspace))

    # Group PartialClusters together where possible
    clusters = groupby(clusters)

    # Introduce conditional PartialClusters
    clusters = guard(clusters)

    return clusters.finalize()