MCPcopy Index your code
hub / github.com/tinygrad/tinygrad / linearize

Function linearize

tinygrad/codegen/late/linearizer.py:7–52  ·  view source on GitHub ↗
(sink:UOp)

Source from the content-addressed store, hash-verified

5from tinygrad.helpers import prod, getenv, TUPLE_ORDER
6
7def linearize(sink:UOp) -> list[UOp]:
8 # this is a toposort with priority
9 lst = list(sink.toposort())
10 out_degree:defaultdict[UOp, int] = defaultdict(int)
11 priorities:dict[UOp, tuple[int, int, Any]] = {}
12
13 # get consumers and assign priorities
14 # NOTE: this requires the lst be locally toposorted
15 for u in reversed(lst):
16 for s in u.src: out_degree[s] += 1
17
18 # we place UOps with higher run_counts later
19 run_count = prod([int(r.vmax)+1 for r in u.ranges])
20
21 # simple priority override. this is all bottom up now, smaller numbers will be closer to the top
22 extra = None
23 match u.op:
24 # the order and placement of these defines is important
25 case Ops.PARAM: priority, extra = -20, u.arg
26 case Ops.DEFINE_VAR: priority, extra = -19, u.arg
27 case Ops.DEFINE_REG: priority = -18
28 case Ops.DEFINE_LOCAL: priority = -17
29 case Ops.LOAD: priority = -1 # place loads early
30 case Ops.STORE: priority = 1 # place stores late
31 case Ops.RANGE: priority = 5 # placing RANGE is good
32 case Ops.END: priority = -5 # placing END is bad
33 case _: priority = 0 # everything else has priority 0
34 priorities[u] = (run_count, priority, extra)
35
36 # number the uops in "ideal" order
37 nkey = {u:i for i,u in enumerate(sorted(lst, key=lambda x: priorities[x]+(x.tuplize if TUPLE_ORDER else ())))}
38
39 # then force them to be toposorted in as close to the ideal order as possible
40 heap = [(-nkey[sink], sink)]
41 newlst = []
42 while heap:
43 newlst.append(u:=heapq.heappop(heap)[1])
44 for v in u.src:
45 out_degree[v] -= 1
46 if out_degree[v] == 0: heapq.heappush(heap, (-nkey[v],v))
47 newlst = newlst[::-1]
48
49 if getenv("DEBUG_LINEARIZE"):
50 for i,u in enumerate(newlst):
51 print(f"{i:4d} {str(u.op):20s} {multirange_str(u.ranges, color=True, pad=10)} {priorities[u]}")
52 return newlst
53
54class CFGContext:
55 def __init__(self, sink:UOp):

Callers 3

do_linearizeFunction · 0.90
get_uopsFunction · 0.90

Calls 5

prodFunction · 0.90
getenvFunction · 0.90
multirange_strFunction · 0.90
toposortMethod · 0.80
appendMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…