def _optimize_schedule_rotations(schedule, sregistry):
    '\n    Transform the schedule such that the tensor temporaries "rotate" along\n    the outermost Dimension. This trades a parallel Dimension for a smaller\n    working set size.\n    '
    ridx = 0
    rmapper = defaultdict(list)
    processed = []
    for (k, group) in groupby(schedule, key=(lambda i: i.writeto)):
        g = list(group)
        candidate = k[ridx]
        d = candidate.dim
        try:
            ds = schedule.dmapper[d]
        except KeyError:
            processed.extend(g)
            continue
        n = candidate.min_size
        assert (n > 0)
        iis = candidate.lower
        iib = candidate.upper
        ii = ModuloDimension(('%sii' % d), ds, iis, incr=iib)
        cd = CustomDimension(name=('%s%s' % (d, d)), symbolic_min=ii, symbolic_max=iib, symbolic_size=n)
        dsi = ModuloDimension(('%si' % ds), cd, ((cd + ds) - iis), n)
        mapper = OrderedDict()
        for i in g:
            mds = []
            for indices in i.indicess:
                v = indices[ridx]
                try:
                    md = mapper[v]
                except KeyError:
                    name = sregistry.make_name(prefix=('%sr' % d.name))
                    md = mapper.setdefault(v, ModuloDimension(name, ds, v, n))
                mds.append(md)
            indicess = [((indices[:ridx] + [md]) + indices[(ridx + 1):]) for (md, indices) in zip(mds, i.indicess)]
            intervals = k.intervals.switch(d, dsi).zero(dsi)
            sub_iterators = dict(k.sub_iterators)
            sub_iterators[d] = dsi
            writeto = IterationSpace(intervals, sub_iterators)
            alias = i.alias.xreplace({d: (d + cd)})
            d1 = writeto[(ridx + 1)].dim
            intervals = IntervalGroup(Interval(cd, 0, 0), relations={(d, cd, d1)})
            rispace = IterationSpace(intervals, {cd: dsi}, {cd: Forward})
            aispace = i.ispace.zero(d)
            aispace = aispace.augment({d: (mds + [ii])})
            ispace = IterationSpace.union(rispace, aispace)
            processed.append(ScheduledAlias(alias, writeto, ispace, i.aliaseds, indicess))
        rmapper[d].extend(list(mapper.values()))
    return Schedule(*processed, dmapper=schedule.dmapper, rmapper=rmapper)
Transform the schedule such that the tensor temporaries "rotate" along
the outermost Dimension. This trades a parallel Dimension for a smaller
working set size.
def _optimize_schedule_rotations(schedule, sregistry):
    '\n    Transform the schedule such that the tensor temporaries "rotate" along\n    the outermost Dimension. This trades a parallel Dimension for a smaller\n    working set size.\n    '
    ridx = 0
    rmapper = defaultdict(list)
    processed = []
    for (k, group) in groupby(schedule, key=(lambda i: i.writeto)):
        g = list(group)
        candidate = k[ridx]
        d = candidate.dim
        try:
            ds = schedule.dmapper[d]
        except KeyError:
            processed.extend(g)
            continue
        n = candidate.min_size
        assert (n > 0)
        iis = candidate.lower
        iib = candidate.upper
        ii = ModuloDimension(('%sii' % d), ds, iis, incr=iib)
        cd = CustomDimension(name=('%s%s' % (d, d)), symbolic_min=ii, symbolic_max=iib, symbolic_size=n)
        dsi = ModuloDimension(('%si' % ds), cd, ((cd + ds) - iis), n)
        mapper = OrderedDict()
        for i in g:
            mds = []
            for indices in i.indicess:
                v = indices[ridx]
                try:
                    md = mapper[v]
                except KeyError:
                    name = sregistry.make_name(prefix=('%sr' % d.name))
                    md = mapper.setdefault(v, ModuloDimension(name, ds, v, n))
                mds.append(md)
            indicess = [((indices[:ridx] + [md]) + indices[(ridx + 1):]) for (md, indices) in zip(mds, i.indicess)]
            intervals = k.intervals.switch(d, dsi).zero(dsi)
            sub_iterators = dict(k.sub_iterators)
            sub_iterators[d] = dsi
            writeto = IterationSpace(intervals, sub_iterators)
            alias = i.alias.xreplace({d: (d + cd)})
            d1 = writeto[(ridx + 1)].dim
            intervals = IntervalGroup(Interval(cd, 0, 0), relations={(d, cd, d1)})
            rispace = IterationSpace(intervals, {cd: dsi}, {cd: Forward})
            aispace = i.ispace.zero(d)
            aispace = aispace.augment({d: (mds + [ii])})
            ispace = IterationSpace.union(rispace, aispace)
            processed.append(ScheduledAlias(alias, writeto, ispace, i.aliaseds, indicess))
        rmapper[d].extend(list(mapper.values()))
    return Schedule(*processed, dmapper=schedule.dmapper, rmapper=rmapper)