forked from tinygrad/tinygrad
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
310ef10542 | ||
|
|
36d679196c | ||
|
|
a0fe1f68ec | ||
|
|
6e8ab4c742 | ||
|
|
7d0c5a74e4 | ||
|
|
bda35265b8 |
@@ -68,12 +68,14 @@ def realize_parents(ctx:dict[UOp, None], rb:UOp) -> None:
|
|||||||
|
|
||||||
def realize_assign(ctx:dict[UOp, None], a:UOp) -> None:
|
def realize_assign(ctx:dict[UOp, None], a:UOp) -> None:
|
||||||
if a.src[1].op not in ALWAYS_CONTIGUOUS: ctx[a.src[1]] = None
|
if a.src[1].op not in ALWAYS_CONTIGUOUS: ctx[a.src[1]] = None
|
||||||
|
# if it's a kernel, we don't realize it
|
||||||
|
if a.src[1].op is not Ops.KERNEL: ctx[a] = None
|
||||||
|
|
||||||
do_realize = PatternMatcher([
|
do_realize = PatternMatcher([
|
||||||
# always realize SINK parents
|
# always realize SINK parents
|
||||||
(UPat(Ops.SINK, name="s"), lambda ctx,s: ctx.update((x.base, None) for x in s.src if x.base.op not in ALWAYS_CONTIGUOUS)),
|
(UPat(Ops.SINK, name="s"), lambda ctx,s: ctx.update((x.base, None) for x in s.src if x.base.op not in ALWAYS_CONTIGUOUS)),
|
||||||
# always realize ASSIGN/COPY/BUFFER_VIEW/CONTIGUOUS
|
# always realize ASSIGN/COPY/BUFFER_VIEW/CONTIGUOUS
|
||||||
(UPat({Ops.ASSIGN, Ops.COPY, Ops.BUFFER_VIEW, Ops.CONTIGUOUS}, name="tr"), realize),
|
(UPat({Ops.COPY, Ops.BUFFER_VIEW, Ops.CONTIGUOUS}, name="tr"), realize),
|
||||||
# realize parents of COPY, MSELECT, MSTACK
|
# realize parents of COPY, MSELECT, MSTACK
|
||||||
(UPat((Ops.COPY, Ops.MSELECT, Ops.MSTACK), name="rb"), realize_parents),
|
(UPat((Ops.COPY, Ops.MSELECT, Ops.MSTACK), name="rb"), realize_parents),
|
||||||
# realize input to assign (might be optimized out)
|
# realize input to assign (might be optimized out)
|
||||||
@@ -125,7 +127,8 @@ class RangeifyContext:
|
|||||||
|
|
||||||
# create ranges
|
# create ranges
|
||||||
range_idx: Iterator[int] = field(default_factory=itertools.count)
|
range_idx: Iterator[int] = field(default_factory=itertools.count)
|
||||||
def new_range(self, s:sint, axistype:AxisType=AxisType.LOOP): return UOp.range(s, next(self.range_idx), axistype)
|
def new_range(self, s:sint, axistype:AxisType=AxisType.LOOP):
|
||||||
|
return UOp.range(s, next(self.range_idx), axistype) if resolve(s!=1) else UOp.const(dtypes.index, 0)
|
||||||
|
|
||||||
def map_reshape(idx:UOp, r:UOp):
|
def map_reshape(idx:UOp, r:UOp):
|
||||||
acc = 1
|
acc = 1
|
||||||
@@ -360,14 +363,15 @@ def cleanup_dead_axes(b:UOp):
|
|||||||
for s,rng in zip(b.shape, b.src[1:]):
|
for s,rng in zip(b.shape, b.src[1:]):
|
||||||
# skip for symbolic. TODO: fix this
|
# skip for symbolic. TODO: fix this
|
||||||
if rng.op is Ops.RANGE and rng.src[0].op is not Ops.CONST: return None
|
if rng.op is Ops.RANGE and rng.src[0].op is not Ops.CONST: return None
|
||||||
if rng not in b.src[0].sparents and rng.op is Ops.RANGE:
|
# CONSTs are already dead axes
|
||||||
|
if rng.op is Ops.CONST or (rng.op is Ops.RANGE and rng not in b.src[0].sparents):
|
||||||
reshape.append(1)
|
reshape.append(1)
|
||||||
hit = True
|
hit = True
|
||||||
else:
|
else:
|
||||||
reshape.append(s)
|
reshape.append(s)
|
||||||
new_rng.append(rng)
|
new_rng.append(rng)
|
||||||
if hit:
|
if hit:
|
||||||
# move the tag to the expand
|
# move the tag to the expand. NOTE: this expand tag might not survive
|
||||||
return b.replace(src=b.src[0:1]+tuple(new_rng), tag=None).reshape(tuple(reshape)).expand(b.shape).replace(tag=b.tag)
|
return b.replace(src=b.src[0:1]+tuple(new_rng), tag=None).reshape(tuple(reshape)).expand(b.shape).replace(tag=b.tag)
|
||||||
|
|
||||||
# if a buffer is being stored just for permutes or something, remove it
|
# if a buffer is being stored just for permutes or something, remove it
|
||||||
@@ -375,7 +379,7 @@ def cleanup_dead_axes(b:UOp):
|
|||||||
def remove_bufferize(src:UOp, buf:UOp, idx:UOp):
|
def remove_bufferize(src:UOp, buf:UOp, idx:UOp):
|
||||||
# see if we can't do it, should this ever hit?
|
# see if we can't do it, should this ever hit?
|
||||||
assert len(buf.src) == len(idx.src), "index on wrong bufferize"
|
assert len(buf.src) == len(idx.src), "index on wrong bufferize"
|
||||||
assert all(x.op is Ops.RANGE for x in buf.src[1:])
|
assert all(x.op in {Ops.RANGE, Ops.CONST} for x in buf.src[1:])
|
||||||
|
|
||||||
# if it's user contiguous, we never remove it
|
# if it's user contiguous, we never remove it
|
||||||
if src.op in ALWAYS_RUN_OPS: return None
|
if src.op in ALWAYS_RUN_OPS: return None
|
||||||
@@ -405,7 +409,8 @@ def remove_bufferize(src:UOp, buf:UOp, idx:UOp):
|
|||||||
|
|
||||||
# if it makes it here, the bufferize is removed
|
# if it makes it here, the bufferize is removed
|
||||||
# this is the ranges replaced
|
# this is the ranges replaced
|
||||||
return src.substitute(dict(zip(buf.src[1:], idx.src[1:])))
|
# NOTE: if buf src is a const, we don't replace it
|
||||||
|
return src.substitute({k:v for k,v in zip(buf.src[1:], idx.src[1:]) if k.op is not Ops.CONST})
|
||||||
|
|
||||||
def pre_bufferize(b:UOp, x:UOp, copy:UOp):
|
def pre_bufferize(b:UOp, x:UOp, copy:UOp):
|
||||||
nb = b.replace(src=(b.src[0].contiguous(),)+b.src[1:])
|
nb = b.replace(src=(b.src[0].contiguous(),)+b.src[1:])
|
||||||
@@ -513,8 +518,8 @@ def bufferize_to_store(x:UOp):
|
|||||||
ret = buf.reshape(shape).index(*rngs, dtype=sdtype).store(x.src[0], *rngs, dtype=x.dtype)
|
ret = buf.reshape(shape).index(*rngs, dtype=sdtype).store(x.src[0], *rngs, dtype=x.dtype)
|
||||||
ret = ret.forced_reshape(shape)
|
ret = ret.forced_reshape(shape)
|
||||||
# TODO: is this right? what if it's offset
|
# TODO: is this right? what if it's offset
|
||||||
if any(r.src[0].op is not Ops.RANGE for r in rngs):
|
if any(r.op is Ops.RANGE and r.src[0].op is not Ops.CONST for r in rngs):
|
||||||
sym_shape = tuple([ssimplify(r.src[0]) for r in rngs])
|
sym_shape = tuple([ssimplify(r.src[0]) if r.op is not Ops.CONST else 1 for r in rngs])
|
||||||
ret = ret.shrink(tuple([(0,x) for x in sym_shape]))
|
ret = ret.shrink(tuple([(0,x) for x in sym_shape]))
|
||||||
return ret.replace(tag=x.tag)
|
return ret.replace(tag=x.tag)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user