Compare commits

...
Author SHA1 Message Date
George HotzandGitHub 310ef10542 Merge branch 'master' into no_one_ranges 2025-10-01 14:31:04 +08:00
geohot 36d679196c fix realize 2025-10-01 14:29:00 +08:00
geohot a0fe1f68ec fix CL image thing 2025-10-01 12:57:43 +08:00
George HotzandGitHub 6e8ab4c742 Merge branch 'master' into no_one_ranges 2025-10-01 12:37:40 +08:00
geohot 7d0c5a74e4 remove the ranges of 1 2025-10-01 12:36:02 +08:00
geohot bda35265b8 use op_in_parents 2025-10-01 11:23:07 +08:00
+13 -8
View File
@@ -68,12 +68,14 @@ def realize_parents(ctx:dict[UOp, None], rb: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 it's a kernel, we don't realize it
if a.src[1].op is not Ops.KERNEL: ctx[a] = None
do_realize = PatternMatcher([
# 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)),
# 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
(UPat((Ops.COPY, Ops.MSELECT, Ops.MSTACK), name="rb"), realize_parents),
# realize input to assign (might be optimized out)
@@ -125,7 +127,8 @@ class RangeifyContext:
# create ranges
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):
acc = 1
@@ -360,14 +363,15 @@ def cleanup_dead_axes(b:UOp):
for s,rng in zip(b.shape, b.src[1:]):
# 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 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)
hit = True
else:
reshape.append(s)
new_rng.append(rng)
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)
# 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):
# see if we can't do it, should this ever hit?
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 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
# 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):
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 = ret.forced_reshape(shape)
# TODO: is this right? what if it's offset
if any(r.src[0].op is not Ops.RANGE for r in rngs):
sym_shape = tuple([ssimplify(r.src[0]) 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]) if r.op is not Ops.CONST else 1 for r in rngs])
ret = ret.shrink(tuple([(0,x) for x in sym_shape]))
return ret.replace(tag=x.tag)