def ta_literal(self, fc, x, y): intervals = [Interval(x, 0, 0), Interval(y, 0, 0)] intervals_swap = [Interval(y, 0, 0), Interval(x, 0, 0)] fwd_ispace = IterationSpace(intervals, directions={ x: Forward, y: Forward }) fwd_ispace_swap = IterationSpace(intervals_swap, directions={ x: Forward, y: Forward }) mixed_ispace = IterationSpace(intervals, directions={ x: Backward, y: Forward }) tcxy_w0 = TimedAccess(fc[x, y], 'W', 0, fwd_ispace) tcxy_r0 = TimedAccess(fc[x, y], 'R', 0, fwd_ispace) tcx1y1_r1 = TimedAccess(fc[x + 1, y + 1], 'R', 1, fwd_ispace) tcx1y_r1 = TimedAccess(fc[x + 1, y], 'R', 1, fwd_ispace) rev_tcxy_w0 = TimedAccess(fc[x, y], 'W', 0, mixed_ispace) rev_tcx1y1_r1 = TimedAccess(fc[x + 1, y + 1], 'R', 1, mixed_ispace) tcyx_irr0 = TimedAccess(fc[y, x], 'R', 0, fwd_ispace) tcxx_irr1 = TimedAccess(fc[x, x], 'R', 0, fwd_ispace) tcxy_irr2 = TimedAccess(fc[x, y], 'R', 0, fwd_ispace_swap) return (tcxy_w0, tcxy_r0, tcx1y1_r1, tcx1y_r1, rev_tcxy_w0, rev_tcx1y1_r1, tcyx_irr0, tcxx_irr1, tcxy_irr2)
def test_intervals_subtract(self, x, y): nullx = NullInterval(x) # All nulls assert nullx.subtract(nullx) == nullx ix = Interval(x, 2, -2) # Mixed nulls and defined on the same dimension assert nullx.subtract(ix) == nullx assert ix.subtract(ix) == Interval(x, 0, 0) assert ix.subtract(nullx) == ix ix2 = Interval(x, 4, -4) ix3 = Interval(x, 6, -6) # All defined same dimension assert ix2.subtract(ix) == ix assert ix.subtract(ix2) == Interval(x, -2, 2) assert ix3.subtract(ix) == ix2 c = Constant(name='c') ix4 = Interval(x, c + 2, c + 4) ix5 = Interval(x, c + 1, c + 5) # All defined symbolic assert ix4.subtract(ix5) == Interval(x, 1, -1) assert ix5.subtract(ix4) == Interval(x, -1, 1) assert ix5.subtract(ix) == Interval(x, c - 1, c + 7)
def test_intervals_union(self): nullx = NullInterval(x) # All nulls assert nullx.union(nullx) == nullx ix = Interval(x, -2, 2) # Mixed nulls and defined on the same dimension assert nullx.union(ix) == ix assert ix.union(ix) == ix assert ix.union(nullx) == ix ix2 = Interval(x, 1, 4) ix3 = Interval(x, -3, 6) # All defined overlapping assert ix.union(ix2) == Interval(x, -2, 4) assert ix.union(ix3) == ix3 assert ix2.union(ix3) == ix3 ix4 = Interval(x, 4, 8) ix5 = Interval(x, -3, -3) ix6 = Interval(x, -10, -3) nully = NullInterval(y) iy = Interval(y, -2, 2) # Mixed disjoint (note: IntervalGroup input order is relevant) assert ix.union(ix4) == IntervalGroup([ix, ix4]) assert ix.union(ix5) == Interval(x, -3, 2) assert ix6.union(ix) == IntervalGroup([ix6, ix]) assert ix.union(nully) == IntervalGroup([ix, nully]) assert ix.union(iy) == IntervalGroup([ix, iy]) assert iy.union(ix) == IntervalGroup([iy, ix])
def ta_literal(self, fc): intervals = [Interval(x, 0, 0), Interval(y, 0, 0)] fwd_ispace = IterationSpace(intervals, directions={x: Forward, y: Forward}) mixed_ispace = IterationSpace(intervals, directions={x: Backward, y: Forward}) tcxy_w0 = TimedAccess(fc[x, y], 'W', 0, fwd_ispace) tcxy_r0 = TimedAccess(fc[x, y], 'R', 0, fwd_ispace) tcx1y1_r1 = TimedAccess(fc[x + 1, y + 1], 'R', 1, fwd_ispace) tcx1y_r1 = TimedAccess(fc[x + 1, y], 'R', 1, fwd_ispace) rev_tcxy_w0 = TimedAccess(fc[x, y], 'W', 0, mixed_ispace) rev_tcx1y1_r1 = TimedAccess(fc[x + 1, y + 1], 'R', 1, mixed_ispace) return tcxy_w0, tcxy_r0, tcx1y1_r1, tcx1y_r1, rev_tcxy_w0, rev_tcx1y1_r1
def test_intervals_switch(self, x, y): nullx = NullInterval(x) nully = NullInterval(y) assert nullx.switch(y) == nully ix = Interval(x, 2, -2) iy = Interval(y, 2, -2) assert ix.switch(y) == iy assert iy.switch(x) == ix assert ix.switch(y).switch(x) == ix
def test_intervals_intersection(self): nullx = NullInterval(x) # All nulls assert nullx.intersection(nullx) == nullx nully = NullInterval(y) ix = Interval(x, -2, 2) iy = Interval(y, -2, 2) # Mixed nulls and defined assert nullx.intersection(ix) == nullx assert nullx.intersection(iy) == nullx assert nullx.intersection(iy) != nully assert nully.intersection(iy) == nully ix2 = Interval(x, -8, -3) ix3 = Interval(x, 3, 4) # All defined disjoint assert ix.intersection(ix2) == nullx assert ix.intersection(ix3) == nullx assert ix2.intersection(ix3) == nullx assert ix.intersection(iy) == nullx assert iy.intersection(ix) == nully ix4 = Interval(x, 1, 4) ix5 = Interval(x, -3, 0) # All defined overlapping assert ix.intersection(ix4) == Interval(x, 1, 2) assert ix.intersection(ix5) == Interval(x, -2, 0)
def compute_intervals(expr): """Return an iterable of :class:`Interval`s representing the data items accessed by the :class:`sympy.Eq` ``expr``.""" # Detect the indexeds' offsets along each dimension stencil = Stencil() for e in retrieve_indexed(expr, mode='all', deep=True): for a in e.indices: if isinstance(a, Dimension): stencil[a].update([0]) d = None off = [0] for i in a.args: if isinstance(i, Dimension): d = i elif i.is_integer: off += [int(i)] if d is not None: stencil[d].update(off) # Determine intervals and their iterators iterators = OrderedDict() for i in stencil.dimensions: if i.is_NonlinearDerived: iterators.setdefault(i.parent, []).append(stencil.entry(i)) else: iterators.setdefault(i, []) intervals = [] for k, v in iterators.items(): offs = set.union(set(stencil.get(k)), *[i.ofs for i in v]) intervals.append(Interval(k, min(offs), max(offs))) return intervals, iterators
def build_intervals(stencil): """ Given a Stencil, return an iterable of Intervals, one for each Dimension in the stencil. """ mapper = {} for d, offs in stencil.items(): dim = d.parent if d.is_NonlinearDerived else d mapper.setdefault(dim, set()).update(offs) return [Interval(d, min(offs), max(offs)) for d, offs in mapper.items()]
def test_intervals_subtract(self): nullx = NullInterval(x) # All nulls assert nullx.subtract(nullx) == nullx ix = Interval(x, 2, -2) # Mixed nulls and defined on the same dimension assert nullx.subtract(ix) == nullx assert ix.subtract(ix) == Interval(x, 0, 0) assert ix.subtract(nullx) == ix ix2 = Interval(x, 4, -4) ix3 = Interval(x, 6, -6) # All defined same dimension assert ix2.subtract(ix) == ix assert ix.subtract(ix2) == Interval(x, -2, 2) assert ix3.subtract(ix) == ix2
def build_intervals(stencil): """ Given a Stencil, return an iterable of Intervals, one for each Dimension in the stencil. """ mapper = defaultdict(set) for d, offs in stencil.items(): if d.is_Stepping: mapper[d.root].update(offs) elif d.is_Conditional: mapper[d.parent].update(offs) elif d.is_Modulo: mapper[d.root].update({d.offset - d.root + i for i in offs}) else: mapper[d].update(offs) return [Interval(d, min(offs), max(offs)) for d, offs in mapper.items()]
def build_intervals(stencil): """ Given ``stencil``, an object of type :class`Stencil`, return: :: * An iterable of :class:`Interval`s, one for each :class:`Dimension` in ``stencil``. * A dictionary of ``iterators``, suitable to build an :class:`IterationSpace`. """ iterators = OrderedDict() for i in stencil.dimensions: if i.is_NonlinearDerived: iterators.setdefault(i.parent, []).append(stencil.entry(i)) else: iterators.setdefault(i, []) intervals = [] for k, v in iterators.items(): offs = set.union(set(stencil.get(k)), *[i.ofs for i in v]) intervals.append(Interval(k, min(offs), max(offs))) return intervals, iterators
def build_intervals(mapper): """ Given M as produced by :func:`detect_accesses`, return: :: * An iterable of :class:`Interval`s, representing the data items accessed in each :class:`Dimension` in M; * A dictionary of ``iterators``, suitable to build an :class:`IterationSpace`. """ iterators = OrderedDict() stencil = Stencil.union(*mapper.values()) for i in stencil.dimensions: if i.is_NonlinearDerived: iterators.setdefault(i.parent, []).append(stencil.entry(i)) else: iterators.setdefault(i, []) intervals = [] for k, v in iterators.items(): offs = set.union(set(stencil.get(k)), *[i.ofs for i in v]) intervals.append(Interval(k, min(offs), max(offs))) return intervals, iterators
def test_intervals_merge(self): nullx = NullInterval(x) # All nulls assert nullx.merge(nullx) == nullx ix = Interval(x, -2, 2) # Mixed nulls and defined on the same dimension assert nullx.merge(ix) == ix assert ix.merge(ix) == ix assert ix.merge(nullx) == ix ix2 = Interval(x, 1, 4) ix3 = Interval(x, -3, 6) # All defined overlapping assert ix.merge(ix2) == Interval(x, -2, 4) assert ix.merge(ix3) == ix3 assert ix2.merge(ix3) == ix3 ix4 = Interval(x, 0, 0) ix5 = Interval(x, -1, -1) ix6 = Interval(x, 9, 11) # Non-overlapping assert ix.merge(ix4) == Interval(x, -2, 2) assert ix.merge(ix5) == Interval(x, -2, 2) assert ix4.merge(ix5) == Interval(x, -1, 0) assert ix.merge(ix6) == Interval(x, -2, 11) assert ix6.merge(ix) == Interval(x, -2, 11) assert ix5.merge(ix6) == Interval(x, -1, 11)
def boxify(self): """ Create a :class:`IntervalGroup` from ``self``, with as many intervals as dimensions in ``self``. """ return IntervalGroup([Interval(k, min(v), max(v)) for k, v in self.items()])
def test_intervals_union(self): nullx = NullInterval(x) # All nulls assert nullx.union(nullx) == nullx ix = Interval(x, -2, 2) # Mixed nulls and defined assert nullx.union(ix) == ix assert ix.union(ix) == ix assert ix.union(nullx) == ix ix2 = Interval(x, 1, 4) ix3 = Interval(x, -3, 6) assert ix.union(ix2) == Interval(x, -2, 4) assert ix.union(ix3) == ix3 assert ix2.union(ix3) == ix3 ix4 = Interval(x, 4, 8) ix5 = Interval(x, -3, -3) ix6 = Interval(x, -10, -3) nully = NullInterval(y) iy = Interval(y, -2, 2) assert ix.union(ix4) == Interval(x, -2, 8) assert ix.union(ix5) == Interval(x, -3, 2) assert ix6.union(ix) == Interval(x, -10, 2) assert ix.union(nully) == IntervalGroup([ix, nully]) assert ix.union(iy) == IntervalGroup([ix, iy]) assert iy.union(ix) == IntervalGroup([iy, ix]) # Mixed symbolic and non-symbolic c = Constant(name='c') ix7 = Interval(x, c, c + 4) ix8 = Interval(x, c - 1, c + 5) assert ix7.union(ix8) == Interval(x, c - 1, c + 5) assert ix8.union(ix7) == Interval(x, c - 1, c + 5) # Symbolic with properties s = Scalar(name='s', nonnegative=True) ix9 = Interval(x, s - 2, s + 2) ix10 = Interval(x, s - 1, s + 1) assert ix.union(ix9) == Interval(x, -2, s + 2) assert ix9.union(ix) == Interval(x, -2, s + 2) assert ix9.union(ix10) == ix9 assert ix10.union(ix9) == ix9
def boxify(self): """ Create a :class:`Space` from ``self``, with as many intervals as dimensions. """ return Space([Interval(k, min(v), max(v)) for k, v in self.items()])
def test_intervals_intersection(self, x, y): nullx = NullInterval(x) # All nulls assert nullx.intersection(nullx) == nullx nully = NullInterval(y) ix = Interval(x, -2, 2) iy = Interval(y, -2, 2) # Mixed nulls and defined assert nullx.intersection(ix) == nullx assert nullx.intersection(iy) == nullx assert nullx.intersection(iy) != nully assert nully.intersection(iy) == nully ix2 = Interval(x, -8, -3) ix3 = Interval(x, 3, 4) assert ix.intersection(ix2) == Interval(x, -2, -3) assert ix.intersection(ix3) == Interval(x, 3, 2) assert ix2.intersection(ix3) == Interval(x, 3, -3) assert ix.intersection(iy) == nullx assert iy.intersection(ix) == nully ix4 = Interval(x, 1, 4) ix5 = Interval(x, -3, 0) assert ix.intersection(ix4) == Interval(x, 1, 2) assert ix.intersection(ix5) == Interval(x, -2, 0) # Mixed symbolic and non-symbolic c = Constant(name='c') ix6 = Interval(x, c, c + 4) ix7 = Interval(x, c - 1, c + 5) assert ix6.intersection(ix7) == Interval(x, c, c + 4) assert ix7.intersection(ix6) == Interval(x, c, c + 4) # Symbolic with properties s = Scalar(name='s', nonnegative=True) ix8 = Interval(x, s - 2, s + 2) ix9 = Interval(x, s - 1, s + 1) assert ix.intersection(ix8) == Interval(x, s - 2, 2) assert ix8.intersection(ix) == Interval(x, s - 2, 2) assert ix8.intersection(ix9) == Interval(x, s - 1, s + 1) assert ix9.intersection(ix8) == Interval(x, s - 1, s + 1)
def test_intervals_union(self, x, y): nullx = NullInterval(x) # All nulls assert nullx.union(nullx) == nullx ix = Interval(x, -2, 2) # Mixed nulls and defined assert nullx.union(ix) == ix assert ix.union(ix) == ix assert ix.union(nullx) == ix ix2 = Interval(x, 1, 4) ix3 = Interval(x, -3, 6) assert ix.union(ix2) == Interval(x, -2, 4) assert ix.union(ix3) == ix3 assert ix2.union(ix3) == ix3 ix4 = Interval(x, 4, 8) ix5 = Interval(x, -3, -3) ix6 = Interval(x, -10, -3) nully = NullInterval(y) iy = Interval(y, -2, 2) assert ix.union(ix4) == Interval(x, -2, 8) assert ix.union(ix5) == Interval(x, -3, 2) assert ix6.union(ix) == Interval(x, -10, 2) # The union of non-compatible Intervals isn't possible, and an exception # is expected ixs1 = Interval(x, -2, 2, stamp=1) for i, j in [(ix, nully), (ix, iy), (iy, ix), (ix, ixs1), (ixs1, ix)]: try: i.union(j) assert False # Shouldn't arrive here except ValueError: assert True except: # No other types of exception expected assert False # Mixed symbolic and non-symbolic c = Constant(name='c') ix7 = Interval(x, c, c + 4) ix8 = Interval(x, c - 1, c + 5) assert ix7.union(ix8) == Interval(x, c - 1, c + 5) assert ix8.union(ix7) == Interval(x, c - 1, c + 5) # Symbolic with properties s = Scalar(name='s', nonnegative=True) ix9 = Interval(x, s - 2, s + 2) ix10 = Interval(x, s - 1, s + 1) assert ix.union(ix9) == Interval(x, -2, s + 2) assert ix9.union(ix) == Interval(x, -2, s + 2) assert ix9.union(ix10) == ix9 assert ix10.union(ix9) == ix9