Files
StarPilot/tinygrad_repo/test/null/test_linearizer_rewrite.py
2026-10-20 03:55:45 +00:00

74 lines
3.4 KiB
Python

import unittest
from tinygrad import Tensor, Context, Device, dtypes
from tinygrad.codegen import to_program
from tinygrad.codegen.opt import Opt, OptOps
from tinygrad.codegen.late.linearizer import do_split_ends
from tinygrad.uop.ops import KernelInfo, AxisType, UOp, Ops
from test.helpers import to_uops_list
class TestLinearizerRewrite(unittest.TestCase):
def test_range_order(self):
types = [AxisType.DEVICE, AxisType.GLOBAL, AxisType.LOCAL, AxisType.WARP, AxisType.WEAK, AxisType.LOOP,
AxisType.UPCAST, AxisType.PLACEHOLDER]
# Axis type wins over numeric ids, including multi-part ids.
ranges = [UOp.range(4, 10-i, t).replace(arg=(t, 10-i, j)) for i,t in enumerate(types) for j in (0, 1)]
self.assertEqual(sorted(ranges[::-1], key=lambda r: r.arg), ranges)
self.assertEqual(ranges[0].axis_id, (10, 0))
self.assertEqual(ranges[0].axis_type, AxisType.DEVICE)
end = do_split_ends(UOp(Ops.NOOP).end(*ranges[::-1]))
for r in ranges:
self.assertIs(end.src[1], r)
end = end.src[0]
self.assertIs(end.op, Ops.NOOP)
def test_reduction(self):
t = Tensor.ones((64,64), device="NULL").contiguous().realize()
out = (t*2).sum(axis=1)
with Context(SPLIT_REDUCEOP=0):
si = out.schedule_linear().src[-1]
opts_to_apply = []
opts_to_apply.append(Opt(OptOps.SPLIT, 0, (4, AxisType.UPCAST)))
opts_to_apply.append(Opt(OptOps.SPLIT, 2, (4, AxisType.UPCAST)))
ast = si.src[0].replace(arg=KernelInfo(opts_to_apply=tuple(opts_to_apply)))
prg = to_program(ast, Device.default.renderer)
print(prg.src[2].arg)
self.assertNotIn(Ops.REDUCE, [u.op for u in prg.src[1].src])
ranges = [u for u in prg.src[1].src if u.op is Ops.RANGE]
self.assertTrue(ranges)
self.assertTrue(all(r.axis_type is AxisType.WEAK for r in ranges))
def test_arange(self):
out = Tensor.arange(32).clone("NULL")
with Context(SPLIT_REDUCEOP=0):
si = out.schedule_linear().src[-1]
opts_to_apply = []
opts_to_apply.append(Opt(OptOps.SPLIT, 0, (4, AxisType.UPCAST)))
ast = si.src[0].replace(arg=KernelInfo(opts_to_apply=tuple(opts_to_apply)))
prg = to_program(ast, Device.default.renderer)
print(prg.src[2].arg)
def test_kernel_info(self):
out = Tensor.arange(4).clone("NULL")
si = out.schedule_linear().src[-1]
ast = si.src[0].replace(arg=KernelInfo(opts_to_apply=()))
prg = to_program(ast, Device.default.renderer)
assert prg.src[0].arg.applied_opts == (), f"expected no opts, got {prg}"
prg = to_program(ast.replace(arg=KernelInfo(name="custom")), Device.default.renderer)
self.assertEqual(prg.src[0].arg.name, "custom")
def test_dependent_loop_bound(self):
buf, out, counts = UOp.param(0, dtypes.int, 16), UOp.param(1, dtypes.int, 4), UOp.param(2, dtypes.int, 4)
outer = UOp.range(4, 0, AxisType.LOOP)
inner = UOp.range(counts.index(outer).load().maximum(0).minimum(4), 1)
store = buf.index(outer * 4 + inner).store(UOp.const(1, dtypes.int)).end(inner)
uops = to_uops_list([out.after(store).index(outer).store(UOp.const(2, dtypes.int))])
self.assertEqual([u.op for u in uops if u.op in (Ops.RANGE, Ops.STORE, Ops.END)],
[Ops.RANGE, Ops.RANGE, Ops.STORE, Ops.END, Ops.STORE, Ops.END])
rngs, ends = [u for u in uops if u.op is Ops.RANGE], [u for u in uops if u.op is Ops.END]
self.assertEqual([e.src[1] for e in ends], rngs[::-1])
if __name__ == '__main__':
unittest.main()